@rancher/shell 3.0.3 → 3.0.5-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 (139) hide show
  1. package/assets/styles/base/_basic.scss +6 -0
  2. package/assets/styles/global/_button.scss +1 -0
  3. package/assets/translations/en-us.yaml +38 -3
  4. package/cloud-credential/aws.vue +2 -0
  5. package/components/AssignTo.vue +25 -11
  6. package/components/AsyncButton.vue +24 -7
  7. package/components/BannerGraphic.vue +1 -0
  8. package/components/CommunityLinks.vue +3 -3
  9. package/components/CopyToClipboardText.vue +2 -1
  10. package/components/DetailText.vue +5 -0
  11. package/components/DisableAuthProviderModal.vue +1 -0
  12. package/components/ExplorerMembers.vue +1 -1
  13. package/components/ExplorerProjectsNamespaces.vue +56 -14
  14. package/components/LandingPagePreference.vue +5 -3
  15. package/components/LocaleSelector.vue +38 -94
  16. package/components/ModalWithCard.vue +1 -0
  17. package/components/MoveModal.vue +1 -0
  18. package/components/PromptRemove.vue +2 -1
  19. package/components/PromptRestore.vue +1 -0
  20. package/components/ResourceCancelModal.vue +1 -0
  21. package/components/SortableTable/index.vue +35 -10
  22. package/components/StatusBadge.vue +10 -4
  23. package/components/__tests__/AsyncButton.test.ts +2 -2
  24. package/components/auth/Principal.vue +9 -3
  25. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  26. package/components/form/ArrayList.vue +75 -54
  27. package/components/form/Command.vue +6 -15
  28. package/components/form/EnvVars.vue +15 -8
  29. package/components/form/HealthCheck.vue +3 -3
  30. package/components/form/HookOption.vue +11 -16
  31. package/components/form/KeyValue.vue +1 -1
  32. package/components/form/LabeledSelect.vue +2 -1
  33. package/components/form/LifecycleHooks.vue +3 -3
  34. package/components/form/MatchExpressions.vue +10 -7
  35. package/components/form/NameNsDescription.vue +123 -103
  36. package/components/form/Networking.vue +20 -12
  37. package/components/form/NodeAffinity.vue +31 -23
  38. package/components/form/NodeScheduling.vue +13 -3
  39. package/components/form/PodAffinity.vue +43 -43
  40. package/components/form/Probe.vue +67 -66
  41. package/components/form/ResourceQuota/Project.vue +5 -1
  42. package/components/form/ResourceSelector.vue +7 -9
  43. package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
  44. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
  45. package/components/form/SSHKnownHosts/index.vue +16 -2
  46. package/components/form/Security.vue +54 -56
  47. package/components/form/Select.vue +31 -6
  48. package/components/form/ShellInput.vue +5 -1
  49. package/components/form/Tolerations.vue +5 -1
  50. package/components/form/ValueFromResource.vue +134 -121
  51. package/components/form/WorkloadPorts.vue +18 -18
  52. package/components/form/__tests__/ArrayList.test.ts +3 -0
  53. package/components/form/__tests__/MatchExpressions.test.ts +12 -12
  54. package/components/form/__tests__/NameNsDescription.test.ts +115 -14
  55. package/components/form/__tests__/Probe.test.ts +12 -8
  56. package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
  57. package/components/form/__tests__/Select.test.ts +37 -0
  58. package/components/formatter/InternalExternalIP.vue +2 -0
  59. package/components/formatter/SecretData.vue +20 -7
  60. package/components/nav/Group.vue +15 -1
  61. package/components/nav/Header.vue +1 -0
  62. package/components/nav/Type.vue +12 -1
  63. package/components/templates/blank.vue +4 -1
  64. package/components/templates/default.vue +2 -0
  65. package/components/templates/home.vue +4 -1
  66. package/components/templates/plain.vue +4 -1
  67. package/composables/useRuntimeFlag.ts +29 -0
  68. package/config/router/routes.js +20 -13
  69. package/core/types.ts +5 -0
  70. package/dialog/AddCustomBadgeDialog.vue +1 -0
  71. package/dialog/DeactivateDriverDialog.vue +5 -4
  72. package/dialog/ForceMachineRemoveDialog.vue +4 -1
  73. package/dialog/GitRepoForceUpdateDialog.vue +1 -1
  74. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
  75. package/edit/auth/__tests__/oidc.test.ts +152 -109
  76. package/edit/auth/azuread.vue +1 -0
  77. package/edit/auth/googleoauth.vue +4 -0
  78. package/edit/auth/oidc.vue +37 -4
  79. package/edit/cloudcredential.vue +1 -0
  80. package/edit/fleet.cattle.io.gitrepo.vue +1 -0
  81. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
  82. package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
  83. package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
  84. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
  85. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +1 -0
  86. package/edit/provisioning.cattle.io.cluster/rke2.vue +25 -34
  87. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
  88. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +29 -1
  89. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
  90. package/edit/token.vue +2 -0
  91. package/edit/workload/index.vue +1 -0
  92. package/edit/workload/mixins/workload.js +0 -2
  93. package/list/management.cattle.io.feature.vue +1 -0
  94. package/list/provisioning.cattle.io.cluster.vue +20 -12
  95. package/machine-config/__tests__/vmwarevsphere.test.ts +48 -3
  96. package/machine-config/vmwarevsphere.vue +16 -0
  97. package/models/__tests__/namespace.test.ts +25 -1
  98. package/models/cloudcredential.js +5 -0
  99. package/models/kontainerdriver.js +6 -3
  100. package/models/management.cattle.io.node.js +3 -3
  101. package/models/namespace.js +4 -5
  102. package/models/nodedriver.js +6 -3
  103. package/models/workload.js +4 -1
  104. package/package.json +4 -4
  105. package/pages/about.vue +16 -8
  106. package/pages/account/index.vue +4 -1
  107. package/pages/auth/login.vue +11 -3
  108. package/pages/auth/logout.vue +4 -1
  109. package/pages/auth/setup.vue +1 -0
  110. package/pages/auth/verify.vue +4 -1
  111. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  112. package/pages/diagnostic.vue +47 -2
  113. package/pages/fail-whale.vue +6 -3
  114. package/pages/home.vue +24 -18
  115. package/pages/support/index.vue +4 -1
  116. package/promptRemove/management.cattle.io.fleetworkspace.vue +1 -1
  117. package/promptRemove/management.cattle.io.globalrole.vue +1 -1
  118. package/promptRemove/management.cattle.io.project.vue +2 -2
  119. package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
  120. package/promptRemove/pod.vue +1 -1
  121. package/rancher-components/Form/Radio/RadioGroup.vue +25 -23
  122. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +3 -3
  123. package/rancher-components/RcDropdown/RcDropdown.vue +6 -5
  124. package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -2
  125. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +12 -2
  126. package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
  127. package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
  128. package/scripts/extension/publish +1 -0
  129. package/server/har-file.js +25 -3
  130. package/store/features.js +2 -1
  131. package/store/type-map.js +4 -0
  132. package/types/shell/index.d.ts +9 -2
  133. package/utils/__tests__/string.test.ts +2 -2
  134. package/utils/cluster.js +35 -0
  135. package/utils/string.js +1 -3
  136. package/utils/validators/machine-pool.ts +20 -0
  137. package/components/formatter/ExtensionCache.vue +0 -74
  138. package/components/formatter/Port.vue +0 -24
  139. package/components/formatter/SecretType.vue +0 -41
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "3.0.3",
3
+ "version": "3.0.5-rc.1",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -51,7 +51,7 @@
51
51
  "add": "2.0.6",
52
52
  "ansi_up": "5.0.0",
53
53
  "axios-retry": "3.1.9",
54
- "axios": "0.21.4",
54
+ "axios": "1.8.4",
55
55
  "babel-eslint": "10.1.0",
56
56
  "babel-plugin-module-resolver": "4.0.0",
57
57
  "babel-preset-vue": "2.0.2",
@@ -75,7 +75,7 @@
75
75
  "dayjs": "1.8.29",
76
76
  "defu": "5.0.1",
77
77
  "diff2html": "3.4.24",
78
- "dompurify": "2.5.4",
78
+ "dompurify": "3.2.5",
79
79
  "element-matches": "^0.1.2",
80
80
  "entities": "4.5.0",
81
81
  "eslint-config-standard": "16.0.3",
@@ -105,7 +105,7 @@
105
105
  "js-yaml-loader": "1.2.2",
106
106
  "js-yaml": "4.1.0",
107
107
  "jsdiff": "1.1.1",
108
- "jsonpath-plus": "10.0.7",
108
+ "jsonpath-plus": "10.3.0",
109
109
  "jsrsasign": "11.0.0",
110
110
  "jszip": "3.8.0",
111
111
  "lodash": "4.17.21",
package/pages/about.vue CHANGED
@@ -119,8 +119,12 @@ export default {
119
119
  <table>
120
120
  <thead>
121
121
  <tr>
122
- <th>{{ t('about.versions.component') }}</th>
123
- <th>{{ t('about.versions.version') }}</th>
122
+ <th class="custom-th">
123
+ {{ t('about.versions.component') }}
124
+ </th>
125
+ <th class="custom-th">
126
+ {{ t('about.versions.version') }}
127
+ </th>
124
128
  </tr>
125
129
  </thead>
126
130
  <tr v-if="rancherVersion">
@@ -210,11 +214,11 @@ export default {
210
214
  v-for="(d, i) in downloadImageList"
211
215
  :key="i"
212
216
  >
213
- <td>
217
+ <th>
214
218
  <div class="os">
215
219
  <i :class="`icon ${d.icon} mr-5`" /> {{ t(d.label) }}
216
220
  </div>
217
- </td>
221
+ </th>
218
222
  <td>
219
223
  <a
220
224
  v-if="d.imageList"
@@ -241,11 +245,11 @@ export default {
241
245
  :key="i"
242
246
  class="link"
243
247
  >
244
- <td>
248
+ <th>
245
249
  <div class="os">
246
250
  <i :class="`icon ${d.icon} mr-5`" /> {{ t(d.label) }}
247
251
  </div>
248
- </td>
252
+ </th>
249
253
  <td>
250
254
  <a
251
255
  v-if="d.cliLink"
@@ -273,7 +277,7 @@ export default {
273
277
  overflow: hidden;
274
278
  border-radius: var(--border-radius);
275
279
 
276
- tr > td:first-of-type {
280
+ tr > th:first-of-type {
277
281
  width: 20%;
278
282
  }
279
283
 
@@ -284,11 +288,15 @@ export default {
284
288
  text-align: left;
285
289
  }
286
290
 
287
- th {
291
+ th.custom-th {
288
292
  background-color: var(--sortable-table-top-divider);
289
293
  border-bottom: 1px solid var(--sortable-table-top-divider);
290
294
  }
291
295
 
296
+ th:not(.custom-th) {
297
+ font-weight: normal;
298
+ }
299
+
292
300
  a {
293
301
  cursor: pointer;
294
302
  }
@@ -179,7 +179,10 @@ export default {
179
179
  <h2 v-t="'accountAndKeys.apiKeys.title'" />
180
180
  <div class="api-url">
181
181
  <span>{{ t("accountAndKeys.apiKeys.apiEndpoint") }}</span>
182
- <CopyToClipboardText :text="apiUrl" />
182
+ <CopyToClipboardText
183
+ :aria-label="t('accountAndKeys.apiKeys.copyApiEnpoint')"
184
+ :text="apiUrl"
185
+ />
183
186
  </div>
184
187
  </div>
185
188
  <button
@@ -31,11 +31,12 @@ import {
31
31
  import loadPlugins from '@shell/plugins/plugin';
32
32
  import Loading from '@shell/components/Loading';
33
33
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
34
+ import TabTitle from '@shell/components/TabTitle.vue';
34
35
 
35
36
  export default {
36
37
  name: 'Login',
37
38
  components: {
38
- LabeledInput, AsyncButton, Checkbox, BrandImage, Banner, InfoBox, CopyCode, Password, LocaleSelector, Loading
39
+ LabeledInput, AsyncButton, Checkbox, BrandImage, Banner, InfoBox, CopyCode, Password, LocaleSelector, Loading, TabTitle
39
40
  },
40
41
 
41
42
  data() {
@@ -311,10 +312,16 @@ export default {
311
312
  v-if="$fetchState.pending"
312
313
  mode="relative"
313
314
  />
314
- <main
315
+ <div
315
316
  v-else
316
317
  class="main-layout login"
317
318
  >
319
+ <TabTitle
320
+ :show-child="false"
321
+ :breadcrumb="false"
322
+ >
323
+ {{ `${vendor} - ${t('login.login')}` }}
324
+ </TabTitle>
318
325
  <div class="row gutless mb-20">
319
326
  <div class="col span-6 p-20">
320
327
  <p class="text-center">
@@ -509,9 +516,10 @@ export default {
509
516
  class="col span-6 landscape"
510
517
  data-testid="login-landscape__img"
511
518
  file-name="login-landscape.svg"
519
+ :alt="t('login.landscapeAlt')"
512
520
  />
513
521
  </div>
514
- </main>
522
+ </div>
515
523
  </template>
516
524
 
517
525
  <style lang="scss" scoped>
@@ -28,7 +28,10 @@ export default {
28
28
  </script>
29
29
 
30
30
  <template>
31
- <main class="main-layout">
31
+ <main
32
+ class="main-layout"
33
+ :aria-label="t('layouts.logout')"
34
+ >
32
35
  <div>
33
36
  <h1 v-t="'logout.message'" />
34
37
  </div>
@@ -331,6 +331,7 @@ export default {
331
331
  style="padding: 0 0 0 12px;"
332
332
  >
333
333
  <CopyToClipboard
334
+ :aria-label="t('setup.copyRandom')"
334
335
  :text="password"
335
336
  class="btn-sm"
336
337
  />
@@ -182,7 +182,10 @@ export default {
182
182
  </script>
183
183
 
184
184
  <template>
185
- <main class="main-layout">
185
+ <main
186
+ class="main-layout"
187
+ :aria-label="t('layouts.verify')"
188
+ >
186
189
  <h1 class="text-center mt-50">
187
190
  <span v-if="testing">
188
191
  Testing Configuration&hellip;
@@ -69,7 +69,7 @@ export default {
69
69
  return {
70
70
  id: m.name,
71
71
  text: m.name,
72
- url: `mailto:${ m.email }`
72
+ url: m.email ? `mailto:${ m.email }` : m.url
73
73
  };
74
74
  });
75
75
  },
@@ -17,6 +17,7 @@ export default {
17
17
  const finalCounts = [];
18
18
  const promises = [];
19
19
  const topFifteenForResponseTime = [];
20
+ const schemaPromises = [];
20
21
 
21
22
  clusterForCounts.forEach((cluster, i) => {
22
23
  // Necessary to retrieve the proper display name of the cluster
@@ -31,9 +32,11 @@ export default {
31
32
  isTableVisible: !!(i === 0 && clusterForCounts.length === 1)
32
33
  });
33
34
  promises.push(this.$store.dispatch('management/request', { url: `/k8s/clusters/${ cluster.mgmt?.id }/v1/counts` }));
35
+ schemaPromises.push(this.$store.dispatch('management/request', { url: `/k8s/clusters/${ cluster.mgmt?.id }/v1/schemas?exclude=metadata.managedFields` }));
34
36
  });
35
37
 
36
38
  const countsPerCluster = await Promise.all(promises);
39
+ const schemasPerCluster = await Promise.all(schemaPromises);
37
40
 
38
41
  countsPerCluster.forEach((clusterCount, index) => {
39
42
  const counts = clusterCount.data?.[0]?.counts;
@@ -69,6 +72,14 @@ export default {
69
72
 
70
73
  this.topFifteenForResponseTime = topFifteenForResponseTime;
71
74
  this.finalCounts = finalCounts;
75
+
76
+ // Schemas
77
+ schemasPerCluster.forEach((schemas, index) => {
78
+ finalCounts[index].schemaCount = schemas?.data?.length || 0;
79
+ finalCounts[index].customSchemas = (schemas?.data?.filter((schema) => {
80
+ return schema.attributes?.group.includes('.') && !schema.attributes?.group.includes('.cattle.io') && !schema.attributes?.group.includes('.k8s.io');
81
+ }).map((schema) => schema.id) || []).sort();
82
+ });
72
83
  },
73
84
 
74
85
  data() {
@@ -148,7 +159,7 @@ export default {
148
159
  systemInformation: this.systemInformation,
149
160
  storeMapping: this.parseStoreData(this.storeMapping),
150
161
  resourceCounts: this.finalCounts,
151
- responseTimes: this.responseTimes
162
+ responseTimes: this.responseTimes,
152
163
  };
153
164
 
154
165
  downloadFile(fileName, JSON.stringify(data), 'application/json')
@@ -352,6 +363,7 @@ export default {
352
363
  <span>Cluster: <b>{{ cluster.name }}</b></span>
353
364
  <span>Namespace: <b>{{ cluster.namespace }}</b></span>
354
365
  <span>Total Resources: <b>{{ sumResourceCount(cluster.counts) }}</b></span>
366
+ <span>Total Schemas: <b>{{ cluster.schemaCount }}</b></span>
355
367
  <span>Nodes: <b>{{ nodeCount(cluster.counts) }}</b></span>
356
368
  <i
357
369
  class="icon"
@@ -365,6 +377,22 @@ export default {
365
377
  </tr>
366
378
  </thead>
367
379
  <tbody v-show="cluster.isTableVisible">
380
+ <tr>
381
+ <td colspan="3">
382
+ <div class="schema-title">
383
+ Custom Schemas
384
+ </div>
385
+ <div class="custom-schemas">
386
+ <div
387
+ v-for="name in cluster.customSchemas"
388
+ :key="name"
389
+ class="schema-name"
390
+ >
391
+ {{ name }}
392
+ </div>
393
+ </div>
394
+ </td>
395
+ </tr>
368
396
  <tr>
369
397
  <th>
370
398
  Resource
@@ -445,6 +473,23 @@ table {
445
473
  padding: 8px 5px;
446
474
  min-width: 150px;
447
475
  text-align: left;
476
+
477
+ .schema-title {
478
+ font-weight: bold;
479
+ margin-bottom: 4px;
480
+ }
481
+
482
+ .custom-schemas {
483
+ display: flex;
484
+ flex-wrap: wrap;
485
+
486
+ > .schema-name {
487
+ margin-right: 5px;
488
+ margin-bottom: 2px;
489
+ border: 1px solid var(--border);
490
+ padding: 2px 5px;
491
+ }
492
+ }
448
493
  }
449
494
 
450
495
  th {
@@ -511,7 +556,7 @@ table {
511
556
  .resources-count-container {
512
557
  .cluster-row {
513
558
  display: grid;
514
- grid-template-columns: repeat(4, 1fr) 20px;
559
+ grid-template-columns: repeat(5, 1fr) 20px;
515
560
  grid-template-rows: 1fr;
516
561
  align-content: center;
517
562
  font-weight: normal;
@@ -70,12 +70,15 @@ export default {
70
70
  :simple="true"
71
71
  />
72
72
 
73
- <main class="main-layout">
73
+ <main
74
+ class="main-layout"
75
+ aria-label="Fail whale layout"
76
+ >
74
77
  <div
75
78
  v-if="error"
76
79
  class="outlet"
77
80
  >
78
- <main class="main-layout error">
81
+ <div class="main-layout error">
79
82
  <div class="text-center">
80
83
  <BrandImage
81
84
  file-name="error-desert-landscape.svg"
@@ -115,7 +118,7 @@ export default {
115
118
  </a>
116
119
  </p>
117
120
  </div>
118
- </main>
121
+ </div>
119
122
  </div>
120
123
  </main>
121
124
  </div>
package/pages/home.vue CHANGED
@@ -49,6 +49,21 @@ export default defineComponent({
49
49
  mixins: [PageHeaderActions],
50
50
 
51
51
  data() {
52
+ const options = this.$store.getters[`type-map/optionsFor`](CAPI.RANCHER_CLUSTER)?.custom || {};
53
+ const params = {
54
+ product: MANAGER,
55
+ cluster: BLANK_CLUSTER,
56
+ resource: CAPI.RANCHER_CLUSTER
57
+ };
58
+ const defaultCreateLocation = {
59
+ name: 'c-cluster-product-resource-create',
60
+ params,
61
+ };
62
+ const defaultImportLocation = {
63
+ ...defaultCreateLocation,
64
+ query: { [MODE]: _IMPORT }
65
+ };
66
+
52
67
  return {
53
68
  HIDE_HOME_PAGE_CARDS,
54
69
  fullVersion: getVersionInfo(this.$store).fullVersion,
@@ -87,24 +102,9 @@ export default defineComponent({
87
102
  },
88
103
  },
89
104
 
90
- createLocation: {
91
- name: 'c-cluster-product-resource-create',
92
- params: {
93
- product: MANAGER,
94
- cluster: BLANK_CLUSTER,
95
- resource: CAPI.RANCHER_CLUSTER
96
- },
97
- },
105
+ createLocation: options.createLocation ? options.createLocation(params) : defaultCreateLocation,
98
106
 
99
- importLocation: {
100
- name: 'c-cluster-product-resource-create',
101
- params: {
102
- product: MANAGER,
103
- cluster: BLANK_CLUSTER,
104
- resource: CAPI.RANCHER_CLUSTER
105
- },
106
- query: { [MODE]: _IMPORT }
107
- },
107
+ importLocation: options.importLocation ? options.importLocation(params) : defaultImportLocation,
108
108
 
109
109
  headers: [
110
110
  STATE,
@@ -512,7 +512,7 @@ export default defineComponent({
512
512
  :show-child="false"
513
513
  :breadcrumb="false"
514
514
  >
515
- {{ vendor }}
515
+ {{ `${vendor} - ${t('landing.homepage')}` }}
516
516
  </TabTitle>
517
517
  <BannerGraphic
518
518
  :small="true"
@@ -805,6 +805,12 @@ export default defineComponent({
805
805
  .cluster-name {
806
806
  display: flex;
807
807
  align-items: center;
808
+
809
+ // Ensure long cluster names truncate with ellipsis
810
+ > A {
811
+ overflow: hidden;
812
+ text-overflow: ellipsis;
813
+ }
808
814
  }
809
815
 
810
816
  .cluster-description {
@@ -118,7 +118,10 @@ export default {
118
118
  </script>
119
119
  <template>
120
120
  <div>
121
- <BannerGraphic :title="t(title, {}, true)" />
121
+ <BannerGraphic
122
+ :title="t(title, {}, true)"
123
+ :alt="t('support.bannerImage')"
124
+ />
122
125
 
123
126
  <IndentedPanel>
124
127
  <div class="content mt-20">
@@ -71,7 +71,7 @@ export default {
71
71
  <div class="mt-10">
72
72
  <div class="mb-10">
73
73
  {{ t('promptRemove.attemptingToRemove', { type }) }} <span
74
- v-clean-html="resourceNames(names, t)"
74
+ v-clean-html="resourceNames(names, null, t)"
75
75
  class="description"
76
76
  />
77
77
  </div>
@@ -21,7 +21,7 @@ export default {
21
21
 
22
22
  <template>
23
23
  <div>
24
- {{ t('promptRemove.attemptingToRemove', { type }) }} <span v-clean-html="resourceNames(names, t)" />
24
+ {{ t('promptRemove.attemptingToRemove', { type }) }} <span v-clean-html="resourceNames(names, null, t)" />
25
25
  <div
26
26
  v-if="info"
27
27
  class="text info mb-10 mt-20"
@@ -94,7 +94,7 @@ export default {
94
94
  <template v-if="!canSeeProjectlessNamespaces">
95
95
  <span class="delete-warning"> {{ t('promptRemove.willDeleteAssociatedNamespaces') }}</span> <br>
96
96
  <div
97
- v-clean-html="resourceNames(names, t)"
97
+ v-clean-html="resourceNames(names, null, t)"
98
98
  class="mt-10"
99
99
  />
100
100
  </template>
@@ -108,7 +108,7 @@ export default {
108
108
  :label="t('promptRemove.deleteAssociatedNamespaces')"
109
109
  />
110
110
  <div class="mt-10 ml-20">
111
- <span v-clean-html="resourceNames(names, t)" />
111
+ <span v-clean-html="resourceNames(names, null, t)" />
112
112
  </div>
113
113
  </div>
114
114
  </div>
@@ -22,7 +22,7 @@ export default {
22
22
  <template>
23
23
  <div>
24
24
  {{ t('promptRemove.attemptingToRemove', { type }) }} <span
25
- v-clean-html="resourceNames(names, t)"
25
+ v-clean-html="resourceNames(names, null, t)"
26
26
  />
27
27
  <div
28
28
  v-if="info"
@@ -98,7 +98,7 @@ export default {
98
98
  <div class="mt-10">
99
99
  <div class="mb-30">
100
100
  {{ t('promptRemove.attemptingToRemove', { type }) }} <span
101
- v-clean-html="resourceNames(names, t)"
101
+ v-clean-html="resourceNames(names, null, t)"
102
102
  class="body"
103
103
  />
104
104
  </div>
@@ -199,33 +199,35 @@ export default defineComponent({
199
199
  </script>
200
200
 
201
201
  <template>
202
- <div>
202
+ <fieldset>
203
203
  <!-- Label -->
204
204
  <div
205
205
  v-if="label || labelKey || tooltip || tooltipKey || $slots.label"
206
206
  class="radio-group label"
207
207
  >
208
- <slot name="label">
209
- <h3>
210
- <t
211
- v-if="labelKey"
212
- :k="labelKey"
213
- />
214
- <template v-else-if="label">
215
- {{ label }}
216
- </template>
217
- <i
218
- v-if="tooltipKey"
219
- v-clean-tooltip="t(tooltipKey)"
220
- class="icon icon-info icon-lg"
221
- />
222
- <i
223
- v-else-if="tooltip"
224
- v-clean-tooltip="tooltip"
225
- class="icon icon-info icon-lg"
226
- />
227
- </h3>
228
- </slot>
208
+ <legend>
209
+ <slot name="label">
210
+ <h3>
211
+ <t
212
+ v-if="labelKey"
213
+ :k="labelKey"
214
+ />
215
+ <template v-else-if="label">
216
+ {{ label }}
217
+ </template>
218
+ <i
219
+ v-if="tooltipKey"
220
+ v-clean-tooltip="t(tooltipKey)"
221
+ class="icon icon-info icon-lg"
222
+ />
223
+ <i
224
+ v-else-if="tooltip"
225
+ v-clean-tooltip="tooltip"
226
+ class="icon icon-info icon-lg"
227
+ />
228
+ </h3>
229
+ </slot>
230
+ </legend>
229
231
  </div>
230
232
 
231
233
  <!-- Group -->
@@ -266,7 +268,7 @@ export default defineComponent({
266
268
  </slot>
267
269
  </div>
268
270
  </div>
269
- </div>
271
+ </fieldset>
270
272
  </template>
271
273
 
272
274
  <style lang='scss'>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { defineComponent, onMounted, onBeforeUnmount, useTemplateRef } from 'vue';
2
+ import { defineComponent, onMounted, onBeforeUnmount, ref } from 'vue';
3
3
 
4
4
  type StateType = boolean | 'true' | 'false' | undefined;
5
5
 
@@ -34,7 +34,7 @@ export default defineComponent({
34
34
  emits: ['update:value'],
35
35
 
36
36
  setup() {
37
- const switchChrome = useTemplateRef<HTMLElement>('switchChrome');
37
+ const switchChrome = ref<HTMLElement | null>(null);
38
38
  const focus = () => {
39
39
  switchChrome.value?.classList.add('focus');
40
40
  };
@@ -43,7 +43,7 @@ export default defineComponent({
43
43
  switchChrome.value?.classList.remove('focus');
44
44
  };
45
45
 
46
- const switchInput = useTemplateRef<HTMLInputElement>('switchInput');
46
+ const switchInput = ref<HTMLInputElement | null>(null);
47
47
 
48
48
  onMounted(() => {
49
49
  switchInput.value?.addEventListener('focus', focus);
@@ -20,7 +20,7 @@
20
20
  * </template>
21
21
  * </rc-dropdown>
22
22
  */
23
- import { useTemplateRef } from 'vue';
23
+ import { ref } from 'vue';
24
24
  import { useClickOutside } from '@shell/composables/useClickOutside';
25
25
  import { useDropdownContext } from '@components/RcDropdown/useDropdownContext';
26
26
 
@@ -42,14 +42,14 @@ const {
42
42
 
43
43
  provideDropdownContext();
44
44
 
45
- const popperContainer = useTemplateRef<HTMLElement>('popperContainer');
46
- const dropdownTarget = useTemplateRef<HTMLElement>('dropdownTarget');
45
+ const popperContainer = ref(null);
46
+ const dropdownTarget = ref(null);
47
47
 
48
48
  useClickOutside(dropdownTarget, () => showMenu(false));
49
49
 
50
50
  const applyShow = () => {
51
51
  registerDropdownCollection(dropdownTarget.value);
52
- setFocus();
52
+ setFocus('down');
53
53
  };
54
54
 
55
55
  </script>
@@ -78,7 +78,8 @@ const applyShow = () => {
78
78
  dropdown-menu-collection
79
79
  :aria-label="ariaLabel || 'Dropdown Menu'"
80
80
  @keydown="handleKeydown"
81
- @keydown.down="setFocus()"
81
+ @keydown.down="setFocus('down')"
82
+ @keydown.up="setFocus('up')"
82
83
  >
83
84
  <slot name="dropdownCollection">
84
85
  <!--Empty slot content-->
@@ -8,8 +8,10 @@ import {
8
8
  import { RcDropdownMenuComponentProps, DropdownOption } from './types';
9
9
  import IconOrSvg from '@shell/components/IconOrSvg';
10
10
 
11
- // eslint-disable-next-line vue/no-setup-props-destructure
12
- const { buttonRole = 'primary', buttonSize = '' } = defineProps<RcDropdownMenuComponentProps>();
11
+ withDefaults(defineProps<RcDropdownMenuComponentProps>(), {
12
+ buttonRole: 'primary',
13
+ buttonSize: undefined,
14
+ });
13
15
 
14
16
  const emit = defineEmits(['update:open', 'select']);
15
17
 
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * A button that opens a menu. Used in conjunction with `RcDropdown.vue`.
4
4
  */
5
- import { inject, onMounted, useTemplateRef } from 'vue';
5
+ import { inject, onMounted, ref } from 'vue';
6
6
  import { RcButton, RcButtonType } from '@components/RcButton';
7
7
  import { DropdownContext, defaultContext } from './types';
8
8
 
@@ -13,7 +13,7 @@ const {
13
13
  handleKeydown,
14
14
  } = inject<DropdownContext>('dropdownContext') || defaultContext;
15
15
 
16
- const dropdownTrigger = useTemplateRef<RcButtonType>('dropdownTrigger');
16
+ const dropdownTrigger = ref<RcButtonType | null>(null);
17
17
 
18
18
  onMounted(() => {
19
19
  registerTrigger(dropdownTrigger.value);
@@ -35,8 +35,18 @@ defineExpose({ focus });
35
35
  @keydown.enter.space="handleKeydown"
36
36
  @click="showMenu(true)"
37
37
  >
38
+ <template #before>
39
+ <slot name="before">
40
+ <!-- Empty Content -->
41
+ </slot>
42
+ </template>
38
43
  <slot name="default">
39
44
  <!--Empty slot content-->
40
45
  </slot>
46
+ <template #after>
47
+ <slot name="after">
48
+ <!-- Empty Content -->
49
+ </slot>
50
+ </template>
41
51
  </RcButton>
42
52
  </template>