@rancher/shell 3.0.12-rc.1 → 3.0.12-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/apis/impl/apis.ts +6 -0
  2. package/apis/index.ts +26 -0
  3. package/apis/intf/resources-api/cluster-api.ts +18 -0
  4. package/apis/intf/resources-api/mgmt-api.ts +15 -0
  5. package/apis/intf/resources-api/resource-base.ts +107 -0
  6. package/apis/intf/resources-api/resource-constants.ts +147 -0
  7. package/apis/intf/resources-api/resources-api.ts +143 -0
  8. package/apis/intf/resources.ts +49 -0
  9. package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
  10. package/apis/intf/shell-api/proxy.ts +216 -0
  11. package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
  12. package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
  13. package/apis/intf/shell.ts +12 -6
  14. package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
  15. package/apis/resources/index.ts +22 -0
  16. package/apis/resources/resources-api-class.ts +187 -0
  17. package/apis/shell/__tests__/proxy.test.ts +369 -0
  18. package/apis/shell/index.ts +8 -1
  19. package/apis/shell/modal.ts +4 -1
  20. package/apis/shell/notifications.ts +9 -6
  21. package/apis/shell/proxy.ts +256 -0
  22. package/apis/shell/slide-in.ts +4 -1
  23. package/apis/vue-shim.d.ts +2 -1
  24. package/assets/data/aws-regions.json +4 -0
  25. package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
  26. package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
  27. package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
  28. package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
  29. package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
  30. package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
  31. package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
  32. package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
  33. package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
  34. package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
  35. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
  36. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
  37. package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
  38. package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
  39. package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
  40. package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
  41. package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
  42. package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
  43. package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
  44. package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
  45. package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
  46. package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
  47. package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
  48. package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
  49. package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
  50. package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
  51. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
  52. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
  53. package/assets/images/providers/entraid-black.svg +4 -0
  54. package/assets/images/providers/entraid.svg +9 -0
  55. package/assets/images/vendor/entraid.svg +9 -0
  56. package/assets/styles/app.scss +0 -1
  57. package/assets/styles/base/_variables.scss +2 -0
  58. package/assets/styles/fonts/_fontstack.scss +132 -8
  59. package/assets/translations/en-us.yaml +41 -22
  60. package/assets/translations/zh-hans.yaml +4 -8
  61. package/chart/__tests__/S3.test.ts +10 -3
  62. package/chart/monitoring/index.vue +10 -1
  63. package/components/ActionDropdownShell.vue +2 -1
  64. package/components/CountBox.vue +20 -0
  65. package/components/CreateDriver.vue +0 -12
  66. package/components/CruResourceFooter.vue +9 -5
  67. package/components/DetailText.vue +12 -3
  68. package/components/ExplorerProjectsNamespaces.vue +1 -1
  69. package/components/InstallHelmCharts.vue +2 -2
  70. package/components/LandingPagePreference.vue +14 -5
  71. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
  72. package/components/Resource/Detail/Metadata/index.vue +6 -0
  73. package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
  74. package/components/Resource/Detail/SpacedRow.vue +3 -1
  75. package/components/Resource/Detail/TitleBar/index.vue +10 -11
  76. package/components/ResourceList/Masthead.vue +12 -8
  77. package/components/SelectIconGrid.vue +5 -10
  78. package/components/SingleClusterInfo.vue +1 -0
  79. package/components/SortableTable/__tests__/sorting.test.ts +126 -0
  80. package/components/SortableTable/index.vue +6 -9
  81. package/components/SortableTable/selection.js +23 -5
  82. package/components/SortableTable/sorting.js +6 -3
  83. package/components/Wizard.vue +14 -13
  84. package/components/__tests__/CountBox.test.ts +72 -0
  85. package/components/__tests__/DetailText.test.ts +113 -0
  86. package/components/fleet/FleetBundles.vue +100 -12
  87. package/components/fleet/FleetClusterTargets/index.vue +54 -15
  88. package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
  89. package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
  90. package/components/form/InputWithSelect.vue +18 -10
  91. package/components/form/KeyValue.vue +17 -1
  92. package/components/form/LabeledSelect.vue +101 -26
  93. package/components/form/NameNsDescription.vue +11 -0
  94. package/components/form/Security.vue +6 -2
  95. package/components/form/Select.vue +73 -56
  96. package/components/form/ServiceNameSelect.vue +13 -11
  97. package/components/form/WorkloadPorts.vue +2 -7
  98. package/components/form/__tests__/KeyValue.test.ts +66 -0
  99. package/components/form/__tests__/NodeScheduling.test.ts +9 -0
  100. package/components/form/__tests__/Security.test.ts +76 -0
  101. package/components/form/labeled-select-utils/useLabeledSelectPagination.ts +138 -0
  102. package/components/formatter/Autoscaler.vue +4 -4
  103. package/components/formatter/ClusterKubeVersion.vue +27 -0
  104. package/components/formatter/ClusterLink.vue +1 -7
  105. package/components/formatter/ClusterProvider.vue +6 -10
  106. package/components/formatter/FleetSummaryGraph.vue +0 -3
  107. package/components/formatter/MachineSummaryGraph.vue +1 -1
  108. package/components/formatter/PodsUsage.vue +2 -2
  109. package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
  110. package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
  111. package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
  112. package/components/nav/Group.vue +7 -6
  113. package/components/nav/Header.vue +24 -3
  114. package/components/nav/NamespaceFilter.vue +2 -2
  115. package/components/nav/NotificationCenter/Notification.vue +4 -1
  116. package/components/nav/NotificationCenter/NotificationHeader.vue +20 -8
  117. package/components/nav/NotificationCenter/__tests__/NotificationHeader.test.ts +80 -0
  118. package/components/nav/TopLevelMenu.helper.ts +15 -3
  119. package/components/nav/TopLevelMenu.vue +16 -5
  120. package/components/nav/Type.vue +8 -7
  121. package/components/nav/WindowManager/index.vue +2 -1
  122. package/components/nav/WorkspaceSwitcher.vue +13 -0
  123. package/components/nav/__tests__/Group.test.ts +67 -0
  124. package/components/nav/__tests__/Header.test.ts +235 -0
  125. package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
  126. package/components/nav/__tests__/Type.test.ts +20 -3
  127. package/components/templates/default.vue +34 -4
  128. package/components/templates/home.vue +30 -25
  129. package/components/templates/plain.vue +31 -26
  130. package/components/templates/standalone.vue +17 -0
  131. package/composables/useFormValidation.ts +93 -0
  132. package/composables/useLabeledFormElement.ts +10 -2
  133. package/composables/useLabeledSelect.ts +60 -0
  134. package/composables/useUserRetentionValidation.ts +1 -49
  135. package/composables/useVeeValidateField.test.ts +159 -0
  136. package/composables/useVeeValidateField.ts +67 -0
  137. package/config/cookies.js +0 -1
  138. package/config/labels-annotations.js +1 -0
  139. package/config/pagination-table-headers.js +18 -1
  140. package/config/product/manager.js +82 -21
  141. package/config/query-params.js +1 -0
  142. package/config/router/routes.js +6 -8
  143. package/config/table-headers.js +20 -1
  144. package/config/types.js +2 -1
  145. package/core/__tests__/plugin-products.test.ts +1505 -30
  146. package/core/plugin-products-base.ts +137 -20
  147. package/core/plugin-products-helpers.ts +5 -4
  148. package/core/plugin-products.ts +4 -0
  149. package/core/plugin-types.ts +129 -4
  150. package/core/plugin.ts +15 -7
  151. package/core/productDebugger.js +9 -4
  152. package/core/types-provisioning.ts +43 -30
  153. package/core/types.ts +58 -19
  154. package/detail/__tests__/management.cattle.io.fleetworkspace.test.ts +128 -0
  155. package/detail/__tests__/pod.test.ts +41 -0
  156. package/detail/harvesterhci.io.management.cluster.vue +6 -2
  157. package/detail/management.cattle.io.fleetworkspace.vue +49 -0
  158. package/detail/pod.vue +1 -1
  159. package/detail/provisioning.cattle.io.cluster.vue +4 -10
  160. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +9 -0
  161. package/edit/__tests__/kontainerDriver.test.ts +0 -13
  162. package/edit/__tests__/nodeDriver.test.ts +5 -11
  163. package/edit/__tests__/resources.cattle.io.restore.test.ts +9 -0
  164. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  165. package/edit/auth/__tests__/azuread.test.ts +217 -34
  166. package/edit/auth/__tests__/oidc.test.ts +54 -0
  167. package/edit/auth/azuread.vue +123 -15
  168. package/edit/auth/oidc.vue +10 -2
  169. package/edit/kontainerDriver.vue +1 -2
  170. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
  171. package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
  172. package/edit/networking.k8s.io.ingress/index.vue +75 -20
  173. package/edit/nodeDriver.vue +0 -2
  174. package/edit/provisioning.cattle.io.cluster/AgentEnv.vue +1 -0
  175. package/edit/provisioning.cattle.io.cluster/__tests__/AgentEnv.test.ts +25 -0
  176. package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
  177. package/edit/provisioning.cattle.io.cluster/index.vue +81 -106
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -4
  179. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  180. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
  181. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
  182. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
  183. package/edit/secret/__tests__/ssh.test.ts +5 -6
  184. package/edit/secret/basic.vue +31 -0
  185. package/edit/secret/index.vue +68 -17
  186. package/edit/secret/registry.vue +38 -0
  187. package/edit/secret/ssh.vue +29 -0
  188. package/edit/secret/tls.vue +30 -0
  189. package/edit/service.vue +4 -4
  190. package/edit/workload/Upgrading.vue +3 -3
  191. package/edit/workload/__tests__/Upgrading.test.ts +6 -9
  192. package/edit/workload/mixins/workload.js +2 -1
  193. package/initialize/App.vue +29 -2
  194. package/initialize/install-plugins.js +0 -2
  195. package/list/__tests__/management.cattle.io.feature.test.ts +105 -0
  196. package/list/catalog.cattle.io.app.vue +25 -5
  197. package/list/fleet.cattle.io.bundle.vue +7 -104
  198. package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
  199. package/list/management.cattle.io.feature.vue +1 -1
  200. package/list/management.cattle.io.fleetworkspace.vue +8 -0
  201. package/list/provisioning.cattle.io.cluster.vue +262 -180
  202. package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
  203. package/machine-config/amazonec2.vue +1 -0
  204. package/mixins/__tests__/chart.test.ts +112 -0
  205. package/mixins/brand.js +2 -1
  206. package/mixins/chart.js +50 -15
  207. package/mixins/resource-fetch-api-pagination.js +41 -5
  208. package/models/__tests__/catalog.cattle.io.app.test.ts +15 -1
  209. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +84 -0
  210. package/models/__tests__/chart.test.ts +99 -6
  211. package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
  212. package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
  213. package/models/__tests__/management.cattle.io.feature.test.ts +131 -0
  214. package/models/__tests__/management.cattle.io.node.ts +6 -5
  215. package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
  216. package/models/__tests__/monitoring.coreos.com.alertmanagerconfig.test.ts +98 -0
  217. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
  218. package/models/base-cluster.x-k8s.io.js +26 -0
  219. package/models/catalog.cattle.io.app.js +21 -17
  220. package/models/catalog.cattle.io.clusterrepo.js +39 -11
  221. package/models/chart.js +33 -19
  222. package/models/cluster.js +1 -1
  223. package/models/cluster.x-k8s.io.machine.js +4 -22
  224. package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
  225. package/models/cluster.x-k8s.io.machineset.js +2 -20
  226. package/models/compliance.cattle.io.clusterscan.js +130 -2
  227. package/models/ext.cattle.io.kubeconfig.ts +4 -7
  228. package/models/fleet-application.js +4 -2
  229. package/models/fleet.cattle.io.bundle.js +1 -1
  230. package/models/kontainerdriver.js +11 -0
  231. package/models/management.cattle.io.authconfig.js +5 -1
  232. package/models/management.cattle.io.cluster.js +402 -78
  233. package/models/management.cattle.io.feature.js +3 -3
  234. package/models/management.cattle.io.kontainerdriver.js +1 -26
  235. package/models/management.cattle.io.node.js +6 -4
  236. package/models/management.cattle.io.nodepool.js +1 -1
  237. package/models/monitoring.coreos.com.alertmanagerconfig.js +31 -17
  238. package/models/networking.k8s.io.ingress.js +12 -4
  239. package/models/nodedriver.js +7 -0
  240. package/models/provisioning.cattle.io.cluster.js +47 -330
  241. package/models/rke.cattle.io.etcdsnapshot.js +1 -2
  242. package/package.json +20 -37
  243. package/pages/__tests__/readme.test.ts +49 -0
  244. package/pages/auth/setup.vue +2 -3
  245. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +265 -0
  246. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +55 -0
  247. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +53 -0
  248. package/pages/c/_cluster/apps/charts/chart.vue +275 -39
  249. package/pages/c/_cluster/apps/charts/index.vue +2 -2
  250. package/pages/c/_cluster/apps/charts/install.vue +18 -10
  251. package/pages/c/_cluster/auth/user.retention/index.vue +55 -22
  252. package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
  253. package/pages/c/_cluster/explorer/index.vue +5 -49
  254. package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
  255. package/pages/c/_cluster/istio/index.vue +21 -6
  256. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -7
  257. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +40 -2
  258. package/pages/c/_cluster/uiplugins/__tests__/PluginInfoPanel.test.ts +61 -0
  259. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +735 -13
  260. package/pages/c/_cluster/uiplugins/index.vue +226 -222
  261. package/pages/diagnostic.vue +13 -17
  262. package/pages/fail-whale.vue +18 -0
  263. package/pages/home.vue +77 -260
  264. package/pages/readme.vue +88 -0
  265. package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
  266. package/plugins/dashboard-store/actions.js +40 -18
  267. package/plugins/dashboard-store/resource-class.js +5 -2
  268. package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
  269. package/plugins/steve/steve-pagination-utils.ts +11 -3
  270. package/plugins/steve/subscribe.js +35 -5
  271. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +211 -1
  272. package/rancher-components/Form/LabeledInput/LabeledInput.vue +37 -4
  273. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -1
  274. package/rancher-components/RcButton/RcButton.test.ts +37 -1
  275. package/rancher-components/RcButton/RcButton.vue +38 -8
  276. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
  277. package/scripts/test-plugins-build.sh +5 -2
  278. package/server/server-middleware.js +2 -2
  279. package/static/humans.txt +1 -0
  280. package/static/robots.txt +34 -0
  281. package/static/welcome-cow.svg +18 -0
  282. package/store/__tests__/catalog.test.ts +276 -12
  283. package/store/__tests__/type-map.test.ts +556 -1
  284. package/store/action-menu.js +8 -3
  285. package/store/auth.js +1 -4
  286. package/store/aws.js +27 -16
  287. package/store/catalog.js +87 -11
  288. package/store/digitalocean.js +20 -38
  289. package/store/index.js +2 -0
  290. package/store/linode.js +25 -40
  291. package/store/pnap.js +1 -0
  292. package/store/type-map.js +111 -29
  293. package/tsconfig.paths.json +8 -8
  294. package/types/kube/kube-api.ts +14 -1
  295. package/types/rancher/steve.api.ts +12 -12
  296. package/types/resources/settings.d.ts +2 -1
  297. package/types/shell/index.d.ts +128 -24
  298. package/types/store/dashboard-store.types.ts +108 -11
  299. package/types/store/pagination.types.ts +6 -3
  300. package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
  301. package/utils/__tests__/async.test.ts +87 -0
  302. package/utils/__tests__/aws.test.ts +140 -0
  303. package/utils/__tests__/banners.test.ts +176 -0
  304. package/utils/__tests__/chart.test.ts +64 -1
  305. package/utils/__tests__/color.test.ts +226 -0
  306. package/utils/__tests__/duration.test.ts +140 -0
  307. package/utils/__tests__/fleet.test.ts +340 -0
  308. package/utils/__tests__/git.test.ts +270 -0
  309. package/utils/__tests__/inactivity.test.ts +316 -0
  310. package/utils/__tests__/ingress.test.ts +553 -0
  311. package/utils/__tests__/kube.test.ts +68 -0
  312. package/utils/__tests__/namespace-filter.test.ts +109 -0
  313. package/utils/__tests__/object.test.ts +77 -0
  314. package/utils/__tests__/pagination-utils.test.ts +361 -0
  315. package/utils/__tests__/parse-externalid.test.ts +137 -0
  316. package/utils/__tests__/perf-setting.utils.test.ts +98 -0
  317. package/utils/__tests__/poller-sequential.test.ts +177 -0
  318. package/utils/__tests__/poller.test.ts +170 -0
  319. package/utils/__tests__/promise.test.ts +346 -0
  320. package/utils/__tests__/settings.test.ts +140 -0
  321. package/utils/__tests__/sort-utils.test.ts +301 -0
  322. package/utils/__tests__/string-utils.test.ts +798 -0
  323. package/utils/__tests__/string.test.ts +23 -1
  324. package/utils/__tests__/style.test.ts +154 -0
  325. package/utils/__tests__/svg-filter.test.ts +184 -0
  326. package/utils/__tests__/time.test.ts +14 -1
  327. package/utils/__tests__/units.test.ts +417 -0
  328. package/utils/__tests__/url.test.ts +246 -0
  329. package/utils/__tests__/versions.test.ts +128 -0
  330. package/utils/__tests__/xccdf.test.ts +391 -0
  331. package/utils/chart.js +36 -0
  332. package/utils/fleet.ts +13 -3
  333. package/utils/gatekeeper/__tests__/util.test.ts +174 -0
  334. package/utils/gc/__tests__/gc-interval.test.ts +119 -0
  335. package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
  336. package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
  337. package/utils/gc/__tests__/gc.test.ts +487 -0
  338. package/utils/ingress.ts +9 -1
  339. package/utils/object.js +33 -2
  340. package/utils/pagination-utils.ts +2 -1
  341. package/utils/string.js +25 -2
  342. package/utils/time.ts +5 -0
  343. package/utils/uiplugins.ts +5 -5
  344. package/utils/validators/__tests__/cluster-name.test.ts +110 -0
  345. package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
  346. package/utils/validators/__tests__/index.test.ts +481 -0
  347. package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
  348. package/utils/validators/__tests__/misc-validators.test.ts +246 -0
  349. package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
  350. package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
  351. package/utils/validators/__tests__/role-template.test.ts +149 -0
  352. package/utils/validators/__tests__/service.test.ts +283 -0
  353. package/utils/validators/__tests__/setting.test.js +32 -0
  354. package/utils/validators/formRules/__tests__/index.test.ts +50 -0
  355. package/utils/validators/formRules/index.ts +5 -5
  356. package/utils/validators/machine-pool.ts +1 -1
  357. package/utils/validators/setting.js +18 -3
  358. package/utils/xccdf.ts +418 -0
  359. package/vue.config.js +0 -9
  360. package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
  361. package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
  362. package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
  363. package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
  364. package/assets/images/providers/azuread-black.svg +0 -22
  365. package/assets/images/providers/azuread.svg +0 -25
  366. package/assets/images/vendor/azuread.svg +0 -18
  367. package/assets/styles/fonts/_dots.scss +0 -18
  368. package/components/EmberPage.vue +0 -622
  369. package/components/EmberPageView.vue +0 -39
  370. package/components/form/labeled-select-utils/labeled-select-pagination.ts +0 -116
  371. package/mixins/labeled-form-element.ts +0 -225
  372. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -28
  373. package/pages/c/_cluster/manager/pages/_page.vue +0 -22
  374. package/pages/c/_cluster/mcapps/pages/_page.vue +0 -22
  375. package/plugins/ember-cookie.js +0 -17
  376. package/utils/ember-page.js +0 -30
@@ -8,6 +8,13 @@ export default {
8
8
  name: 'WorkspaceSwitcher',
9
9
  components: { Select },
10
10
 
11
+ props: {
12
+ disabled: {
13
+ type: Boolean,
14
+ default: false,
15
+ },
16
+ },
17
+
11
18
  computed: {
12
19
  ...mapState(['allWorkspaces', 'workspace', 'allNamespaces', 'defaultNamespace', 'getActiveNamespaces']),
13
20
 
@@ -94,6 +101,7 @@ export default {
94
101
  label="label"
95
102
  :options="options"
96
103
  :clearable="false"
104
+ :disabled="disabled"
97
105
  :reduce="(opt) => opt.value"
98
106
  />
99
107
  <!--button v-shortkey.once="['w']" class="hide" @shortkey="focus()" /-->
@@ -187,4 +195,9 @@ export default {
187
195
  .filter :deep() .unlabeled-select INPUT[type='search'] {
188
196
  padding: 7px;
189
197
  }
198
+
199
+ .filter :deep() .unlabeled-select.disabled {
200
+ opacity: 0.5;
201
+ cursor: not-allowed;
202
+ }
190
203
  </style>
@@ -0,0 +1,67 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import Group from '@shell/components/nav/Group.vue';
3
+
4
+ describe('component: Group', () => {
5
+ it('isOverview ignores query parameters and hash strings when checking active state', () => {
6
+ const group = {
7
+ name: 'test',
8
+ children: [
9
+ {
10
+ route: { name: 'overview-route' },
11
+ overview: true
12
+ }
13
+ ]
14
+ };
15
+
16
+ const wrapper = shallowMount(Group as any, {
17
+ props: {
18
+ group, canCollapse: true, idPrefix: ''
19
+ },
20
+ global: {
21
+ mocks: {
22
+ $route: { path: '/test/route', fullPath: '/test/route?query=val#hash' },
23
+ $router: {
24
+ resolve: jest.fn().mockReturnValue({ path: '/test/route', fullPath: '/test/route' }),
25
+ getRoutes: jest.fn().mockReturnValue([])
26
+ },
27
+ t: (key: string) => key
28
+ }
29
+ }
30
+ });
31
+
32
+ expect((wrapper.vm as any).isOverview).toBe(true);
33
+ });
34
+
35
+ it('hasActiveRoute ignores query parameters when checking item paths', () => {
36
+ const group = {
37
+ name: 'test',
38
+ children: [
39
+ { route: { name: 'child-route', params: {} } }
40
+ ]
41
+ };
42
+
43
+ const wrapper = shallowMount(Group as any, {
44
+ props: {
45
+ group, canCollapse: true, idPrefix: ''
46
+ },
47
+ global: {
48
+ mocks: {
49
+ $route: {
50
+ params: {},
51
+ hash: '#hash',
52
+ path: '/child/route',
53
+ fullPath: '/child/route?query=val#hash',
54
+ matched: []
55
+ },
56
+ $router: {
57
+ resolve: jest.fn().mockReturnValue({ path: '/child/route', fullPath: '/child/route' }),
58
+ getRoutes: jest.fn().mockReturnValue([])
59
+ },
60
+ t: (key: string) => key
61
+ }
62
+ }
63
+ });
64
+
65
+ expect((wrapper.vm as any).hasActiveRoute()).toBe(true);
66
+ });
67
+ });
@@ -0,0 +1,235 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import Header from '@shell/components/nav/Header.vue';
3
+
4
+ describe('component: Header', () => {
5
+ const defaultStoreMock = {
6
+ getters: {
7
+ clusterReady: false,
8
+ isExplorer: false,
9
+ isRancher: false,
10
+ currentCluster: null,
11
+ currentProduct: null,
12
+ rootProduct: { name: 'fleet' },
13
+ backToRancherLink: '',
14
+ backToRancherGlobalLink: '',
15
+ pageActions: [],
16
+ isSingleProduct: false,
17
+ isRancherInHarvester: false,
18
+ showTopLevelMenu: false,
19
+ showWorkspaceSwitcher: true,
20
+ 'management/schemaFor': () => null,
21
+ 'management/all': () => [],
22
+ 'rancher/schemaFor': () => null,
23
+ 'rancher/byId': () => null,
24
+ 'rancher/all': () => [],
25
+ 'auth/principalId': 'test',
26
+ 'auth/enabled': false,
27
+ 'i18n/withFallback': () => '',
28
+ },
29
+ dispatch: jest.fn(),
30
+ commit: jest.fn(),
31
+ };
32
+
33
+ const defaultRouteMock = {
34
+ name: 'c-cluster-fleet-application-resource',
35
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo',
36
+ params: { resource: 'fleet.cattle.io.gitrepo' },
37
+ };
38
+
39
+ const defaultConfigMock = { rancherEnv: 'web' };
40
+
41
+ function createWrapper(routeOverride = {}, storeOverride = {}) {
42
+ const routeMock = {
43
+ ...defaultRouteMock,
44
+ ...routeOverride,
45
+ };
46
+
47
+ const storeMock = {
48
+ ...defaultStoreMock,
49
+ getters: {
50
+ ...defaultStoreMock.getters,
51
+ ...storeOverride,
52
+ },
53
+ dispatch: jest.fn(),
54
+ commit: jest.fn(),
55
+ };
56
+
57
+ return shallowMount(Header as any, {
58
+ global: {
59
+ mocks: {
60
+ $store: storeMock,
61
+ $route: routeMock,
62
+ $config: defaultConfigMock,
63
+ $extension: { getDynamic: jest.fn() },
64
+ },
65
+ stubs: {
66
+ 'router-link': { template: '<a><slot /></a>' },
67
+ BrandImage: { template: '<span />' },
68
+ ClusterProviderIcon: { template: '<span />' },
69
+ ClusterBadge: { template: '<span />' },
70
+ TopLevelMenu: { template: '<div />' },
71
+ NamespaceFilter: { template: '<div />' },
72
+ WorkspaceSwitcher: { template: '<div />' },
73
+ IconOrSvg: { template: '<span />' },
74
+ AppModal: { template: '<div />' },
75
+ NotificationCenter: { template: '<div />' },
76
+ HeaderPageActionMenu: { template: '<div />' },
77
+ RcDropdown: { template: '<div><slot /><slot name="dropdownCollection" /></div>' },
78
+ RcDropdownItem: { template: '<div><slot /></div>' },
79
+ RcDropdownSeparator: { template: '<hr />' },
80
+ RcDropdownTrigger: { template: '<button><slot /></button>' },
81
+ },
82
+ },
83
+ });
84
+ }
85
+
86
+ describe('disableWorkspaceSwitcher', () => {
87
+ it('should return false on a list page', () => {
88
+ const wrapper = createWrapper({
89
+ name: 'c-cluster-fleet-application-resource',
90
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo',
91
+ params: { resource: 'fleet.cattle.io.gitrepo' },
92
+ });
93
+
94
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(false);
95
+ });
96
+
97
+ it('should return true on a detail page (route has an id param)', () => {
98
+ const wrapper = createWrapper({
99
+ name: 'c-cluster-fleet-application-resource-namespace-id',
100
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/fleet-default/my-repo',
101
+ params: {
102
+ resource: 'fleet.cattle.io.gitrepo', namespace: 'fleet-default', id: 'my-repo'
103
+ },
104
+ });
105
+
106
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(true);
107
+ });
108
+
109
+ it('should return true on a create page (route name ends with -create)', () => {
110
+ const wrapper = createWrapper({
111
+ name: 'c-cluster-fleet-application-resource-create',
112
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/create',
113
+ params: { resource: 'fleet.cattle.io.gitrepo' },
114
+ });
115
+
116
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(true);
117
+ });
118
+
119
+ it('should return true on the application create page', () => {
120
+ const wrapper = createWrapper({
121
+ name: 'c-cluster-fleet-application-create',
122
+ path: '/c/local/fleet/application/create',
123
+ params: {},
124
+ });
125
+
126
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(true);
127
+ });
128
+
129
+ it('should return false on the Workspaces list page', () => {
130
+ const wrapper = createWrapper({
131
+ name: 'c-cluster-fleet-application-resource',
132
+ path: '/c/local/fleet/application/management.cattle.io.fleetworkspace',
133
+ params: { resource: 'management.cattle.io.fleetworkspace' },
134
+ });
135
+
136
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(false);
137
+ });
138
+
139
+ it('should return false on a non-workspace resource list page', () => {
140
+ const wrapper = createWrapper({
141
+ name: 'c-cluster-fleet-application-resource',
142
+ path: '/c/local/fleet/application/fleet.cattle.io.cluster',
143
+ params: { resource: 'fleet.cattle.io.cluster' },
144
+ });
145
+
146
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(false);
147
+ });
148
+
149
+ it('should return true on an edit page (route has an id param)', () => {
150
+ const wrapper = createWrapper({
151
+ name: 'c-cluster-fleet-application-resource-namespace-id',
152
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/fleet-default/my-repo?mode=edit',
153
+ params: {
154
+ resource: 'fleet.cattle.io.gitrepo', namespace: 'fleet-default', id: 'my-repo'
155
+ },
156
+ });
157
+
158
+ expect((wrapper.vm as any).disableWorkspaceSwitcher).toBe(true);
159
+ });
160
+ });
161
+
162
+ describe('showFilter', () => {
163
+ it('should return true on a list page when showWorkspaceSwitcher is enabled', () => {
164
+ const wrapper = createWrapper(
165
+ {
166
+ name: 'c-cluster-fleet-application-resource',
167
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo',
168
+ params: { resource: 'fleet.cattle.io.gitrepo' },
169
+ },
170
+ { currentProduct: { showWorkspaceSwitcher: true } },
171
+ );
172
+
173
+ expect((wrapper.vm as any).showFilter).toBe(true);
174
+ });
175
+
176
+ it('should return true when showWorkspaceSwitcher is enabled on a detail page (switcher visible but disabled)', () => {
177
+ const wrapper = createWrapper(
178
+ {
179
+ name: 'c-cluster-fleet-application-resource-namespace-id',
180
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/fleet-default/my-repo',
181
+ params: {
182
+ resource: 'fleet.cattle.io.gitrepo', namespace: 'fleet-default', id: 'my-repo'
183
+ },
184
+ },
185
+ { currentProduct: { showWorkspaceSwitcher: true } },
186
+ );
187
+
188
+ expect((wrapper.vm as any).showFilter).toBe(true);
189
+ });
190
+
191
+ it('should return true when showWorkspaceSwitcher is enabled on a create page (switcher visible but disabled)', () => {
192
+ const wrapper = createWrapper(
193
+ {
194
+ name: 'c-cluster-fleet-application-resource-create',
195
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/create',
196
+ params: { resource: 'fleet.cattle.io.gitrepo' },
197
+ },
198
+ { currentProduct: { showWorkspaceSwitcher: true } },
199
+ );
200
+
201
+ expect((wrapper.vm as any).showFilter).toBe(true);
202
+ });
203
+
204
+ it('should return false when showWorkspaceSwitcher is false in the store (e.g. Workspaces page)', () => {
205
+ const wrapper = createWrapper(
206
+ {
207
+ name: 'c-cluster-fleet-application-resource',
208
+ path: '/c/local/fleet/application/management.cattle.io.fleetworkspace',
209
+ params: { resource: 'management.cattle.io.fleetworkspace' },
210
+ },
211
+ {
212
+ currentProduct: { showWorkspaceSwitcher: true },
213
+ showWorkspaceSwitcher: false,
214
+ },
215
+ );
216
+
217
+ expect((wrapper.vm as any).showFilter).toBe(false);
218
+ });
219
+
220
+ it('should return true when showNamespaceFilter is enabled regardless of route', () => {
221
+ const wrapper = createWrapper(
222
+ {
223
+ name: 'c-cluster-fleet-application-resource-namespace-id',
224
+ path: '/c/local/fleet/application/fleet.cattle.io.gitrepo/fleet-default/my-repo',
225
+ params: {
226
+ resource: 'fleet.cattle.io.gitrepo', namespace: 'fleet-default', id: 'my-repo'
227
+ },
228
+ },
229
+ { currentCluster: { id: 'local' }, currentProduct: { showNamespaceFilter: true } },
230
+ );
231
+
232
+ expect((wrapper.vm as any).showFilter).toBe(true);
233
+ });
234
+ });
235
+ });
@@ -110,28 +110,28 @@ describe('topLevelMenu', () => {
110
110
  id: 'an-id1',
111
111
  mgmt: { id: 'an-id1' },
112
112
  nameDisplay: 'c-cluster',
113
- isReady: true
113
+ canExplore: true
114
114
  },
115
115
  {
116
116
  name: 'x33-cwf5-name',
117
117
  id: 'an-id2',
118
118
  mgmt: { id: 'an-id2' },
119
119
  nameDisplay: 'a-cluster',
120
- isReady: true
120
+ canExplore: true
121
121
  },
122
122
  {
123
123
  name: 'x34-cwf5-name',
124
124
  id: 'an-id3',
125
125
  mgmt: { id: 'an-id3' },
126
126
  nameDisplay: 'b-cluster',
127
- isReady: true
127
+ canExplore: true
128
128
  },
129
129
  {
130
130
  name: 'local-name',
131
131
  id: 'local',
132
132
  mgmt: { id: 'local' },
133
133
  nameDisplay: 'local',
134
- isReady: true
134
+ canExplore: true
135
135
  },
136
136
  ])
137
137
  }
@@ -156,28 +156,28 @@ describe('topLevelMenu', () => {
156
156
  id: 'an-id1',
157
157
  mgmt: { id: 'an-id1' },
158
158
  nameDisplay: 'c-cluster',
159
- isReady: true
159
+ canExplore: true
160
160
  },
161
161
  {
162
162
  name: 'x33-cwf5-name',
163
163
  id: 'an-id2',
164
164
  mgmt: { id: 'an-id2' },
165
165
  nameDisplay: 'a-cluster',
166
- isReady: false
166
+ canExplore: false
167
167
  },
168
168
  {
169
169
  name: 'x34-cwf5-name',
170
170
  id: 'an-id3',
171
171
  mgmt: { id: 'an-id3' },
172
172
  nameDisplay: 'b-cluster',
173
- isReady: true
173
+ canExplore: true
174
174
  },
175
175
  {
176
176
  name: 'local-name',
177
177
  id: 'local',
178
178
  mgmt: { id: 'local' },
179
179
  nameDisplay: 'local',
180
- isReady: true,
180
+ canExplore: true,
181
181
  isLocal: true,
182
182
  },
183
183
  ];
@@ -195,9 +195,9 @@ describe('topLevelMenu', () => {
195
195
  await waitForIt();
196
196
 
197
197
  expect(wrapper.find('[data-testid="top-level-menu-cluster-0"] .cluster-name p').text()).toStrictEqual('local');
198
+ expect(wrapper.find('[data-testid="top-level-menu-cluster-3"] .cluster-name p').text()).toStrictEqual('a-cluster');
198
199
  expect(wrapper.find('[data-testid="top-level-menu-cluster-1"] .cluster-name p').text()).toStrictEqual('b-cluster');
199
200
  expect(wrapper.find('[data-testid="top-level-menu-cluster-2"] .cluster-name p').text()).toStrictEqual('c-cluster');
200
- expect(wrapper.find('[data-testid="top-level-menu-cluster-3"] .cluster-name p').text()).toStrictEqual('a-cluster');
201
201
  });
202
202
 
203
203
  it('should show local cluster always on top of the list of clusters (pinned and ready clusters)', async() => {
@@ -212,7 +212,7 @@ describe('topLevelMenu', () => {
212
212
  id: 'an-id1',
213
213
  mgmt: { id: 'an-id1' },
214
214
  nameDisplay: 'c-cluster',
215
- isReady: true,
215
+ canExplore: true,
216
216
  pinned: true
217
217
  },
218
218
  {
@@ -220,7 +220,7 @@ describe('topLevelMenu', () => {
220
220
  id: 'an-id2',
221
221
  mgmt: { id: 'an-id2' },
222
222
  nameDisplay: 'a-cluster',
223
- isReady: true,
223
+ canExplore: true,
224
224
  pinned: true
225
225
  },
226
226
  {
@@ -228,7 +228,7 @@ describe('topLevelMenu', () => {
228
228
  id: 'an-id3',
229
229
  mgmt: { id: 'an-id3' },
230
230
  nameDisplay: 'b-cluster',
231
- isReady: true,
231
+ canExplore: true,
232
232
  pinned: true
233
233
  },
234
234
  {
@@ -236,7 +236,7 @@ describe('topLevelMenu', () => {
236
236
  id: 'local',
237
237
  mgmt: { id: 'local' },
238
238
  nameDisplay: 'local',
239
- isReady: true,
239
+ canExplore: true,
240
240
  pinned: true
241
241
  },
242
242
  ])
@@ -271,7 +271,7 @@ describe('topLevelMenu', () => {
271
271
  id: 'an-id1',
272
272
  mgmt: { id: 'an-id1' },
273
273
  nameDisplay: 'c-cluster',
274
- isReady: true,
274
+ canExplore: true,
275
275
  pinned: true
276
276
  },
277
277
  {
@@ -279,7 +279,7 @@ describe('topLevelMenu', () => {
279
279
  id: 'an-id2',
280
280
  mgmt: { id: 'an-id2' },
281
281
  nameDisplay: 'a-cluster',
282
- isReady: true,
282
+ canExplore: true,
283
283
  pinned: true
284
284
  },
285
285
  {
@@ -287,7 +287,7 @@ describe('topLevelMenu', () => {
287
287
  id: 'an-id3',
288
288
  mgmt: { id: 'an-id3' },
289
289
  nameDisplay: 'b-cluster',
290
- isReady: false,
290
+ canExplore: false,
291
291
  pinned: true
292
292
  },
293
293
  {
@@ -295,7 +295,7 @@ describe('topLevelMenu', () => {
295
295
  id: 'local',
296
296
  mgmt: { id: 'local' },
297
297
  nameDisplay: 'local',
298
- isReady: true,
298
+ canExplore: true,
299
299
  pinned: true
300
300
  },
301
301
  ])
@@ -328,7 +328,7 @@ describe('topLevelMenu', () => {
328
328
  mgmt: { id: 'an-id1' },
329
329
  description: 'some-description1',
330
330
  nameDisplay: 'some-label',
331
- isReady: true,
331
+ canExplore: true,
332
332
  pinned: true
333
333
  },
334
334
  // pinned NOT ready cluster
@@ -347,7 +347,7 @@ describe('topLevelMenu', () => {
347
347
  mgmt: { id: 'an-id3' },
348
348
  description: 'some-description3',
349
349
  nameDisplay: 'some-label',
350
- isReady: true
350
+ canExplore: true
351
351
  },
352
352
  // unpinned NOT ready cluster
353
353
  {
@@ -392,7 +392,7 @@ describe('topLevelMenu', () => {
392
392
  mgmt: { id: 'an-id1' },
393
393
  description: 'some-description1',
394
394
  nameDisplay: 'some-label',
395
- isReady: true,
395
+ canExplore: true,
396
396
  pinned: true
397
397
  },
398
398
  // pinned NOT ready cluster
@@ -411,7 +411,7 @@ describe('topLevelMenu', () => {
411
411
  mgmt: { id: 'an-id3' },
412
412
  description: 'some-description3',
413
413
  nameDisplay: 'some-label',
414
- isReady: true
414
+ canExplore: true
415
415
  },
416
416
  // unpinned NOT ready cluster
417
417
  {
@@ -713,4 +713,128 @@ describe('topLevelMenu', () => {
713
713
  expect(wrapper.vm.mgmtClusters).toStrictEqual([]);
714
714
  });
715
715
  });
716
+
717
+ describe('computed properties', () => {
718
+ describe('routeComboActive', () => {
719
+ it('should be true when routeCombo is true and there are multiple ready clusters', async() => {
720
+ const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
721
+ global: {
722
+ mocks: {
723
+ $route: {},
724
+ $store: {
725
+ ...generateStore([
726
+ {
727
+ nameDisplay: 'cluster1',
728
+ id: 'an-id1',
729
+ mgmt: { id: 'an-id1' },
730
+ canExplore: true
731
+ },
732
+ {
733
+ nameDisplay: 'cluster2',
734
+ id: 'an-id2',
735
+ mgmt: { id: 'an-id2' },
736
+ canExplore: true
737
+ }
738
+ ])
739
+ }
740
+ },
741
+ stubs: ['BrandImage', 'router-link'],
742
+ }
743
+ });
744
+
745
+ await waitForIt();
746
+ await wrapper.setData({ routeCombo: true });
747
+
748
+ expect(wrapper.vm.routeComboActive).toBe(true);
749
+ });
750
+
751
+ it('should be false when routeCombo is false', async() => {
752
+ const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
753
+ global: {
754
+ mocks: {
755
+ $route: {},
756
+ $store: {
757
+ ...generateStore([
758
+ {
759
+ nameDisplay: 'cluster1',
760
+ id: 'an-id1',
761
+ mgmt: { id: 'an-id1' },
762
+ canExplore: true
763
+ },
764
+ {
765
+ nameDisplay: 'cluster2',
766
+ id: 'an-id2',
767
+ mgmt: { id: 'an-id2' },
768
+ canExplore: true
769
+ }
770
+ ])
771
+ }
772
+ },
773
+ stubs: ['BrandImage', 'router-link'],
774
+ }
775
+ });
776
+
777
+ await waitForIt();
778
+ await wrapper.setData({ routeCombo: false });
779
+
780
+ expect(wrapper.vm.routeComboActive).toBe(false);
781
+ });
782
+
783
+ it('should be false when there is only one ready cluster and it is the current cluster', async() => {
784
+ const store = generateStore([
785
+ {
786
+ nameDisplay: 'cluster1',
787
+ id: 'an-id1',
788
+ mgmt: { id: 'an-id1' },
789
+ canExplore: true
790
+ }
791
+ ]);
792
+
793
+ store.getters.clusterId = 'an-id1' as any;
794
+
795
+ const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
796
+ global: {
797
+ mocks: {
798
+ $route: {},
799
+ $store: store
800
+ },
801
+ stubs: ['BrandImage', 'router-link'],
802
+ }
803
+ });
804
+
805
+ await waitForIt();
806
+ await wrapper.setData({ routeCombo: true });
807
+
808
+ expect(wrapper.vm.routeComboActive).toBe(false);
809
+ });
810
+
811
+ it('should be true when there is only one ready cluster but it is not the current cluster', async() => {
812
+ const store = generateStore([
813
+ {
814
+ nameDisplay: 'cluster1',
815
+ id: 'an-id1',
816
+ mgmt: { id: 'an-id1' },
817
+ canExplore: true
818
+ }
819
+ ]);
820
+
821
+ store.getters.clusterId = 'some-other-cluster-id' as any;
822
+
823
+ const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
824
+ global: {
825
+ mocks: {
826
+ $route: {},
827
+ $store: store
828
+ },
829
+ stubs: ['BrandImage', 'router-link'],
830
+ }
831
+ });
832
+
833
+ await waitForIt();
834
+ await wrapper.setData({ routeCombo: true });
835
+
836
+ expect(wrapper.vm.routeComboActive).toBe(true);
837
+ });
838
+ });
839
+ });
716
840
  });
@@ -28,10 +28,10 @@ describe('component: Type', () => {
28
28
  };
29
29
  const routerMock = {
30
30
  resolve: jest.fn((route) => {
31
- return { fullPath: route };
31
+ return { fullPath: route, path: route };
32
32
  })
33
33
  };
34
- const routeMock = { fullPath: 'route' };
34
+ const routeMock = { fullPath: 'route', path: 'route' };
35
35
 
36
36
  describe('should pass props correctly', () => {
37
37
  it('should forward Type props to router-link', () => {
@@ -104,7 +104,7 @@ describe('component: Type', () => {
104
104
  directives: { cleanHtml: (identity) => identity },
105
105
 
106
106
  mocks: {
107
- $store: storeMock, $router: routerMock, $route: { fullPath: 'bad' }
107
+ $store: storeMock, $router: routerMock, $route: { fullPath: 'bad', path: 'bad' }
108
108
  },
109
109
  stubs: { routerLink: createChildRenderingRouterLinkStub() },
110
110
  },
@@ -152,6 +152,23 @@ describe('component: Type', () => {
152
152
 
153
153
  expect(elementWithSelector.exists()).toBe(false);
154
154
  });
155
+ it('should use active and exact active classes when route matches but includes query and hash', () => {
156
+ const wrapper = shallowMount(Type as any, {
157
+ props: { type: defaultRouteTypeProp, highlightRoute: true },
158
+
159
+ global: {
160
+ directives: { cleanHtml: (identity) => identity },
161
+
162
+ mocks: {
163
+ $store: storeMock, $router: routerMock, $route: { fullPath: 'route?repo=test#myhash', path: 'route' }
164
+ },
165
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isExactActive: true }) },
166
+ },
167
+ });
168
+
169
+ expect(wrapper.find(`.${ activeClass }`).exists()).toBe(true);
170
+ expect(wrapper.find(`.${ exactActiveClass }`).exists()).toBe(true);
171
+ });
155
172
  });
156
173
 
157
174
  describe('should use classes if preconditions are met', () => {