@rancher/shell 3.0.1 → 3.0.2-rc.1

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 (96) hide show
  1. package/assets/styles/base/_basic.scss +17 -5
  2. package/assets/styles/base/_mixins.scss +2 -1
  3. package/assets/styles/global/_button.scss +10 -0
  4. package/assets/styles/global/_form.scss +2 -2
  5. package/assets/translations/en-us.yaml +33 -5
  6. package/assets/translations/zh-hans.yaml +1 -1
  7. package/components/ActionMenu.vue +8 -0
  8. package/components/AsyncButton.vue +9 -3
  9. package/components/BannerGraphic.vue +10 -0
  10. package/components/ButtonGroup.vue +2 -0
  11. package/components/ButtonMultiAction.vue +6 -0
  12. package/components/ClusterIconMenu.vue +1 -1
  13. package/components/CodeMirror.vue +28 -1
  14. package/components/CommunityLinks.vue +13 -0
  15. package/components/CruResource.vue +6 -0
  16. package/components/GrowlManager.vue +14 -4
  17. package/components/LocaleSelector.vue +49 -5
  18. package/components/PaginatedResourceTable.vue +4 -3
  19. package/components/ResourceDetail/Masthead.vue +11 -4
  20. package/components/ResourceList/index.vue +5 -3
  21. package/components/ResourceTable.vue +1 -1
  22. package/components/SortableTable/THead.vue +19 -4
  23. package/components/SortableTable/index.vue +13 -9
  24. package/components/SortableTable/selection.js +19 -5
  25. package/components/YamlEditor.vue +2 -1
  26. package/components/auth/SelectPrincipal.vue +1 -1
  27. package/components/fleet/FleetBundles.vue +2 -1
  28. package/components/form/LabeledSelect.vue +20 -7
  29. package/components/form/NodeScheduling.vue +5 -1
  30. package/components/form/Password.vue +23 -13
  31. package/components/form/ResourceLabeledSelect.vue +1 -1
  32. package/components/form/Select.vue +28 -6
  33. package/components/form/SelectOrCreateAuthSecret.vue +39 -11
  34. package/components/form/__tests__/NodeScheduling.test.ts +44 -0
  35. package/components/formatter/Endpoints.vue +1 -1
  36. package/components/formatter/LiveExpiryDate.vue +5 -1
  37. package/components/formatter/ServiceTargets.vue +1 -1
  38. package/components/formatter/ServiceType.vue +19 -17
  39. package/components/nav/Pinned.vue +6 -1
  40. package/components/nav/TopLevelMenu.helper.ts +17 -1
  41. package/components/nav/TopLevelMenu.vue +154 -19
  42. package/config/pagination-table-headers.js +9 -1
  43. package/config/product/apps.js +63 -30
  44. package/config/product/explorer.js +182 -17
  45. package/config/product/settings.js +9 -1
  46. package/config/router/routes.js +0 -1
  47. package/config/settings.ts +20 -2
  48. package/config/table-headers.js +23 -15
  49. package/config/types.js +2 -1
  50. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +12 -3
  51. package/edit/fleet.cattle.io.gitrepo.vue +40 -33
  52. package/edit/provisioning.cattle.io.cluster/rke2.vue +13 -2
  53. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +10 -2
  54. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
  55. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +6 -3
  56. package/edit/workload/mixins/workload.js +15 -7
  57. package/list/catalog.cattle.io.app.vue +4 -11
  58. package/list/catalog.cattle.io.clusterrepo.vue +59 -25
  59. package/list/fleet.cattle.io.bundle.vue +2 -2
  60. package/list/management.cattle.io.feature.vue +12 -5
  61. package/list/management.cattle.io.setting.vue +30 -19
  62. package/list/namespace.vue +4 -1
  63. package/list/networking.k8s.io.ingress.vue +14 -11
  64. package/list/node.vue +65 -63
  65. package/list/persistentvolume.vue +55 -20
  66. package/list/persistentvolumeclaim.vue +3 -15
  67. package/list/service.vue +16 -21
  68. package/list/workload.vue +35 -49
  69. package/mixins/resource-fetch.js +8 -1
  70. package/mixins/vue-select-overrides.js +10 -16
  71. package/models/management.cattle.io.cluster.js +6 -1
  72. package/models/persistentvolume.js +1 -3
  73. package/models/storage.k8s.io.storageclass.js +4 -0
  74. package/package.json +28 -29
  75. package/pages/c/_cluster/explorer/EventsTable.vue +58 -16
  76. package/pages/c/_cluster/explorer/index.vue +3 -16
  77. package/pages/c/_cluster/settings/performance.vue +49 -23
  78. package/pages/home.vue +24 -3
  79. package/pages/support/index.vue +1 -1
  80. package/plugins/floating-vue.js +1 -1
  81. package/plugins/steve/steve-pagination-utils.ts +85 -15
  82. package/rancher-components/Banner/Banner.vue +12 -0
  83. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -5
  84. package/rancher-components/Form/Radio/RadioButton.vue +0 -6
  85. package/rancher-components/Form/Radio/RadioGroup.vue +5 -1
  86. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +2 -2
  87. package/scripts/test-plugins-build.sh +21 -6
  88. package/scripts/typegen.sh +1 -0
  89. package/store/index.js +16 -0
  90. package/store/type-map.utils.ts +14 -1
  91. package/types/shell/index.d.ts +467 -418
  92. package/types/store/vuex.d.ts +1 -1
  93. package/types/vue-shim.d.ts +2 -8
  94. package/utils/cluster.js +2 -2
  95. package/utils/string.js +6 -0
  96. package/vue.config.js +3 -4
@@ -103,17 +103,17 @@ export default {
103
103
  resources.push(this.t('performance.serverPagination.resources.all'));
104
104
  } else {
105
105
  settings.resources.enableSome.enabled.forEach((resource) => {
106
- resources.push(resource);
106
+ resources.push(!!resource.length ? resource : `${ resource.resource } (${ resource.context })`);
107
107
  });
108
108
  if (settings.resources.enableSome.generic) {
109
109
  resources.push(this.t('performance.serverPagination.resources.generic', {}, true));
110
110
  }
111
111
  }
112
112
 
113
- storeResources.push(`${ store }: ${ resources.join(', ') }`);
113
+ storeResources.push(`Resources in store '${ store }': ${ resources.join(', ') }`);
114
114
  });
115
115
 
116
- return storeResources.join('. ');
116
+ return storeResources.join('<br><br>');
117
117
  }
118
118
  },
119
119
 
@@ -187,6 +187,13 @@ export default {
187
187
  body: this.t(`performance.${ l10n[property] }.incompatibleDescription`, {}, true),
188
188
  },
189
189
  });
190
+ },
191
+
192
+ setPaginationDefaults() {
193
+ this.value = {
194
+ ...this.value,
195
+ serverPagination: { ...DEFAULT_PERF_SETTING.serverPagination }
196
+ };
190
197
  }
191
198
  },
192
199
  };
@@ -202,7 +209,9 @@ export default {
202
209
  <div class="ui-perf-setting">
203
210
  <!-- Server Side Pagination -->
204
211
  <div class="mt-40">
205
- <h2>{{ t('performance.serverPagination.label') }}</h2>
212
+ <h2 id="ssp-setting">
213
+ {{ t('performance.serverPagination.label') }}
214
+ </h2>
206
215
  <p>{{ t('performance.serverPagination.description') }}</p>
207
216
  <Banner
208
217
  color="error"
@@ -225,9 +234,17 @@ export default {
225
234
  <p :class="{ 'text-muted': !value.serverPagination.enabled }">
226
235
  {{ t('performance.serverPagination.applicable') }}
227
236
  </p>
228
- <p :class="{ 'text-muted': !value.serverPagination.enabled }">
229
- {{ steveCacheApplicableResources }}
230
- </p>
237
+ <p
238
+ v-clean-html="steveCacheApplicableResources"
239
+ :class="{ 'text-muted': !value.serverPagination.enabled }"
240
+ />
241
+ <button
242
+ class="btn btn-sm role-primary"
243
+ style="width: fit-content;"
244
+ @click.prevent="setPaginationDefaults()"
245
+ >
246
+ {{ t('performance.serverPagination.populateDefaults') }}
247
+ </button>
231
248
  </div>
232
249
  <!-- Inactivity -->
233
250
  <div class="mt-20">
@@ -273,6 +290,11 @@ export default {
273
290
  <!-- Incremental Loading -->
274
291
  <div class="mt-40">
275
292
  <h2>{{ t('performance.incrementalLoad.label') }}</h2>
293
+ <Banner
294
+ color="warning"
295
+ >
296
+ <span v-clean-html="t(`performance.deprecatedForSSP`, { setting: t('performance.incrementalLoad.label') }, true)" />
297
+ </Banner>
276
298
  <p>{{ t('performance.incrementalLoad.description') }}</p>
277
299
  <Checkbox
278
300
  :value="value.incrementalLoading.enabled"
@@ -300,11 +322,12 @@ export default {
300
322
  <!-- Enable manual refresh list views -->
301
323
  <div class="mt-40">
302
324
  <h2 v-t="'performance.manualRefresh.label'" />
303
- <p>{{ t('performance.manualRefresh.description') }}</p>
304
325
  <Banner
305
- color="error"
306
- label-key="performance.experimental"
307
- />
326
+ color="warning"
327
+ >
328
+ <span v-clean-html="t(`performance.deprecatedForSSP`, { setting: t('performance.manualRefresh.label') }, true)" />
329
+ </Banner>
330
+ <p>{{ t('performance.manualRefresh.description') }}</p>
308
331
  <Checkbox
309
332
  :value="value.manualRefresh.enabled"
310
333
  :mode="mode"
@@ -331,11 +354,12 @@ export default {
331
354
  <!-- Enable GC of resources from store -->
332
355
  <div class="mt-40">
333
356
  <h2 v-t="'performance.gc.label'" />
334
- <p>{{ t('performance.gc.description') }}</p>
335
357
  <Banner
336
- color="error"
337
- label-key="performance.experimental"
338
- />
358
+ color="warning"
359
+ >
360
+ <span v-clean-html="t(`performance.deprecatedForSSP`, { setting: t('performance.gc.label') }, true)" />
361
+ </Banner>
362
+ <p>{{ t('performance.gc.description') }}</p>
339
363
  <Checkbox
340
364
  v-model:value="value.garbageCollection.enabled"
341
365
  :mode="mode"
@@ -411,11 +435,12 @@ export default {
411
435
  <!-- Force NS filter -->
412
436
  <div class="mt-40">
413
437
  <h2>{{ t('performance.nsFiltering.label') }}</h2>
414
- <p>{{ t('performance.nsFiltering.description') }}</p>
415
438
  <Banner
416
- color="error"
417
- label-key="performance.experimental"
418
- />
439
+ color="warning"
440
+ >
441
+ <span v-clean-html="t(`performance.deprecatedForSSP`, { setting: t('performance.nsFiltering.label') }, true)" />
442
+ </Banner>
443
+ <p>{{ t('performance.nsFiltering.description') }}</p>
419
444
  <Checkbox
420
445
  :value="value.forceNsFilterV2.enabled"
421
446
  :mode="mode"
@@ -428,11 +453,12 @@ export default {
428
453
  <!-- Advanced Websocket Worker -->
429
454
  <div class="mt-40">
430
455
  <h2>{{ t('performance.advancedWorker.label') }}</h2>
431
- <p>{{ t('performance.advancedWorker.description') }}</p>
432
456
  <Banner
433
- color="error"
434
- label-key="performance.experimental"
435
- />
457
+ color="warning"
458
+ >
459
+ <span v-clean-html="t(`performance.deprecatedForSSP`, { setting: t('performance.advancedWorker.label') }, true)" />
460
+ </Banner>
461
+ <p>{{ t('performance.advancedWorker.description') }}</p>
436
462
  <Checkbox
437
463
  v-model:value="value.advancedWorker.enabled"
438
464
  :mode="mode"
package/pages/home.vue CHANGED
@@ -27,7 +27,7 @@ import { RESET_CARDS_ACTION, SET_LOGIN_ACTION } from '@shell/config/page-actions
27
27
  import { STEVE_NAME_COL, STEVE_STATE_COL } from '@shell/config/pagination-table-headers';
28
28
  import { PaginationParamFilter, FilterArgs, PaginationFilterField, PaginationArgs } from '@shell/types/store/pagination.types';
29
29
  import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
30
- import { sameContents } from 'utils/array';
30
+ import { sameContents } from '@shell/utils/array';
31
31
 
32
32
  export default defineComponent({
33
33
  name: 'Home',
@@ -504,16 +504,18 @@ export default defineComponent({
504
504
  {{ t('landing.seeWhatsNew') }}
505
505
  </div>
506
506
  <a
507
- class="hand"
507
+ class="hand banner-link"
508
508
  :href="releaseNotesUrl"
509
+ role="link"
509
510
  target="_blank"
510
511
  rel="noopener noreferrer nofollow"
512
+ :aria-label="t('landing.whatsNewLink')"
511
513
  @click.stop="showWhatsNew"
514
+ @keyup.stop.enter="showWhatsNew"
512
515
  ><span v-clean-html="t('landing.whatsNewLink')" /></a>
513
516
  </Banner>
514
517
  </div>
515
518
  </div>
516
-
517
519
  <div class="row home-panels">
518
520
  <div class="col main-panel">
519
521
  <div
@@ -532,7 +534,11 @@ export default defineComponent({
532
534
  </div>
533
535
  <a
534
536
  class="hand mr-20"
537
+ tabindex="0"
538
+ :aria-label="t('landing.landingPrefs.userPrefs')"
535
539
  @click.prevent.stop="showUserPrefs"
540
+ @keyup.prevent.stop.enter="showUserPrefs"
541
+ @keyup.prevent.stop.space="showUserPrefs"
536
542
  ><span v-clean-html="t('landing.landingPrefs.userPrefs')" /></a>
537
543
  </Banner>
538
544
  </div>
@@ -583,6 +589,9 @@ export default defineComponent({
583
589
  :to="manageLocation"
584
590
  class="btn btn-sm role-secondary"
585
591
  data-testid="cluster-management-manage-button"
592
+ role="button"
593
+ :aria-label="t('cluster.manageAction')"
594
+ @keyup.space="$router.push(manageLocation)"
586
595
  >
587
596
  {{ t('cluster.manageAction') }}
588
597
  </router-link>
@@ -591,6 +600,9 @@ export default defineComponent({
591
600
  :to="importLocation"
592
601
  class="btn btn-sm role-primary"
593
602
  data-testid="cluster-create-import-button"
603
+ role="button"
604
+ :aria-label="t('cluster.importAction')"
605
+ @keyup.space="$router.push(importLocation)"
594
606
  >
595
607
  {{ t('cluster.importAction') }}
596
608
  </router-link>
@@ -599,6 +611,9 @@ export default defineComponent({
599
611
  :to="createLocation"
600
612
  class="btn btn-sm role-primary"
601
613
  data-testid="cluster-create-button"
614
+ role="button"
615
+ :aria-label="t('generic.create')"
616
+ @keyup.space="$router.push(createLocation)"
602
617
  >
603
618
  {{ t('generic.create') }}
604
619
  </router-link>
@@ -614,6 +629,8 @@ export default defineComponent({
614
629
  <router-link
615
630
  v-if="row.mgmt.isReady && !row.hasError"
616
631
  :to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}"
632
+ role="link"
633
+ :aria-label="row.nameDisplay"
617
634
  >
618
635
  {{ row.nameDisplay }}
619
636
  </router-link>
@@ -687,6 +704,10 @@ export default defineComponent({
687
704
  </template>
688
705
 
689
706
  <style lang='scss' scoped>
707
+ .banner-link:focus-visible {
708
+ @include focus-outline;
709
+ }
710
+
690
711
  .home-panels {
691
712
  display: flex;
692
713
  align-items: stretch;
@@ -7,7 +7,7 @@ import { getVendor } from '@shell/config/private-label';
7
7
  import { SETTING } from '@shell/config/settings';
8
8
  import { addParam } from '@shell/utils/url';
9
9
  import { isRancherPrime } from '@shell/config/version';
10
- import { hasCspAdapter } from 'mixins/brand';
10
+ import { hasCspAdapter } from '@shell/mixins/brand';
11
11
  import TabTitle from '@shell/components/TabTitle';
12
12
 
13
13
  export default {
@@ -1 +1 @@
1
- export const floatingVueOptions = { themes: { tooltip: { html: true } } };
1
+ export const floatingVueOptions = { themes: { tooltip: { html: true, triggers: ['hover', 'touch'] } } };
@@ -5,9 +5,16 @@ import Namespace from '@shell/models/namespace';
5
5
  import { uniq } from '@shell/utils/array';
6
6
  import {
7
7
  CAPI,
8
- CONFIG_MAP, MANAGEMENT, NAMESPACE, NODE, POD
8
+ CATALOG,
9
+ CONFIG_MAP, MANAGEMENT, EVENT, NAMESPACE, NODE, POD, PVC,
10
+ PV,
11
+ STORAGE_CLASS,
12
+ SERVICE,
13
+ INGRESS,
14
+ WORKLOAD_TYPES,
15
+ HPA
9
16
  } from '@shell/config/types';
10
- import { CAPI as CAPI_LABELS } from '@shell/config/labels-annotations';
17
+ import { CAPI as CAPI_LABELS, CATTLE_PUBLIC_ENDPOINTS } from '@shell/config/labels-annotations';
11
18
  import { Schema } from '@shell/plugins/steve/schema';
12
19
 
13
20
  class NamespaceProjectFilters {
@@ -133,8 +140,8 @@ class StevePaginationUtils extends NamespaceProjectFilters {
133
140
  [MANAGEMENT.CLUSTER]: [
134
141
  { field: 'spec.internal' },
135
142
  { field: 'spec.displayName' },
136
- // { field: `status.provider` }, // Pending API Support - https://github.com/rancher/rancher/issues/48256
137
- // { field: `metadata.labels."${ CAPI_LABELS.PROVIDER }"` }, // Pending API Support - https://github.com/rancher/rancher/issues/48256
143
+ { field: `status.provider` },
144
+ { field: `metadata.labels."${ CAPI_LABELS.PROVIDER }"` },
138
145
 
139
146
  ],
140
147
  [CONFIG_MAP]: [
@@ -146,11 +153,71 @@ class StevePaginationUtils extends NamespaceProjectFilters {
146
153
  [CAPI.MACHINE]: [
147
154
  { field: 'spec.clusterName' }
148
155
  ],
156
+ [EVENT]: [
157
+ { field: '_type' },
158
+ { field: 'reason' },
159
+ { field: 'involvedObject.kind' },
160
+ { field: 'message' },
161
+ ],
162
+ [CATALOG.CLUSTER_REPO]: [
163
+ { field: 'spec.gitRepo' },
164
+ { field: 'spec.gitBranch' },
165
+ { field: `metadata.annotations[clusterrepo.cattle.io/hidden]` }
166
+ ],
167
+ [CATALOG.OPERATION]: [
168
+ { field: 'status.action' },
169
+ { field: 'status.namespace' },
170
+ { field: 'status.releaseName' },
171
+ ],
149
172
  [CAPI.RANCHER_CLUSTER]: [
150
173
  { field: `metadata.labels."${ CAPI_LABELS.PROVIDER }"` },
151
174
  { field: `status.provider` },
152
175
  { field: 'status.clusterName' },
176
+ ],
177
+ [SERVICE]: [
178
+ { field: 'spec.type' },
179
+ // { field: 'spec.clusterIP' }, // Pending API support (blocked https://github.com/rancher/rancher/issues/48473 (index fields)
180
+ ],
181
+ [INGRESS]: [
182
+ // { field: 'spec.rules.host' }, // Pending API support (blocked https://github.com/rancher/rancher/issues/48473 (index fields)
183
+ // { field: 'spec.ingressClassName' }, // Pending API support (blocked https://github.com/rancher/rancher/issues/48473 (index fields)
184
+ ],
185
+ [HPA]: [
186
+ // { field: 'spec.scaleTargetRef.name' }, // Pending API support https://github.com/rancher/rancher/issues/48473 (hpa filtering fix)
187
+ // { field: 'spec.minReplicas' }, // Pending API support https://github.com/rancher/rancher/issues/48473 (hpa filtering fix)
188
+ // { field: 'spec.maxReplicas' }, // Pending API support https://github.com/rancher/rancher/issues/48473 (hpa filtering fix)
189
+ // { field: 'spec.currentReplicas' }, // Pending API support https://github.com/rancher/rancher/issues/48473 (hpa filtering fix)
190
+ ],
191
+ [PVC]: [
192
+ { field: 'spec.volumeName' },
193
+ ],
194
+ [PV]: [
195
+ { field: 'status.reason' },
196
+ { field: 'spec.persistentVolumeReclaimPolicy' },
197
+ ],
198
+ [STORAGE_CLASS]: [
199
+ { field: 'provisioner' },
200
+ // { field: `metadata.annotations[STORAGE.DEFAULT_STORAGE_CLASS]` }, // Pending API Support - https://github.com/rancher/rancher/issues/48453
201
+ ],
202
+ [CATALOG.APP]: [
203
+ { field: 'spec.chart.metadata.name' }
204
+ ],
205
+ [WORKLOAD_TYPES.CRON_JOB]: [
206
+ { field: `metadata.annotations[${ CATTLE_PUBLIC_ENDPOINTS }]` }
207
+ ],
208
+ [WORKLOAD_TYPES.DAEMON_SET]: [
209
+ { field: `metadata.annotations[${ CATTLE_PUBLIC_ENDPOINTS }]` }
210
+ ],
211
+ [WORKLOAD_TYPES.DEPLOYMENT]: [
212
+ { field: `metadata.annotations[${ CATTLE_PUBLIC_ENDPOINTS }]` }
213
+ ],
214
+ [WORKLOAD_TYPES.JOB]: [
215
+ { field: `metadata.annotations[${ CATTLE_PUBLIC_ENDPOINTS }]` }
216
+ ],
217
+ [WORKLOAD_TYPES.STATEFUL_SET]: [
218
+ { field: `metadata.annotations[${ CATTLE_PUBLIC_ENDPOINTS }]` }
153
219
  ]
220
+
154
221
  }
155
222
 
156
223
  private convertArrayPath(path: string): string {
@@ -318,18 +385,21 @@ class StevePaginationUtils extends NamespaceProjectFilters {
318
385
  state.checked.push(field);
319
386
 
320
387
  // First check in our hardcoded list of supported filters
321
- if ([
322
- StevePaginationUtils.VALID_FIELDS[''], // Global
323
- StevePaginationUtils.VALID_FIELDS[schema.id], // Type specific
324
- ].find((fields) => fields?.find((f) => {
325
- if (f.startsWith) {
326
- if (field.startsWith(f.field)) {
327
- return true;
388
+ if (
389
+ process.env.NODE_ENV === 'dev' &&
390
+ [
391
+ StevePaginationUtils.VALID_FIELDS[''], // Global
392
+ StevePaginationUtils.VALID_FIELDS[schema.id], // Type specific
393
+ ].find((fields) => fields?.find((f) => {
394
+ if (f.startsWith) {
395
+ if (field.startsWith(f.field)) {
396
+ return true;
397
+ }
398
+ } else {
399
+ return field === f.field;
328
400
  }
329
- } else {
330
- return field === f.field;
331
- }
332
- }))) {
401
+ }))
402
+ ) {
333
403
  return;
334
404
  }
335
405
 
@@ -67,6 +67,7 @@ export default defineComponent({
67
67
  :class="{
68
68
  [color]: true,
69
69
  }"
70
+ role="banner"
70
71
  >
71
72
  <div
72
73
  v-if="icon"
@@ -102,7 +103,12 @@ export default defineComponent({
102
103
  <div
103
104
  v-if="closable"
104
105
  class="banner__content__closer"
106
+ tabindex="0"
107
+ role="button"
108
+ :aria-label="t('generic.close')"
105
109
  @click="$emit('close')"
110
+ @keyup.enter="$emit('close')"
111
+ @keyup.space="$emit('close')"
106
112
  >
107
113
  <i
108
114
  data-testid="banner-close"
@@ -226,6 +232,7 @@ $icon-size: 24px;
226
232
  width: $icon-size;
227
233
  line-height: $icon-size;
228
234
  text-align: center;
235
+ outline: none;
229
236
 
230
237
  .closer-icon {
231
238
  opacity: 0.7;
@@ -235,6 +242,11 @@ $icon-size: 24px;
235
242
  color: var(--link);
236
243
  }
237
244
  }
245
+
246
+ &:focus-visible i {
247
+ @include focus-outline;
248
+ outline-offset: 2px;
249
+ }
238
250
  }
239
251
 
240
252
  &.icon {
@@ -113,7 +113,7 @@ export default defineComponent({
113
113
  primary: {
114
114
  type: Boolean,
115
115
  default: false
116
- },
116
+ }
117
117
  },
118
118
 
119
119
  emits: ['update:value'],
@@ -135,7 +135,14 @@ export default defineComponent({
135
135
  */
136
136
  isChecked(): boolean {
137
137
  return this.isMulti(this.value) ? this.findTrueValues(this.value) : this.value === this.valueWhenTrue;
138
- }
138
+ },
139
+
140
+ /**
141
+ * Determines if the Labeled Input should display a tooltip.
142
+ */
143
+ hasTooltip(): boolean {
144
+ return !!this.tooltip || !!this.tooltipKey;
145
+ },
139
146
  },
140
147
 
141
148
  methods: {
@@ -214,6 +221,9 @@ export default defineComponent({
214
221
  <div
215
222
  class="checkbox-outer-container"
216
223
  data-checkbox-ctrl
224
+ :class="{
225
+ 'v-popper--has-tooltip': hasTooltip,
226
+ }"
217
227
  >
218
228
  <label
219
229
  class="checkbox-container"
@@ -227,9 +237,10 @@ export default defineComponent({
227
237
  :checked="isChecked"
228
238
  :value="valueWhenTrue"
229
239
  type="checkbox"
230
- :tabindex="-1"
240
+ tabindex="-1"
231
241
  :name="id"
232
242
  @click.stop.prevent
243
+ @keyup.enter.stop.prevent
233
244
  >
234
245
  <span
235
246
  class="checkbox-custom"
@@ -240,7 +251,7 @@ export default defineComponent({
240
251
  role="checkbox"
241
252
  />
242
253
  <span
243
- v-if="$slots.label || label || labelKey || tooltipKey || tooltip"
254
+ v-if="$slots.label || label || labelKey || hasTooltip"
244
255
  class="checkbox-label"
245
256
  :class="{ 'checkbox-primary': primary }"
246
257
  >
@@ -325,9 +336,14 @@ $fontColor: var(--input-label);
325
336
  width: 14px;
326
337
  background-color: var(--body-bg);
327
338
  border-radius: var(--border-radius);
328
- transition: all 0.3s ease-out;
329
339
  border: 1px solid var(--border);
330
340
  flex-shrink: 0;
341
+
342
+ &:focus-visible {
343
+ @include focus-outline;
344
+ outline-offset: 2px;
345
+ border-radius: 0;
346
+ }
331
347
  }
332
348
 
333
349
  input {
@@ -337,6 +353,12 @@ $fontColor: var(--input-label);
337
353
  z-index: -1;
338
354
  }
339
355
 
356
+ input:focus-visible ~ .checkbox-custom {
357
+ @include focus-outline;
358
+ outline-offset: 2px;
359
+ border-radius: 0;
360
+ }
361
+
340
362
  input:checked ~ .checkbox-custom {
341
363
  background-color:var(--primary);
342
364
  -webkit-transform: rotate(0deg) scale(1);
@@ -243,14 +243,8 @@ $fontColor: var(--input-label);
243
243
  min-width: 14px;
244
244
  background-color: var(--input-bg);
245
245
  border-radius: 50%;
246
- transition: all 0.3s ease-out;
247
246
  border: 1.5px solid var(--border);
248
247
  margin-top: 5px;
249
-
250
- &:focus {
251
- outline: none;
252
- border-radius: 50%;
253
- }
254
248
  }
255
249
 
256
250
  input {
@@ -145,6 +145,9 @@ export default defineComponent({
145
145
  */
146
146
  isDisabled(): boolean {
147
147
  return (this.disabled || this.isView);
148
+ },
149
+ radioGroupLabel(): string {
150
+ return this.labelKey ? this.t(this.labelKey) : this.label ? this.label : '';
148
151
  }
149
152
  },
150
153
 
@@ -202,9 +205,10 @@ export default defineComponent({
202
205
 
203
206
  <!-- Group -->
204
207
  <div
208
+ role="radiogroup"
209
+ :aria-label="radioGroupLabel"
205
210
  class="radio-group"
206
211
  :class="{'row':row}"
207
- tabindex="0"
208
212
  @keyup.down.stop="clickNext(1)"
209
213
  @keyup.up.stop="clickNext(-1)"
210
214
  >
@@ -1,7 +1,7 @@
1
1
  variables:
2
- NODE_VERSION: "v16.20.2"
2
+ NODE_VERSION: "v20.17.0"
3
3
  NODE_DISTRO: "node-${NODE_VERSION}-linux-x64"
4
- YQ_VERSION: "v4.44.1"
4
+ YQ_VERSION: "v4.44.6"
5
5
  YQ_URL: "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"
6
6
 
7
7
  .podman-setup: &podman-setup
@@ -93,6 +93,19 @@ update_version_in_package_json "${SHELL_DIR}/package.json" "${SHELL_VERSION}"
93
93
  update_version_in_package_json "${BASE_DIR}/pkg/rancher-components/package.json" "${SHELL_VERSION}"
94
94
  update_version_in_package_json "${BASE_DIR}/creators/extension/package.json" "${SHELL_VERSION}"
95
95
 
96
+
97
+ createTestComponent() {
98
+ # Add test list component to the test package
99
+ # Validates rancher-components imports
100
+
101
+ # NOTE - This fails if importing some components with TS imports...
102
+ # cp ${SHELL_DIR}/list/catalog.cattle.io.clusterrepo.vue pkg/test-pkg/list
103
+ # See https://github.com/rancher/dashboard/issues/12918
104
+
105
+ # Use a basic list instead
106
+ cp ${SHELL_DIR}/list/namespace.vue pkg/test-pkg/list
107
+ }
108
+
96
109
  # Publish shell pkg (tag is needed as publish-shell is optimized to work with release-shell-pkg workflow)
97
110
  echo "Publishing Shell package to local registry"
98
111
  yarn install
@@ -133,7 +146,7 @@ if [ "${SKIP_STANDALONE}" == "false" ]; then
133
146
  # Add test list component to the test package
134
147
  # Validates rancher-components imports
135
148
  mkdir -p pkg/test-pkg/list
136
- cp ${SHELL_DIR}/list/catalog.cattle.io.clusterrepo.vue pkg/test-pkg/list
149
+ createTestComponent
137
150
 
138
151
  FORCE_COLOR=true yarn build-pkg test-pkg | cat
139
152
 
@@ -159,7 +172,7 @@ if [ "${TEST_PERSIST_BUILD}" != "true" ]; then
159
172
  fi
160
173
 
161
174
  yarn create @rancher/extension test-pkg -i
162
- cp ${SHELL_DIR}/list/catalog.cattle.io.clusterrepo.vue ./pkg/test-pkg/list
175
+ createTestComponent
163
176
  FORCE_COLOR=true yarn build-pkg test-pkg | cat
164
177
 
165
178
  if [ "${TEST_PERSIST_BUILD}" != "true" ]; then
@@ -223,9 +236,11 @@ function clone_repo_test_extension_build() {
223
236
  # Don't forget to add the unit tests exception to clone_repo_test_extension_build function if a new extension has those
224
237
  clone_repo_test_extension_build "rancher" "kubewarden-ui" "kubewarden"
225
238
  clone_repo_test_extension_build "rancher" "elemental-ui" "elemental"
226
- clone_repo_test_extension_build "neuvector" "manager-ext" "neuvector-ui-ext"
227
- clone_repo_test_extension_build "rancher" "capi-ui-extension" "capi"
228
- clone_repo_test_extension_build "StackVista" "rancher-extension-stackstate" "observability"
229
- clone_repo_test_extension_build "harvester" "harvester-ui-extension" "harvester"
239
+ # TODO #13141: Enable neuvector tests after issues have been resolved
240
+ # clone_repo_test_extension_build "neuvector" "manager-ext" "neuvector-ui-ext"
241
+ # TODO: #13173: Enable capi, stackstate, and harvester after `entities` resolution has been set
242
+ # clone_repo_test_extension_build "rancher" "capi-ui-extension" "capi"
243
+ # clone_repo_test_extension_build "StackVista" "rancher-extension-stackstate" "observability"
244
+ # clone_repo_test_extension_build "harvester" "harvester-ui-extension" "harvester"
230
245
 
231
246
  echo "All done"
@@ -40,6 +40,7 @@ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/resource-fetch.js --declar
40
40
  # # models
41
41
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/models/namespace.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/models/ > /dev/null
42
42
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/models/networking.k8s.io.ingress.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/models/ > /dev/null
43
+ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/models/catalog.cattle.io.clusterrepo.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/models/ > /dev/null
43
44
 
44
45
  #./node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/*.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store
45
46
 
package/store/index.js CHANGED
@@ -259,6 +259,10 @@ export const state = () => {
259
259
  $router: markRaw({}),
260
260
  $route: markRaw({}),
261
261
  $plugin: markRaw({}),
262
+ /**
263
+ * Cache state of side nav clusters. This avoids flickering when the user changes pages and the side nav component re-renders
264
+ */
265
+ sideNavCache: undefined,
262
266
  };
263
267
  };
264
268
 
@@ -613,6 +617,10 @@ export const getters = {
613
617
  return `${ base }/latest`;
614
618
  },
615
619
 
620
+ sideNavCache(state) {
621
+ return state.sideNavCache;
622
+ },
623
+
616
624
  ...gcGetters
617
625
  };
618
626
 
@@ -751,6 +759,10 @@ export const mutations = {
751
759
 
752
760
  setPlugin(state, pluginDefinition) {
753
761
  state.$plugin = markRaw(pluginDefinition || {});
762
+ },
763
+
764
+ setSideNavCache(state, sideNavCache) {
765
+ state.sideNavCache = sideNavCache;
754
766
  }
755
767
  };
756
768
 
@@ -1270,5 +1282,9 @@ export const actions = {
1270
1282
  });
1271
1283
  },
1272
1284
 
1285
+ setSideNavCache({ commit }, sideNavCache) {
1286
+ commit('setSideNavCache', sideNavCache);
1287
+ },
1288
+
1273
1289
  ...gcActions
1274
1290
  };