@rancher/shell 3.0.8-rc.8 → 3.0.8-rc.9

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 (142) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -64
  2. package/assets/translations/en-us.yaml +9 -1
  3. package/components/BackLink.vue +8 -0
  4. package/components/BannerGraphic.vue +1 -5
  5. package/components/BrandImage.vue +17 -6
  6. package/components/Cron/CronExpressionEditor.vue +1 -1
  7. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  8. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +1 -0
  9. package/components/Drawer/ResourceDetailDrawer/index.vue +1 -0
  10. package/components/Drawer/ResourceDetailDrawer/types.ts +2 -1
  11. package/components/Questions/__tests__/index.test.ts +159 -0
  12. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  13. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  14. package/components/Resource/Detail/Metadata/index.vue +3 -3
  15. package/components/Resource/Detail/composables.ts +2 -2
  16. package/components/Tabbed/__tests__/index.test.ts +86 -0
  17. package/components/auth/SelectPrincipal.vue +24 -6
  18. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  19. package/components/formatter/InternalExternalIP.vue +4 -1
  20. package/components/formatter/__tests__/InternalExternalIP.test.ts +1 -1
  21. package/components/templates/standalone.vue +1 -1
  22. package/composables/useI18n.ts +10 -1
  23. package/config/__test__/uiplugins.test.ts +309 -0
  24. package/config/labels-annotations.js +1 -0
  25. package/config/product/explorer.js +3 -1
  26. package/config/router/routes.js +6 -2
  27. package/config/types.js +7 -0
  28. package/config/uiplugins.js +46 -2
  29. package/core/__test__/extension-manager-impl.test.js +236 -0
  30. package/core/extension-manager-impl.js +23 -6
  31. package/core/types-provisioning.ts +1 -1
  32. package/detail/provisioning.cattle.io.cluster.vue +1 -0
  33. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  34. package/dialog/RollbackWorkloadDialog.vue +2 -5
  35. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +2 -2
  36. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  37. package/edit/configmap.vue +1 -0
  38. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  39. package/edit/fleet.cattle.io.helmop.vue +6 -6
  40. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  41. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  42. package/edit/logging-flow/index.vue +1 -0
  43. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  44. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  45. package/edit/management.cattle.io.project.vue +1 -0
  46. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  47. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  48. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  49. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  50. package/edit/monitoring.coreos.com.route.vue +1 -1
  51. package/edit/namespace.vue +1 -0
  52. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  53. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  54. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  55. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  56. package/edit/node.vue +1 -0
  57. package/edit/persistentvolume/index.vue +27 -22
  58. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  59. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  60. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  61. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  62. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  63. package/edit/persistentvolume/plugins/csi.vue +18 -16
  64. package/edit/persistentvolume/plugins/fc.vue +13 -14
  65. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  66. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  67. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  68. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  69. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  70. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  71. package/edit/persistentvolume/plugins/local.vue +1 -3
  72. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  73. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  74. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  75. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  76. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  77. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  78. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  79. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  80. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  81. package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -0
  82. package/edit/secret/index.vue +1 -1
  83. package/edit/service.vue +1 -0
  84. package/edit/serviceaccount.vue +1 -0
  85. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  86. package/edit/workload/index.vue +2 -1
  87. package/edit/workload/mixins/workload.js +1 -1
  88. package/initialize/App.vue +4 -4
  89. package/initialize/install-plugins.js +17 -2
  90. package/mixins/__tests__/brand.spec.ts +2 -2
  91. package/mixins/brand.js +1 -7
  92. package/mixins/create-edit-view/index.js +5 -0
  93. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  94. package/models/management.cattle.io.cluster.js +21 -3
  95. package/models/provisioning.cattle.io.cluster.js +21 -9
  96. package/package.json +5 -4
  97. package/pages/auth/login.vue +1 -3
  98. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  99. package/pages/c/_cluster/apps/charts/chart.vue +33 -15
  100. package/pages/c/_cluster/explorer/index.vue +8 -6
  101. package/pages/c/_cluster/manager/hostedprovider/index.vue +12 -6
  102. package/pages/c/_cluster/settings/brand.vue +1 -1
  103. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  104. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  105. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  106. package/plugins/dashboard-client-init.js +3 -0
  107. package/plugins/dashboard-store/getters.js +18 -1
  108. package/plugins/dashboard-store/resource-class.js +3 -2
  109. package/plugins/i18n.js +8 -0
  110. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  111. package/plugins/steve/steve-pagination-utils.ts +39 -20
  112. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -42
  113. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  114. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  115. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  116. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  117. package/rancher-components/Pill/types.ts +0 -1
  118. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  119. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  120. package/rancher-components/RcIcon/index.ts +1 -0
  121. package/rancher-components/RcIcon/types.ts +160 -0
  122. package/rancher-components/utils/status.test.ts +67 -0
  123. package/rancher-components/utils/status.ts +77 -0
  124. package/scripts/typegen.sh +1 -0
  125. package/store/action-menu.js +8 -0
  126. package/store/auth.js +3 -3
  127. package/store/catalog.js +6 -0
  128. package/store/index.js +4 -4
  129. package/store/prefs.js +4 -5
  130. package/store/wm.ts +4 -4
  131. package/types/shell/index.d.ts +38 -2
  132. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  133. package/types/store/pagination.types.ts +157 -9
  134. package/utils/__tests__/provider.test.ts +98 -0
  135. package/utils/__tests__/selector-typed.test.ts +263 -0
  136. package/utils/color.js +1 -1
  137. package/utils/dynamic-content/__tests__/info.test.ts +6 -0
  138. package/utils/dynamic-content/info.ts +43 -0
  139. package/utils/favicon.js +4 -4
  140. package/utils/provider.ts +14 -0
  141. package/utils/selector-typed.ts +6 -2
  142. package/plugins/nuxt-client-init.js +0 -3
@@ -1,64 +1 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Layer_2_00000129197277348757038330000010842559623398722730_"
4
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 439.6 36.2"
5
- style="enable-background:new 0 0 439.6 36.2;" xml:space="preserve">
6
- <style type="text/css">
7
- .st0{fill:#FFFFFF;}
8
- </style>
9
- <g id="Layer_1-2">
10
- <g id="Layer_1-3">
11
- <path class="st0" d="M67.1,11.3c-0.4-0.5-1.2-0.5-1.6,0c-0.5,0.5-0.4,1.4,0.2,1.8c0.4,0.2,0.9,0.2,1.3,0
12
- C67.5,12.7,67.6,11.8,67.1,11.3 M65.6,7.4c-3.1-0.7-5.8,2-5.1,5.1c0.4,1.6,1.6,2.8,3.2,3.2c3.1,0.7,5.9-2.1,5.1-5.1
13
- C68.4,9,67.2,7.8,65.6,7.4 M45.3,24.7c-2-0.7-2.8-0.6-5.3-0.6c-1.8,0-1.8,0-3.9,0c-0.6,0-0.9,3,1.4,3.6c1,0.3,2.1,0.5,2.8,1.2
14
- c0.3,0.3,0.5,0.9-0.2,0.9h-5.6c-1,0-1.9,0-2.7-0.6c-1.1-1-1.7-2.3-2.2-3.6c-0.6-1.4-1.2-2.7-2-4c-1.5-2.6-3.5-4.9-6.1-6.3
15
- c-3.3-1.8-8.9-2.6-13.3,0.8c-4.7,3.6-3.7,10.3,0.4,13.6c1.6,1.3,3.7,1.8,5.8,1.7c4-0.2,7-3.2,6.3-6.9c-0.2-1.2-1-2.4-2-3
16
- c-0.8-0.5-1.7-0.6-2.6-0.6c-0.9,0-2,0.2-2.6,0.9c-0.8,0.8-0.9,2.2-0.3,3.1c0.4,0.5,0.9,0.9,0.8,1.6c-0.1,0.5-0.4,0.8-0.9,0.9
17
- c-0.8,0.2-1.4-0.3-2-0.8c-1.3-1.4-1.7-3.5-1-5.2c0.9-2.3,3.6-3.5,6-3.5c3.2,0.1,6.2,2.2,7.5,5.1s0.9,6.5-0.9,9.1
18
- c-4,5.8-13.8,5.1-18.4,0.2C1.4,29.2-0.2,26.2,0,20.6c0.2-3.9,2.4-7.8,5.3-10.6c4.7-4.4,10.9-7.5,17.3-8.8c3.8-0.8,7.8-1,11.7-0.6
19
- c3.4,0.3,6.9,1,10.2,2c1.6,0.5,3.2,1.1,4.8,1.8c1.4,0.6,3.2,1.3,4.2,2.4c0-2-0.1-4.2-0.1-5.7c0-0.6,0.6-1,1.1-0.7
20
- c2.2,1,7.5,3.5,11.1,5.2c4.7,2.2,5.1,7.3,5.2,11.8c0,0.1,0,0.2,0,0.3c-0.2,0.3-0.9,0.2-1.2,0.2c-0.6,0-1.4,0-2,0
21
- c-1.1,0-2.2,0-3.4,0c-2.1-0.1-4.1-1-5.5-2.2c-0.1-0.1-0.6-0.2-0.8,0s-0.1,0.6,0,0.7c0.8,0.8,1.6,1.3,2.6,1.8
22
- c1.2,0.6,2.6,0.8,4,0.9c1.5,0.1,2.9,0.1,4.4-0.1c1.2-0.1,1.5-0.2,0.3,0.7c-1.1,0.8-2.3,1.4-3.6,1.8c-1.8,0.6-3.7,0.9-5.6,1
23
- c-1.2,0-2.3,0-3.4-0.2c-0.6-0.1-1.2-0.2-1.8-0.2c-0.5,0-1-0.1-1.5,0c-0.4,0.1-0.8,0.3-1.1,0.7c-0.4,0.5-0.5,1.8-0.3,2.4
24
- c0.4,1.1,1.3,1.8,2.3,2.4c1,0.6,2.4,0.8,2.7,2c0.1,0.2-2.2,0.3-2.4,0.2h-3c0,0-1.6,0-2.2-0.2c0,0,0,0-0.1,0
25
- c-0.3-0.2-0.5-0.6-0.6-1c-0.2-0.5-0.5-1-0.8-1.5C47.3,26.2,46.3,25.1,45.3,24.7 M67.8,11.6c0,1.7-1.4,3.2-3.2,3.2
26
- s-3.2-1.4-3.2-3.1s1.4-3.1,3.2-3.1C66.4,8.4,67.8,9.8,67.8,11.6"/>
27
- </g>
28
- <path class="st0" d="M80.4,25.5l3-3c2.2,2.2,4.2,3.1,6.5,3.1c3.2,0,5-1.6,5-4c0-6.4-14-2.8-14-12.5c0-5.2,3.9-8.5,9.8-8.5
29
- c3.6,0,6.6,1.4,8.5,3.5l-3.1,3.1c-1.6-1.6-3.2-2.5-5.4-2.5c-3,0-4.9,1.5-4.9,3.9c0,6.1,14.1,2.1,14.1,12.2c0,5.4-4.1,8.8-10.2,8.8
30
- C85.6,29.8,82.6,28.1,80.4,25.5z"/>
31
- <path class="st0" d="M104.5,19.5V1.2h4.9v17.9c0,4.1,2.4,6.1,6,6.1s5.9-2,5.9-6.1V1.2h4.9v18.3c0,6.8-4.3,10.2-10.8,10.2
32
- S104.5,26.4,104.5,19.5z"/>
33
- <path class="st0" d="M130.7,25.5l3-3c2.2,2.2,4.2,3.1,6.5,3.1c3.2,0,5-1.6,5-4c0-6.4-14-2.8-14-12.5c0-5.2,3.9-8.5,9.8-8.5
34
- c3.6,0,6.6,1.4,8.5,3.5l-3.1,3.1c-1.6-1.6-3.2-2.5-5.4-2.5c-3,0-4.9,1.5-4.9,3.9c0,6.1,14.1,2.1,14.1,12.2c0,5.4-4.1,8.8-10.2,8.8
35
- C135.9,29.8,132.8,28.1,130.7,25.5L130.7,25.5z"/>
36
- <path class="st0" d="M154.4,24.5V5.9c0-2.7,2-4.7,4.7-4.7h13.6v4.5h-12c-0.8,0-1.5,0.6-1.5,1.4V13h12.6v4.3h-12.6v6
37
- c0,0.8,0.6,1.4,1.5,1.4h12v4.5h-13.6C156.4,29.2,154.4,27.2,154.4,24.5z"/>
38
- <path class="st0" d="M187.5,1.2h9c5.6,0,9.4,2.9,9.4,8.4c0,4.7-2.5,7.3-6.5,8.1l7.4,11.5h-4l-7-11.2h-4.9v11.2h-3.4L187.5,1.2
39
- L187.5,1.2z M196.4,15c3.6,0,6.1-1.7,6.1-5.4c0-3.5-2.4-5.5-6.1-5.5h-5.4V15C190.9,15,196.4,15,196.4,15z"/>
40
- <path class="st0" d="M222.9,27.3c-1.1,1.5-3,2.3-5.7,2.3c-4.6,0-7.4-2.3-7.4-5.7s2.8-6,7.8-6c2.1,0,3.7,0.5,4.9,1.3v-2.5
41
- c0-2.9-1.5-4.3-4.5-4.3c-2,0-4.4,0.8-6,2.3l-1.5-2.2c1.7-2,4.7-3,7.7-3c4.5,0,7.6,2.4,7.6,7.2v6.2c0,2.1,0,4.2,0.1,6.3h-2.9
42
- C222.9,29.2,222.9,27.3,222.9,27.3z M217.8,27.2c2.9,0,4.7-1.3,4.7-3.3s-1.8-3.3-4.7-3.3s-4.8,1.3-4.8,3.3S215,27.2,217.8,27.2z"/>
43
- <path class="st0" d="M232,10h3.1v3c1.6-2.6,4.3-3.4,6.4-3.4c4.3,0,7.3,2.8,7.3,8.3v11.3h-3.2V18.4c0-4.1-2.1-5.8-4.9-5.8
44
- c-3,0-5.4,2-5.4,5.9v10.8H232L232,10L232,10z"/>
45
- <path class="st0" d="M253.5,19.8v-0.5c0-5.8,4.2-9.8,9.9-9.8c2.8,0,5.2,1.1,6.8,3l-2,2c-1.2-1.3-2.8-2-4.8-2
46
- c-3.8,0-6.7,2.7-6.7,6.8v0.5c0,4.1,2.8,6.8,6.7,6.8c1.9,0,3.5-0.6,4.8-1.9l2,2c-1.6,1.9-4.1,3-6.8,3
47
- C257.7,29.6,253.5,25.6,253.5,19.8L253.5,19.8z"/>
48
- <path class="st0" d="M274.9,0h3.1v13c1.6-2.6,4.3-3.4,6.4-3.4c4.3,0,7.3,2.8,7.3,8.3v11.3h-3.2V18.4c0-4.1-2.1-5.8-4.9-5.8
49
- c-3,0-5.4,2-5.4,5.9v10.8h-3.2L274.9,0L274.9,0z"/>
50
- <path class="st0" d="M296.4,19.7v-0.4c0-5.6,3.6-9.7,9-9.7s8.9,4.4,8.2,11h-13.9c0.4,3.6,2.8,6.1,6.6,6.1c2,0,3.6-0.5,4.7-1.5
51
- l1.8,2c-1.5,1.6-3.9,2.5-6.7,2.5C300.3,29.6,296.4,25.6,296.4,19.7L296.4,19.7z M310.5,17.9c0-3.5-2.1-5.6-5-5.6
52
- c-3.2,0-5.3,2.2-5.8,5.6H310.5L310.5,17.9z"/>
53
- <path class="st0" d="M317.8,10h3.2V13c0.9-2.4,3-3.2,5.3-3.2h1.6v3.2H326c-3.1,0-5,1.5-5,4.7v11.4h-3.2L317.8,10L317.8,10z"/>
54
- <path class="st0" d="M341.5,1.2h8.7c5.6,0,9.4,3.1,9.4,8.4s-3.8,8.4-9.4,8.4h-5.3v11.2h-3.4V1.2z M350.3,15.2
55
- c3.5,0,5.8-2.2,5.8-5.5s-2.4-5.5-5.8-5.5h-5.4v11H350.3z"/>
56
- <path class="st0" d="M363.5,10h3.2V13c0.9-2.4,3-3.2,5.3-3.2h1.6v3.2h-1.9c-3.1,0-5,1.5-5,4.7v11.4h-3.2L363.5,10L363.5,10z"/>
57
- <path class="st0" d="M379,12.8h-3.7V10h6.9v19.2H379V12.8z M378.9,1.1h3.5v4.6h-3.5V1.1z"/>
58
- <path class="st0" d="M388.6,10h3.1v3c1.5-2.6,4-3.4,6.1-3.4c2.8,0,5,1.2,6.1,3.8c1.6-2.9,4.5-3.8,6.6-3.8c4.2,0,7.1,2.7,7.1,8.2
59
- v11.4h-3.2v-11c0-4-1.8-5.6-4.6-5.6s-5,2-5,5.6v11h-3.2v-11c0-4-1.8-5.6-4.6-5.6s-5,2-5,5.6v11h-3.2L388.6,10L388.6,10z"/>
60
- <path class="st0" d="M422.3,19.7v-0.4c0-5.6,3.6-9.7,9-9.7s8.9,4.4,8.2,11h-13.9c0.4,3.6,2.8,6.1,6.6,6.1c2,0,3.6-0.5,4.7-1.5
61
- l1.8,2c-1.5,1.6-3.9,2.5-6.7,2.5C426.2,29.6,422.3,25.6,422.3,19.7L422.3,19.7z M436.4,17.9c0-3.5-2.1-5.6-5-5.6
62
- c-3.2,0-5.3,2.2-5.8,5.6H436.4L436.4,17.9z"/>
63
- </g>
64
- </svg>
1
+ <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 439.57 36.19"><defs><style>.cls-1{fill:#30ba78;}.cls-2{fill:#efefef;}</style></defs><g id="Layer_1-2"><g id="Layer_1-3"><path class="cls-1" d="M67.08,11.32c-.45-.46-1.18-.46-1.63,0-.5.5-.44,1.37.18,1.78.38.25.89.25,1.27,0,.62-.41.68-1.28.18-1.78M65.59,7.4c-3.08-.72-5.85,2.04-5.12,5.12.37,1.57,1.61,2.81,3.18,3.18,3.08.72,5.85-2.05,5.12-5.12-.37-1.57-1.61-2.81-3.18-3.18M45.26,24.73c-2.01-.74-2.78-.59-5.35-.56-1.78.02-1.84-.04-3.87-.04-.63,0-.86,3,1.41,3.63.99.27,2.07.45,2.81,1.21.33.34.52.85-.25.85h-5.63c-.99,0-1.92.02-2.67-.61-1.14-.96-1.67-2.28-2.24-3.6-.59-1.36-1.23-2.71-1.97-3.99-1.49-2.56-3.45-4.87-6.09-6.28-3.29-1.77-8.88-2.64-13.31.76-4.66,3.58-3.66,10.29.42,13.57,1.61,1.3,3.71,1.84,5.78,1.72,4.03-.24,7.01-3.21,6.27-6.87-.25-1.23-.96-2.38-2.04-3.02-.77-.45-1.67-.61-2.56-.61-.95,0-1.97.2-2.65.86-.81.78-.94,2.17-.29,3.1.36.51.94.94.84,1.61-.07.45-.44.79-.89.89-.76.17-1.45-.26-1.96-.79-1.31-1.35-1.72-3.5-1-5.24.94-2.28,3.57-3.53,6.03-3.45,3.18.11,6.17,2.2,7.47,5.1,1.3,2.9.91,6.46-.88,9.08-3.99,5.83-13.84,5.14-18.41.22C1.36,29.19-.2,26.19.02,20.62c.15-3.94,2.43-7.82,5.32-10.55C10.06,5.63,16.28,2.59,22.6,1.28c3.84-.79,7.81-.98,11.71-.59,3.44.34,6.86.97,10.16,2,1.64.51,3.25,1.12,4.81,1.83,1.38.63,3.18,1.32,4.25,2.41,0-1.98-.08-4.15-.08-5.66,0-.58.61-.97,1.13-.72,2.24,1.04,7.53,3.54,11.07,5.16,4.74,2.16,5.07,7.27,5.24,11.79,0,.1,0,.21-.04.29-.15.31-.95.23-1.24.23-.57,0-1.42,0-1.99.03-1.13.05-2.23.03-3.36-.03-2.09-.1-4.11-1.03-5.47-2.17-.13-.11-.57-.24-.78-.02-.21.22-.14.57-.02.68.78.78,1.62,1.29,2.6,1.8,1.24.64,2.6.8,3.97.88,1.47.09,2.95.07,4.42-.09,1.23-.12,1.54-.21.33.69-1.06.79-2.3,1.36-3.55,1.78-1.79.61-3.69.91-5.58.96-1.15.03-2.29-.03-3.43-.18-.59-.07-1.17-.18-1.76-.24-.48-.05-.98-.14-1.45-.04-.43.09-.83.33-1.11.68-.37.49-.5,1.83-.29,2.41.42,1.13,1.34,1.78,2.3,2.36,1.05.62,2.43.84,2.7,2.03.06.25-2.18.26-2.43.25h-2.97s-1.62.04-2.24-.19c-.02,0-.04-.02-.06-.02-.34-.18-.49-.64-.61-.99-.17-.49-.46-.98-.81-1.48-.67-.96-1.7-2-2.78-2.4M67.76,11.55c0,1.74-1.41,3.15-3.15,3.15s-3.15-1.41-3.15-3.15,1.41-3.15,3.15-3.15,3.15,1.41,3.15,3.15"/></g><path class="cls-2" d="M80.39,25.52l3.04-3.04c2.16,2.2,4.16,3.12,6.52,3.12,3.16,0,5.04-1.6,5.04-3.96,0-6.44-13.96-2.8-13.96-12.48,0-5.2,3.88-8.52,9.76-8.52,3.6,0,6.6,1.4,8.48,3.52l-3.12,3.12c-1.6-1.64-3.24-2.48-5.36-2.48-2.96,0-4.88,1.52-4.88,3.88,0,6.08,14.08,2.12,14.08,12.24,0,5.36-4.12,8.84-10.2,8.84-4.2,0-7.24-1.68-9.4-4.24Z"/><path class="cls-2" d="M104.47,19.52V1.2h4.92v17.92c0,4.08,2.36,6.08,5.96,6.08s5.92-2,5.92-6.08V1.2h4.92v18.32c0,6.84-4.32,10.24-10.84,10.24s-10.88-3.4-10.88-10.24Z"/><path class="cls-2" d="M130.67,25.52l3.04-3.04c2.16,2.2,4.16,3.12,6.52,3.12,3.16,0,5.04-1.6,5.04-3.96,0-6.44-13.96-2.8-13.96-12.48,0-5.2,3.88-8.52,9.76-8.52,3.6,0,6.6,1.4,8.48,3.52l-3.12,3.12c-1.6-1.64-3.24-2.48-5.36-2.48-2.96,0-4.88,1.52-4.88,3.88,0,6.08,14.08,2.12,14.08,12.24,0,5.36-4.12,8.84-10.2,8.84-4.2,0-7.24-1.68-9.4-4.24Z"/><path class="cls-2" d="M154.43,24.52V5.88c0-2.72,1.96-4.68,4.68-4.68h13.6v4.48h-11.96c-.84,0-1.48.64-1.48,1.44v5.88h12.6v4.28h-12.6v6c0,.8.64,1.44,1.48,1.44h11.96v4.48h-13.6c-2.72,0-4.68-1.96-4.68-4.68Z"/><path class="cls-2" d="M187.51,1.2h9c5.64,0,9.4,2.88,9.4,8.36,0,4.72-2.52,7.32-6.52,8.12l7.36,11.52h-3.96l-7-11.24h-4.88v11.24h-3.4V1.2ZM196.35,15.04c3.64,0,6.08-1.68,6.08-5.4,0-3.52-2.44-5.52-6.08-5.52h-5.44v10.92h5.44Z"/><path class="cls-2" d="M222.91,27.28c-1.08,1.52-2.96,2.32-5.68,2.32-4.56,0-7.4-2.28-7.4-5.68s2.8-5.96,7.76-5.96c2.08,0,3.72.48,4.92,1.32v-2.52c0-2.88-1.48-4.28-4.48-4.28-2,0-4.36.76-6.04,2.28l-1.52-2.2c1.72-1.96,4.72-3,7.68-3,4.48,0,7.56,2.4,7.56,7.16v6.16c0,2.12,0,4.2.12,6.32h-2.92v-1.92ZM217.83,27.16c2.88,0,4.68-1.28,4.68-3.32s-1.76-3.28-4.68-3.28-4.76,1.28-4.76,3.28,1.88,3.32,4.76,3.32Z"/><path class="cls-2" d="M231.99,9.96h3.12v3.04c1.56-2.64,4.32-3.44,6.36-3.44,4.32,0,7.28,2.8,7.28,8.32v11.32h-3.2v-10.84c0-4.12-2.08-5.84-4.88-5.84-2.96,0-5.44,2.04-5.44,5.88v10.8h-3.24V9.96Z"/><path class="cls-2" d="M253.51,19.8v-.48c0-5.76,4.2-9.76,9.88-9.76,2.76,0,5.2,1.08,6.76,2.96l-2,2c-1.2-1.28-2.8-1.96-4.76-1.96-3.84,0-6.68,2.68-6.68,6.76v.48c0,4.08,2.84,6.8,6.72,6.8,1.92,0,3.52-.6,4.84-1.92l1.96,1.96c-1.6,1.88-4.08,2.96-6.84,2.96-5.72,0-9.88-4.04-9.88-9.8Z"/><path class="cls-2" d="M274.87,0h3.12v13c1.56-2.64,4.32-3.44,6.36-3.44,4.32,0,7.28,2.8,7.28,8.32v11.32h-3.2v-10.84c0-4.12-2.08-5.84-4.88-5.84-2.96,0-5.44,2.04-5.44,5.88v10.8h-3.24V0Z"/><path class="cls-2" d="M296.39,19.68v-.4c0-5.56,3.6-9.72,9-9.72s8.92,4.36,8.16,11h-13.92c.36,3.56,2.8,6.08,6.56,6.08,2,0,3.56-.48,4.72-1.52l1.84,2c-1.48,1.6-3.92,2.48-6.72,2.48-5.72,0-9.64-4.04-9.64-9.92ZM310.47,17.92c-.04-3.52-2.08-5.56-5.04-5.56-3.24,0-5.32,2.2-5.76,5.56h10.8Z"/><path class="cls-2" d="M317.75,9.96h3.16v3.08c.92-2.44,2.96-3.16,5.32-3.16h1.64v3.2h-1.92c-3.12,0-4.96,1.52-4.96,4.72v11.4h-3.24V9.96Z"/><path class="cls-2" d="M341.47,1.2h8.68c5.6,0,9.36,3.12,9.36,8.44s-3.76,8.4-9.36,8.4h-5.28v11.16h-3.4V1.2ZM350.31,15.16c3.48,0,5.84-2.16,5.84-5.52s-2.36-5.48-5.84-5.48h-5.44v11h5.44Z"/><path class="cls-2" d="M363.47,9.96h3.16v3.08c.92-2.44,2.96-3.16,5.32-3.16h1.64v3.2h-1.92c-3.12,0-4.96,1.52-4.96,4.72v11.4h-3.24V9.96Z"/><path class="cls-2" d="M379.03,12.76h-3.72v-2.8h6.92v19.24h-3.2V12.76ZM378.91,1.08h3.52v4.64h-3.52V1.08Z"/><path class="cls-2" d="M388.59,9.96h3.12v3c1.48-2.56,3.96-3.4,6.08-3.4,2.8,0,4.96,1.24,6.08,3.76,1.6-2.88,4.48-3.76,6.6-3.76,4.2,0,7.08,2.68,7.08,8.2v11.44h-3.2v-11.04c0-3.96-1.84-5.64-4.64-5.64s-5,2-5,5.64v11.04h-3.24v-11.04c0-3.96-1.84-5.64-4.6-5.64s-5.04,2-5.04,5.64v11.04h-3.24V9.96Z"/><path class="cls-2" d="M422.31,19.68v-.4c0-5.56,3.6-9.72,9-9.72s8.92,4.36,8.16,11h-13.92c.36,3.56,2.8,6.08,6.56,6.08,2,0,3.56-.48,4.72-1.52l1.84,2c-1.48,1.6-3.92,2.48-6.72,2.48-5.72,0-9.64-4.04-9.64-9.92ZM436.39,17.92c-.04-3.52-2.08-5.56-5.04-5.56-3.24,0-5.32,2.2-5.76,5.56h10.8Z"/></g></svg>
@@ -125,6 +125,7 @@ generic:
125
125
  enable: Enable
126
126
  disable: Disable
127
127
  experimental: Experimental
128
+ primeOnly: Prime Only
128
129
 
129
130
  deprecated: Deprecated
130
131
  upgradeable: Upgradeable
@@ -1125,6 +1126,7 @@ catalog:
1125
1126
  home: Homepage
1126
1127
  repository: Repository Page
1127
1128
  maintainers: Maintainers
1129
+ maintainerContactTooltip: Contact {maintainer}
1128
1130
  related: Related
1129
1131
  chartUrls: Chart
1130
1132
  keywords: Keywords
@@ -2343,6 +2345,7 @@ cluster:
2343
2345
  placeholder: Search for a member to provide cluster access
2344
2346
  searchPlaceholder: Start typing to search
2345
2347
  noResults: No results found
2348
+ minCharacters: Type at least {count} characters to search
2346
2349
  privateRegistry:
2347
2350
  header: Registry for Rancher System Container Images
2348
2351
  label: Enable cluster scoped container registry for Rancher system container images
@@ -5248,6 +5251,7 @@ inactivity:
5248
5251
  # Rancher Extensions
5249
5252
  plugins:
5250
5253
  altIcon: Icon for {extension} extension card
5254
+ incompatiblePrimeOnly: "The latest version of this extension ({ version }) needs Rancher Prime in order to be installed."
5251
5255
  incompatibleRancherVersion: "The latest version of this extension ({ version }) is not compatible with the current Rancher version ({ required })."
5252
5256
  incompatibleKubeVersion: "The latest version of this extension ({ version }) is not compatible with the current Kube version ({ required })."
5253
5257
  incompatibleUiExtensionsApiVersionMissing: 'The latest version of this extension ({ version }) is missing the mandatory annotation catalog.cattle.io/ui-extensions-version from Rancher 2.10 and onwards.'
@@ -5257,6 +5261,8 @@ plugins:
5257
5261
  closePluginPanel: Close plugin description panel
5258
5262
  viewVersionDetails: View extension {name} version {version} details/Readme
5259
5263
  labels:
5264
+ isDeveloper: Developer Load
5265
+ primeOnly: Prime only
5260
5266
  builtin: Built-In
5261
5267
  experimental: Experimental
5262
5268
  third-party: Third-Party
@@ -5279,6 +5285,7 @@ plugins:
5279
5285
  title: Error loading extension
5280
5286
  message: Could not load extension code
5281
5287
  generic: Extension error
5288
+ primeOnly: Unable to load Rancher Prime Extension in Rancher Community
5282
5289
  apiAnnotationMissing: 'Unable to load Extension. The version installed is not compatible with the current Extensions API Version (Extension is missing the annotation catalog.cattle.io/ui-extensions-version which implies incompatibility with Rancher 2.10 and onwards)'
5283
5290
  api: Unable to load Extension. The version installed is not compatible with the current Extensions API version
5284
5291
  host: Unable to load Extension. The version installed is not compatible with this application host
@@ -5303,6 +5310,7 @@ plugins:
5303
5310
  detail: Detail
5304
5311
  versions: Versions
5305
5312
  versionError: Could not load version information
5313
+ requiresRancherPrime: "Requires Rancher Prime"
5306
5314
  requiresRancherVersion: "Requires Rancher {required}"
5307
5315
  requiresKubeVersion: "Requires Kube version {required}"
5308
5316
  requiresExtensionApiVersionMissing: 'Missing the annotation catalog.cattle.io/ui-extensions-version which implies incompatibility with Rancher 2.10 and onwards'
@@ -5322,7 +5330,7 @@ plugins:
5322
5330
  warnNoAuth: This version of the extension will be loaded before authentication and will have access to the login process.
5323
5331
  manageCatalog:
5324
5332
  label: Manage Extension Catalogs
5325
- title: Extension
5333
+ title: Extensions
5326
5334
  subtitle: Catalogs
5327
5335
  imageLoad:
5328
5336
  load: Import Extension Catalog
@@ -34,8 +34,16 @@ export default {
34
34
  display: flex;
35
35
  font-size: 16px;
36
36
  margin: 10px 0 20px 0;
37
+ padding: 0 4px 2px 0;
37
38
  outline: 0;
38
39
  width: fit-content;
40
+ border-bottom: 2px solid transparent;
41
+
42
+ &:hover {
43
+ text-decoration: none;
44
+ border-bottom: 2px solid;
45
+ border-bottom-color: inherit;
46
+ }
39
47
 
40
48
  &:focus-visible {
41
49
  @include focus-outline;
@@ -1,8 +1,6 @@
1
1
  <script>
2
2
  import Closeable from '@shell/mixins/closeable';
3
3
  import BrandImage from '@shell/components/BrandImage';
4
- import { MANAGEMENT } from '@shell/config/types';
5
- import { SETTING } from '@shell/config/settings';
6
4
  import { getBrandMeta } from '@shell/utils/brand';
7
5
 
8
6
  export default {
@@ -21,9 +19,7 @@ export default {
21
19
  },
22
20
 
23
21
  data() {
24
- const globalSettings = this.$store.getters['management/all'](MANAGEMENT.SETTING);
25
- const setting = globalSettings?.find((gs) => gs.id === SETTING.BRAND);
26
- const brandMeta = getBrandMeta(setting?.value);
22
+ const brandMeta = getBrandMeta(this.$store.getters['management/brand']);
27
23
  const banner = brandMeta?.banner || {};
28
24
  const align = banner.textAlign || 'center';
29
25
  const bannerClass = banner.bannerClass || '';
@@ -36,9 +36,9 @@ export default {
36
36
  };
37
37
  },
38
38
  computed: {
39
- ...mapGetters({ theme: 'prefs/theme' }),
39
+ ...mapGetters({ theme: 'prefs/theme', brand: 'management/brand' }),
40
40
 
41
- brand() {
41
+ brandBase() {
42
42
  const setting = this.managementSettings.filter((setting) => setting.id === SETTING.BRAND)[0] || {};
43
43
 
44
44
  return setting.value;
@@ -78,19 +78,30 @@ export default {
78
78
  }
79
79
  },
80
80
 
81
+ isDark() {
82
+ return this.theme === 'dark';
83
+ },
84
+
81
85
  pathToBrandedImage() {
82
86
  if (this.fileName === 'rancher-logo.svg' || this.supportCustomLogo) {
83
- if (this.theme === 'dark' && this.uiLogoDark) {
87
+ if (this.isDark && this.uiLogoDark) {
84
88
  return this.uiLogoDark;
85
89
  }
86
90
 
87
91
  if (this.uiLogoLight) {
88
92
  return this.uiLogoLight;
89
93
  }
94
+
95
+ // csp, rgs, and federal map to SUSE, but have their own custom logos
96
+ if (this.brandBase !== this.brand) {
97
+ try {
98
+ return require(`~shell/assets/brand/${ this.brandBase }/${ this.isDark ? 'dark/' : '' }${ this.fileName }`);
99
+ } catch { }
100
+ }
90
101
  }
91
102
 
92
103
  if (this.fileName === 'banner.svg') {
93
- if (this.theme === 'dark' && this.uiBannerDark) {
104
+ if (this.isDark && this.uiBannerDark) {
94
105
  return this.uiBannerDark;
95
106
  }
96
107
 
@@ -100,7 +111,7 @@ export default {
100
111
  }
101
112
 
102
113
  if (this.fileName === 'login-landscape.svg') {
103
- if (this.theme === 'dark' && this.uiLoginBackgroundDark) {
114
+ if (this.isDark && this.uiLoginBackgroundDark) {
104
115
  return this.uiLoginBackgroundDark;
105
116
  }
106
117
 
@@ -112,7 +123,7 @@ export default {
112
123
  if (!this.brand) {
113
124
  return this.defaultPathToBrandedImage;
114
125
  } else {
115
- if (this.theme === 'dark' || this.dark) {
126
+ if (this.isDark || this.dark) {
116
127
  try {
117
128
  return require(`~shell/assets/brand/${ this.brand }/dark/${ this.fileName }`);
118
129
  } catch {}
@@ -268,7 +268,7 @@ const handleBlur = (field: CronField) => {
268
268
  </template>
269
269
 
270
270
  <style scoped lang="scss">
271
- $input-max-width: 110px;
271
+ $input-max-width: 120px;
272
272
 
273
273
  .cron-row {
274
274
  display: flex;
@@ -207,7 +207,7 @@ onBeforeUnmount(() => {
207
207
 
208
208
  .custom-cron-editor {
209
209
  margin: 64px auto;
210
- max-width: 600px;
210
+ max-width: 660px;
211
211
  }
212
212
 
213
213
  .cron-info {
@@ -25,6 +25,7 @@ const i18n = useI18n(store);
25
25
  :real-mode="_VIEW"
26
26
  :initial-value="props.resource"
27
27
  :use-tabbed-hash="false /* Have to disable hashing on child components or it modifies the url and closes the drawer */"
28
+ :default-tab="props.defaultTab"
28
29
  as="config"
29
30
  />
30
31
  </div>
@@ -79,6 +79,7 @@ const canEdit = computed(() => {
79
79
  <ConfigTab
80
80
  v-if="configTabProps"
81
81
  v-bind="configTabProps"
82
+ :default-tab="props.defaultTab"
82
83
  />
83
84
  <YamlTab
84
85
  v-if="yamlTabProps"
@@ -7,10 +7,11 @@ export interface ConfigProps {
7
7
  resource: any;
8
8
  component: any;
9
9
  resourceType: string;
10
+ defaultTab?: string;
10
11
  }
11
12
 
12
13
  export interface ResourceDetailDrawerProps {
13
14
  resource: any;
14
-
15
+ defaultTab?: string;
15
16
  onClose?: () => void;
16
17
  }
@@ -0,0 +1,159 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import Questions from '@shell/components/Questions/index.vue';
3
+
4
+ const mockT = jest.fn((key) => key);
5
+ const mockWithFallback = jest.fn((key, args, fallback) => fallback || key);
6
+
7
+ const defaultMocks = {
8
+ $fetchState: { pending: false },
9
+ $store: {
10
+ getters: {
11
+ 'i18n/t': mockT,
12
+ 'i18n/withFallback': mockWithFallback
13
+ }
14
+ }
15
+ };
16
+
17
+ const defaultProps = {
18
+ source: { questions: { questions: [] } },
19
+ value: {},
20
+ targetNamespace: 'default',
21
+ mode: 'edit',
22
+ };
23
+
24
+ describe('component: Questions', () => {
25
+ describe('computed: groups', () => {
26
+ it('should group questions with the same group into a single group', () => {
27
+ const questions = [
28
+ { variable: 'q1', group: 'Group 1' },
29
+ { variable: 'q2', group: 'Group 1' },
30
+ ];
31
+ const wrapper = shallowMount(Questions, {
32
+ props: { ...defaultProps, source: { questions: { questions } } },
33
+ global: { mocks: defaultMocks },
34
+ });
35
+
36
+ const groups = wrapper.vm.groups;
37
+
38
+ expect(groups).toHaveLength(1);
39
+ expect(groups[0].name).toBe('Group 1');
40
+ expect(groups[0].questions).toHaveLength(2);
41
+ });
42
+
43
+ it('should place questions without a group into a default group', () => {
44
+ const questions = [
45
+ { variable: 'q1' },
46
+ { variable: 'q2' },
47
+ ];
48
+ const wrapper = shallowMount(Questions, {
49
+ props: { ...defaultProps, source: { questions: { questions } } },
50
+ global: { mocks: defaultMocks },
51
+ });
52
+
53
+ const groups = wrapper.vm.groups;
54
+
55
+ expect(groups).toHaveLength(1);
56
+ expect(groups[0].name).toBe('Questions'); // Default group name
57
+ expect(groups[0].questions).toHaveLength(2);
58
+ });
59
+
60
+ it('should create multiple groups for questions with different groups', () => {
61
+ const questions = [
62
+ { variable: 'q1', group: 'Group 1' },
63
+ { variable: 'q2', group: 'Group 2' },
64
+ ];
65
+ const wrapper = shallowMount(Questions, {
66
+ props: { ...defaultProps, source: { questions: { questions } } },
67
+ global: { mocks: defaultMocks },
68
+ });
69
+
70
+ const groups = wrapper.vm.groups;
71
+
72
+ expect(groups).toHaveLength(2);
73
+ });
74
+
75
+ it('should correctly group a mix of grouped and ungrouped questions', () => {
76
+ const questions = [
77
+ { variable: 'q1', group: 'Group 1' },
78
+ { variable: 'q2' },
79
+ { variable: 'q3', group: 'Group 1' },
80
+ ];
81
+ const wrapper = shallowMount(Questions, {
82
+ props: { ...defaultProps, source: { questions: { questions } } },
83
+ global: { mocks: defaultMocks },
84
+ });
85
+
86
+ const groups = wrapper.vm.groups;
87
+
88
+ expect(groups).toHaveLength(2); // 'Group 1' and 'Questions'
89
+ const group1 = groups.find((g: any) => g.name === 'Group 1');
90
+ const defaultGroup = groups.find((g: any) => g.name === 'Questions');
91
+
92
+ expect(group1.questions).toHaveLength(2);
93
+ expect(defaultGroup.questions).toHaveLength(1);
94
+ });
95
+ });
96
+
97
+ describe('computed: asTabs', () => {
98
+ it('should be true by default', () => {
99
+ const wrapper = shallowMount(Questions, {
100
+ props: defaultProps,
101
+ global: { mocks: defaultMocks },
102
+ });
103
+
104
+ expect(wrapper.vm.asTabs).toBe(true);
105
+ });
106
+
107
+ it('should be true when tabbed is true', () => {
108
+ const wrapper = shallowMount(Questions, {
109
+ props: { ...defaultProps, tabbed: true },
110
+ global: { mocks: defaultMocks },
111
+ });
112
+
113
+ expect(wrapper.vm.asTabs).toBe(true);
114
+ });
115
+
116
+ it('should be false when tabbed is false', () => {
117
+ const wrapper = shallowMount(Questions, {
118
+ props: { ...defaultProps, tabbed: false },
119
+ global: { mocks: defaultMocks },
120
+ });
121
+
122
+ expect(wrapper.vm.asTabs).toBe(false);
123
+ });
124
+
125
+ it('should be false when tabbed is "never"', () => {
126
+ const wrapper = shallowMount(Questions, {
127
+ props: { ...defaultProps, tabbed: 'never' },
128
+ global: { mocks: defaultMocks },
129
+ });
130
+
131
+ expect(wrapper.vm.asTabs).toBe(false);
132
+ });
133
+
134
+ describe('when tabbed is "multiple"', () => {
135
+ it('should be true if there are groups', () => {
136
+ const questions = [{ variable: 'q1', group: 'Group 1' }];
137
+ const wrapper = shallowMount(Questions, {
138
+ props: {
139
+ ...defaultProps, source: { questions: { questions } }, tabbed: 'multiple'
140
+ },
141
+ global: { mocks: defaultMocks },
142
+ });
143
+
144
+ expect(wrapper.vm.groups).toHaveLength(1);
145
+ expect(wrapper.vm.asTabs).toBe(true);
146
+ });
147
+
148
+ it('should be false if there are no groups', () => {
149
+ const wrapper = shallowMount(Questions, {
150
+ props: { ...defaultProps, tabbed: 'multiple' },
151
+ global: { mocks: defaultMocks },
152
+ });
153
+
154
+ expect(wrapper.vm.groups).toHaveLength(0);
155
+ expect(wrapper.vm.asTabs).toBe(false);
156
+ });
157
+ });
158
+ });
159
+ });
@@ -8,7 +8,7 @@ export type Annotation = Row;
8
8
  export interface AnnotationsProps {
9
9
  annotations: Annotation[];
10
10
 
11
- onShowConfiguration?: (returnFocusSelector: string) => void;
11
+ onShowConfiguration?: (returnFocusSelector: string, defaultTab: string) => void;
12
12
  }
13
13
 
14
14
  </script>
@@ -26,6 +26,6 @@ const i18n = useI18n(store);
26
26
  :rows="annotations"
27
27
  type="active"
28
28
 
29
- @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector)"
29
+ @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector, 'labels-and-annotations')"
30
30
  />
31
31
  </template>
@@ -8,7 +8,7 @@ export type Label = Row;
8
8
  export interface LabelsProps {
9
9
  labels: Label[];
10
10
 
11
- onShowConfiguration?: (returnFocusSelector: string) => void;
11
+ onShowConfiguration?: (returnFocusSelector: string, defaultTab: string) => void;
12
12
  }
13
13
 
14
14
  </script>
@@ -27,6 +27,6 @@ const i18n = useI18n(store);
27
27
  :propertyName="i18n.t('component.resource.detail.metadata.labels.title')"
28
28
  :rows="labels"
29
29
  type="active"
30
- @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector)"
30
+ @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector, 'labels-and-annotations')"
31
31
  />
32
32
  </template>
@@ -48,7 +48,7 @@ const showBothEmpty = computed(() => labels.length === 0 && annotations.length =
48
48
  type="active"
49
49
  :rows="[]"
50
50
  :propertyName="i18n.t('component.resource.detail.metadata.labelsAndAnnotations')"
51
- @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector)"
51
+ @show-configuration="(returnFocusSelector: string, defaultTab: string) => emit('show-configuration', returnFocusSelector, defaultTab)"
52
52
  />
53
53
  </div>
54
54
  <!-- I'm not using v-else here so I can maintain the spacing correctly with the other columns in other rows. -->
@@ -58,7 +58,7 @@ const showBothEmpty = computed(() => labels.length === 0 && annotations.length =
58
58
  >
59
59
  <Labels
60
60
  :labels="labels"
61
- @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector)"
61
+ @show-configuration="(returnFocusSelector: string, defaultTab: string) => emit('show-configuration', returnFocusSelector, defaultTab)"
62
62
  />
63
63
  </div>
64
64
  <div
@@ -67,7 +67,7 @@ const showBothEmpty = computed(() => labels.length === 0 && annotations.length =
67
67
  >
68
68
  <Annotations
69
69
  :annotations="annotations"
70
- @show-configuration="(returnFocusSelector: string) => emit('show-configuration', returnFocusSelector)"
70
+ @show-configuration="(returnFocusSelector: string, defaultTab: string) => emit('show-configuration', returnFocusSelector, defaultTab)"
71
71
  />
72
72
  </div>
73
73
  </SpacedRow>
@@ -46,12 +46,12 @@ export const useResourceDetailBannerProps = (resource: any): Ref<BannerProps | u
46
46
  };
47
47
 
48
48
  export const useOnShowConfiguration = (resource: any) => {
49
- return (returnFocusSelector?: string) => {
49
+ return (returnFocusSelector?: string, defaultTab?: string) => {
50
50
  const resourceValue = toValue(resource);
51
51
  // Because extensions can make a copy of the resource-class it's possible that an extension will have a resource-class which predates the inclusion of showConfiguration
52
52
  // to still the rest of shell to consume
53
53
  const showConfiguration = resourceValue.showConfiguration ? resourceValue.showConfiguration.bind(resourceValue) : ResourceClass.prototype.showConfiguration.bind(resourceValue);
54
54
 
55
- showConfiguration(returnFocusSelector);
55
+ showConfiguration(returnFocusSelector, defaultTab);
56
56
  };
57
57
  };
@@ -0,0 +1,86 @@
1
+ import { mount, VueWrapper } from '@vue/test-utils';
2
+ import Tabbed from '@shell/components/Tabbed/index.vue';
3
+ import Tab from '@shell/components/Tabbed/Tab.vue';
4
+
5
+ jest.mock('@shell/components/form/ResourceTabs/composable', () => ({ useTabCountWatcher: () => ({}) }));
6
+
7
+ const mockT = (key: string) => key;
8
+
9
+ const defaultGlobalMountOptions = {
10
+ components: { Tab },
11
+ mocks: {
12
+ $router: {
13
+ replace: jest.fn(),
14
+ currentRoute: { _value: { hash: '' } }
15
+ },
16
+ $route: { hash: '' },
17
+ t: mockT,
18
+ store: { getters: { 'i18n/t': mockT } }
19
+ }
20
+ };
21
+
22
+ describe('component: Tabbed', () => {
23
+ const findTabNav = (wrapper: VueWrapper<any>) => wrapper.find('[data-testid="tabbed-block"]');
24
+
25
+ it('should display tab navigation for a single tab when hideSingleTab is false (default)', async() => {
26
+ const wrapper = mount(Tabbed, {
27
+ slots: { default: { components: { Tab }, template: '<Tab name="tab1" label="Tab 1" />' } },
28
+ global: { ...defaultGlobalMountOptions },
29
+ });
30
+
31
+ await wrapper.vm.$nextTick();
32
+
33
+ expect(findTabNav(wrapper).exists()).toBe(true);
34
+ });
35
+
36
+ it('should display tab navigation for multiple tabs when hideSingleTab is false (default)', async() => {
37
+ const wrapper = mount(Tabbed, {
38
+ slots: {
39
+ default: {
40
+ components: { Tab },
41
+ template: `
42
+ <Tab name="tab1" label="Tab 1" />
43
+ <Tab name="tab2" label="Tab 2" />
44
+ `,
45
+ },
46
+ },
47
+ global: { ...defaultGlobalMountOptions },
48
+ });
49
+
50
+ await wrapper.vm.$nextTick();
51
+
52
+ expect(findTabNav(wrapper).exists()).toBe(true);
53
+ });
54
+
55
+ it('should NOT display tab navigation for a single tab when hideSingleTab is true', async() => {
56
+ const wrapper = mount(Tabbed, {
57
+ props: { hideSingleTab: true },
58
+ slots: { default: { components: { Tab }, template: '<Tab name="tab1" label="Tab 1" />' } },
59
+ global: { ...defaultGlobalMountOptions },
60
+ });
61
+
62
+ await wrapper.vm.$nextTick();
63
+
64
+ expect(findTabNav(wrapper).exists()).toBe(false);
65
+ });
66
+
67
+ it('should display tab navigation for multiple tabs when hideSingleTab is true', async() => {
68
+ const wrapper = mount(Tabbed, {
69
+ props: { hideSingleTab: true },
70
+ slots: {
71
+ default: {
72
+ components: { Tab },
73
+ template: `
74
+ <Tab name="tab1" label="Tab 1" />
75
+ <Tab name="tab2" label="Tab 2" />
76
+ `,
77
+ },
78
+ },
79
+ global: { ...defaultGlobalMountOptions },
80
+ });
81
+
82
+ await wrapper.vm.$nextTick();
83
+
84
+ expect(findTabNav(wrapper).exists()).toBe(true);
85
+ });
86
+ });