@rancher/shell 0.5.3 → 2.0.0

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 (581) hide show
  1. package/assets/data/aws-regions.json +9 -0
  2. package/assets/images/vendor/openid.svg +18 -0
  3. package/assets/styles/app.scss +1 -2
  4. package/assets/styles/fonts/_icons.scss +3 -3
  5. package/assets/styles/global/_columns.scss +1 -1
  6. package/assets/styles/global/_labeled-input.scss +2 -0
  7. package/assets/styles/themes/_csp.scss +2 -2
  8. package/assets/styles/themes/_dark.scss +8 -2
  9. package/assets/styles/themes/_light.scss +2 -1
  10. package/assets/styles/themes/_suse.scss +1 -1
  11. package/assets/styles/vendor/vue-select.scss +5 -0
  12. package/assets/translations/en-us.yaml +296 -58
  13. package/assets/translations/zh-hans.yaml +5 -27
  14. package/babel.config.js +1 -1
  15. package/chart/__tests__/S3.test.ts +9 -2
  16. package/chart/monitoring/grafana/index.vue +6 -2
  17. package/chart/monitoring/prometheus/index.vue +2 -2
  18. package/chart/rancher-backup/S3.vue +11 -9
  19. package/chart/rancher-backup/index.vue +15 -5
  20. package/cloud-credential/__tests__/harvester.test.ts +18 -0
  21. package/cloud-credential/generic.vue +18 -9
  22. package/cloud-credential/harvester.vue +11 -3
  23. package/components/AppModal.vue +167 -0
  24. package/components/AssignTo.vue +7 -4
  25. package/components/AsyncButton.vue +18 -5
  26. package/components/BackLink.vue +4 -4
  27. package/components/BannerGraphic.vue +1 -0
  28. package/components/BrandImage.vue +47 -1
  29. package/components/Carousel.vue +14 -8
  30. package/components/Certificates.vue +8 -11
  31. package/components/ClusterBadge.vue +12 -3
  32. package/components/ClusterIconMenu.vue +44 -16
  33. package/components/ClusterProviderIcon.vue +14 -3
  34. package/components/CodeMirror.vue +73 -38
  35. package/components/CommunityLinks.vue +12 -8
  36. package/components/CreateDriver.vue +81 -0
  37. package/components/CruResource.vue +51 -27
  38. package/components/DetailTop.vue +2 -2
  39. package/components/Dialog.vue +6 -5
  40. package/components/DisableAuthProviderModal.vue +14 -8
  41. package/components/DraggableZone.vue +2 -2
  42. package/components/ExplorerMembers.vue +3 -3
  43. package/components/ExplorerProjectsNamespaces.vue +6 -6
  44. package/components/FixedBanner.vue +47 -36
  45. package/components/GlobalRoleBindings.vue +26 -0
  46. package/components/Import.vue +10 -6
  47. package/components/Inactivity.vue +1 -5
  48. package/components/KeyValueView.vue +14 -10
  49. package/components/MessageLink.vue +2 -2
  50. package/components/ModalWithCard.vue +5 -8
  51. package/components/MoveModal.vue +35 -33
  52. package/components/PodSecurityAdmission.vue +3 -3
  53. package/components/PromptChangePassword.vue +33 -33
  54. package/components/PromptModal.vue +11 -21
  55. package/components/PromptRemove.vue +11 -17
  56. package/components/PromptRestore.vue +18 -16
  57. package/components/Questions/__tests__/Boolean.test.ts +9 -19
  58. package/components/Questions/__tests__/Float.test.ts +9 -19
  59. package/components/Questions/__tests__/Int.test.ts +9 -19
  60. package/components/Questions/__tests__/String.test.ts +9 -19
  61. package/components/Questions/__tests__/Yaml.test.ts +9 -20
  62. package/components/Questions/__tests__/utils/questions-defaults.ts +20 -0
  63. package/components/Questions/index.vue +18 -2
  64. package/components/ResourceCancelModal.vue +34 -29
  65. package/components/ResourceDetail/Masthead.vue +23 -7
  66. package/components/ResourceDetail/index.vue +5 -0
  67. package/components/ResourceList/Masthead.vue +28 -10
  68. package/components/ResourceList/index.vue +65 -14
  69. package/components/ResourceTable.vue +73 -19
  70. package/components/ResourceYaml.vue +1 -0
  71. package/components/SelectIconGrid.vue +3 -3
  72. package/components/SideNav.vue +15 -37
  73. package/components/SingleClusterInfo.vue +4 -4
  74. package/components/SortableTable/THead.vue +26 -12
  75. package/components/SortableTable/filtering.js +9 -1
  76. package/components/SortableTable/grouping.js +8 -1
  77. package/components/SortableTable/index.vue +142 -42
  78. package/components/SortableTable/paging.js +36 -7
  79. package/components/SortableTable/selection.js +2 -1
  80. package/components/SortableTable/sorting.js +24 -7
  81. package/components/TabTitle.vue +84 -0
  82. package/components/Tabbed/index.vue +6 -1
  83. package/components/TableDataUserIcon.vue +47 -0
  84. package/components/TypeDescription.vue +1 -0
  85. package/components/Wizard.vue +1 -0
  86. package/components/__tests__/AppModal.test.ts +98 -0
  87. package/components/__tests__/AsyncButton.test.ts +1 -3
  88. package/components/__tests__/BackLink.test.ts +1 -1
  89. package/components/__tests__/ButtonGroup.test.ts +3 -6
  90. package/components/__tests__/Carousel.test.ts +43 -0
  91. package/components/__tests__/Certificates.test.ts +29 -0
  92. package/components/__tests__/{CodeMirror.spec.ts → CodeMirror.test.ts} +5 -17
  93. package/components/__tests__/CruResource.test.ts +10 -9
  94. package/components/__tests__/EtcdInfoBanner.test.ts +37 -0
  95. package/components/__tests__/FixedBanner.test.ts +5 -20
  96. package/components/__tests__/NamespaceFilter.test.ts +9 -18
  97. package/components/__tests__/TabTitle.test.ts +129 -0
  98. package/components/auth/AzureWarning.vue +2 -2
  99. package/components/auth/RoleDetailEdit.vue +10 -0
  100. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  101. package/components/auth/login/oidc.vue +7 -1
  102. package/components/fleet/FleetClusters.vue +9 -9
  103. package/components/fleet/FleetIntro.vue +11 -17
  104. package/components/fleet/FleetNoWorkspaces.vue +2 -2
  105. package/components/fleet/FleetRepos.vue +1 -0
  106. package/components/fleet/ForceDirectedTreeChart/index.vue +9 -3
  107. package/components/form/ArrayList.vue +30 -19
  108. package/components/form/ArrayListSelect.vue +9 -4
  109. package/components/form/ClusterAppearance.vue +132 -0
  110. package/components/form/ColorInput.vue +1 -0
  111. package/components/form/Error.vue +3 -3
  112. package/components/form/Footer.vue +2 -2
  113. package/components/form/GitPicker.vue +83 -38
  114. package/components/form/KeyValue.vue +67 -48
  115. package/components/form/LabeledSelect.vue +143 -43
  116. package/components/form/Labels.vue +3 -1
  117. package/components/form/NameNsDescription.vue +26 -9
  118. package/components/form/ResourceLabeledSelect.vue +187 -0
  119. package/components/form/ResourceTabs/index.vue +31 -15
  120. package/components/form/SecretSelector.vue +93 -18
  121. package/components/form/Select.vue +1 -1
  122. package/components/form/SelectOrCreateAuthSecret.vue +135 -62
  123. package/components/form/SimpleSecretSelector.vue +88 -28
  124. package/components/form/__tests__/BannerSettings.test.ts +53 -0
  125. package/components/form/__tests__/KeyValue.test.ts +121 -12
  126. package/components/form/__tests__/LabeledSelect.test.ts +0 -18
  127. package/components/form/__tests__/NameNsDescription.test.ts +25 -15
  128. package/components/form/labeled-select-utils/labeled-select-pagination.ts +151 -0
  129. package/components/form/labeled-select-utils/labeled-select.utils.ts +122 -0
  130. package/components/formatter/AppSummaryGraph.vue +2 -2
  131. package/components/formatter/CloudCredPublicData.vue +30 -0
  132. package/components/formatter/ClusterLink.vue +2 -2
  133. package/components/formatter/FleetSummaryGraph.vue +2 -1
  134. package/components/formatter/ImagePercentageBar.vue +0 -4
  135. package/components/formatter/IngressTarget.vue +18 -7
  136. package/components/formatter/Link.vue +2 -2
  137. package/components/formatter/LinkDetail.vue +2 -2
  138. package/components/formatter/LinkDetailImage.vue +2 -2
  139. package/components/formatter/LinkName.vue +2 -2
  140. package/components/formatter/LiveDate.vue +16 -0
  141. package/components/formatter/PrincipalGroupBindings.vue +2 -2
  142. package/components/formatter/SecretType.vue +2 -2
  143. package/components/formatter/VirtualServiceGateways.vue +2 -2
  144. package/components/formatter/__tests__/LinkDetail.test.ts +5 -5
  145. package/components/nav/Group.vue +7 -5
  146. package/components/nav/Header.vue +82 -43
  147. package/components/nav/NamespaceFilter.vue +8 -1
  148. package/components/nav/TopLevelMenu.vue +336 -125
  149. package/components/nav/Type.vue +58 -102
  150. package/components/nav/__tests__/TopLevelMenu.test.ts +370 -9
  151. package/components/nav/__tests__/Type.test.ts +321 -126
  152. package/components/nuxt/nuxt-child.js +0 -5
  153. package/components/nuxt/nuxt-error.vue +1 -1
  154. package/components/nuxt/nuxt-link.client.js +13 -95
  155. package/components/templates/default.vue +3 -3
  156. package/components/templates/error.vue +6 -10
  157. package/components/templates/standalone.vue +0 -4
  158. package/components/templates/unauthenticated.vue +1 -2
  159. package/components/user.retention/user-retention-header.vue +34 -0
  160. package/composables/useCompactInput.test.ts +36 -0
  161. package/composables/useCompactInput.ts +2 -2
  162. package/composables/useI18n.ts +26 -0
  163. package/composables/useLabeledFormElement.test.ts +135 -0
  164. package/composables/useStore.ts +16 -0
  165. package/config/home-links.js +32 -1
  166. package/config/labels-annotations.js +2 -1
  167. package/config/middleware.js +0 -6
  168. package/config/pagination-table-headers.js +57 -0
  169. package/config/pod-security-admission.ts +1 -1
  170. package/config/private-label.js +1 -3
  171. package/config/product/auth.js +1 -0
  172. package/config/product/explorer.js +167 -46
  173. package/config/product/legacy.js +3 -95
  174. package/config/product/manager.js +44 -11
  175. package/config/query-params.js +1 -0
  176. package/config/roles.ts +23 -0
  177. package/config/router/index.js +23 -0
  178. package/config/router/navigation-guards/attempt-first-login.js +73 -0
  179. package/config/router/navigation-guards/authentication.js +63 -0
  180. package/config/router/navigation-guards/index.js +15 -0
  181. package/config/router/navigation-guards/load-initial-settings.js +15 -0
  182. package/config/router/routes.js +487 -0
  183. package/config/settings.ts +38 -2
  184. package/config/store.js +7 -3
  185. package/config/table-headers.js +46 -1
  186. package/config/types.js +36 -16
  187. package/config/uiplugins.js +10 -5
  188. package/core/plugin-helpers.js +1 -1
  189. package/core/plugin.ts +2 -1
  190. package/core/plugins.js +289 -282
  191. package/creators/app/files/.eslintignore +0 -2
  192. package/creators/app/files/.vscode/settings.json +0 -1
  193. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +2 -6
  194. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +2 -6
  195. package/creators/pkg/init +32 -0
  196. package/detail/__tests__/service.test.ts +62 -0
  197. package/detail/catalog.cattle.io.app.vue +1 -1
  198. package/detail/cis.cattle.io.clusterscan.vue +14 -3
  199. package/detail/fleet.cattle.io.gitrepo.vue +15 -9
  200. package/detail/namespace.vue +2 -2
  201. package/detail/networking.k8s.io.ingress.vue +52 -19
  202. package/detail/node.vue +20 -43
  203. package/detail/pod.vue +1 -68
  204. package/detail/provisioning.cattle.io.cluster.vue +2 -1
  205. package/detail/service.vue +1 -1
  206. package/detail/workload/index.vue +2 -15
  207. package/dialog/AddCustomBadgeDialog.vue +318 -161
  208. package/dialog/DeactivateDriverDialog.vue +118 -0
  209. package/dialog/RollbackWorkloadDialog.vue +2 -2
  210. package/dialog/RotateCertificatesDialog.vue +0 -21
  211. package/directives/clean-html.js +15 -0
  212. package/directives/clean-tooltip.js +32 -0
  213. package/directives/focus.js +41 -0
  214. package/directives/int-number.js +21 -0
  215. package/directives/positive-int-number.js +19 -0
  216. package/directives/trim-whitespace.js +19 -0
  217. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +3 -2
  218. package/edit/__tests__/kontainerDriver.test.ts +107 -0
  219. package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +12 -1
  220. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  221. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +2 -3
  222. package/edit/__tests__/nodeDriver.test.ts +107 -0
  223. package/edit/__tests__/service.test.ts +1 -5
  224. package/edit/__tests__/ui.cattle.io.navlink.test.ts +3 -1
  225. package/edit/auth/AuthProviderWarningBanners.vue +34 -0
  226. package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +19 -0
  227. package/edit/auth/__tests__/azuread.test.ts +241 -0
  228. package/edit/auth/__tests__/oidc.test.ts +137 -0
  229. package/edit/auth/azuread.vue +133 -31
  230. package/edit/auth/github.vue +5 -17
  231. package/edit/auth/googleoauth.vue +5 -18
  232. package/edit/auth/ldap/index.vue +5 -17
  233. package/edit/auth/oidc.vue +143 -42
  234. package/edit/auth/saml.vue +5 -14
  235. package/edit/catalog.cattle.io.clusterrepo.vue +175 -20
  236. package/edit/cis.cattle.io.clusterscan.vue +5 -2
  237. package/edit/cis.cattle.io.clusterscanbenchmark.vue +41 -9
  238. package/edit/cloudcredential.vue +26 -4
  239. package/edit/configmap.vue +10 -4
  240. package/edit/fleet.cattle.io.gitrepo.vue +7 -4
  241. package/edit/helm.cattle.io.projecthelmchart.vue +29 -19
  242. package/edit/kontainerDriver.vue +65 -0
  243. package/edit/logging-flow/Match.vue +10 -9
  244. package/edit/logging-flow/index.vue +4 -19
  245. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +232 -2
  246. package/edit/logging.banzaicloud.io.output/index.vue +43 -26
  247. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -3
  248. package/edit/management.cattle.io.project.vue +2 -1
  249. package/edit/management.cattle.io.setting.vue +20 -0
  250. package/edit/management.cattle.io.user.vue +2 -1
  251. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +10 -7
  252. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +21 -16
  253. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +1 -0
  254. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -0
  255. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -0
  256. package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +2 -0
  257. package/edit/monitoring.coreos.com.prometheusrule/index.vue +2 -0
  258. package/edit/networking.k8s.io.ingress/Rules.vue +8 -3
  259. package/edit/networking.k8s.io.ingress/index.vue +64 -8
  260. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -0
  261. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +6 -2
  262. package/edit/networking.k8s.io.networkpolicy/__tests__/{PolicyRuleTarget.spec.ts → PolicyRuleTarget.test.ts} +45 -6
  263. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.test.ts +1 -1
  264. package/edit/networking.k8s.io.networkpolicy/index.vue +2 -0
  265. package/edit/nodeDriver.vue +65 -0
  266. package/edit/persistentvolume/index.vue +2 -2
  267. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +18 -9
  268. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +165 -1
  269. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +1 -1
  270. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +0 -3
  271. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +228 -0
  272. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +70 -12
  273. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +5 -0
  274. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  275. package/edit/provisioning.cattle.io.cluster/index.vue +21 -15
  276. package/edit/provisioning.cattle.io.cluster/rke2.vue +185 -114
  277. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +67 -7
  278. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +19 -6
  279. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +132 -0
  280. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +7 -0
  281. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +1 -0
  282. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +1 -0
  283. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +3 -0
  284. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -0
  285. package/edit/resources.cattle.io.backup.vue +139 -124
  286. package/edit/resources.cattle.io.restore.vue +146 -126
  287. package/edit/service.vue +1 -0
  288. package/edit/serviceaccount.vue +46 -4
  289. package/edit/workload/__tests__/Job.test.ts +1 -3
  290. package/edit/workload/__tests__/Upgrading.test.ts +2 -2
  291. package/edit/workload/mixins/workload.js +34 -1
  292. package/edit/workload/storage/emptyDir.vue +2 -2
  293. package/initialize/App.vue +75 -0
  294. package/initialize/app-extended.js +128 -0
  295. package/initialize/entry-helpers.js +549 -0
  296. package/initialize/entry.js +32 -0
  297. package/initialize/install-components.js +23 -0
  298. package/initialize/install-directives.js +59 -0
  299. package/initialize/install-plugins.js +123 -0
  300. package/list/__tests__/workload.test.ts +1 -1
  301. package/list/cis.cattle.io.clusterscan.vue +16 -10
  302. package/list/group.principal.vue +2 -2
  303. package/list/management.cattle.io.feature.vue +11 -7
  304. package/list/management.cattle.io.user.vue +36 -3
  305. package/list/networking.k8s.io.ingress.vue +36 -0
  306. package/list/node.vue +211 -73
  307. package/list/provisioning.cattle.io.cluster.vue +17 -4
  308. package/list/ui.cattle.io.navlink.vue +2 -2
  309. package/list/workload.vue +22 -0
  310. package/machine-config/__tests__/vmwarevsphere-pool-config-merge.test.ts +30 -0
  311. package/machine-config/__tests__/vmwarevsphere.test.ts +162 -59
  312. package/machine-config/amazonec2.vue +1 -1
  313. package/machine-config/azure.vue +38 -21
  314. package/machine-config/generic.vue +11 -15
  315. package/machine-config/vmwarevsphere-pool-config-merge.ts +25 -0
  316. package/machine-config/vmwarevsphere.vue +20 -11
  317. package/middleware/authenticated.js +9 -361
  318. package/mixins/__tests__/chart.test.ts +48 -6
  319. package/mixins/__tests__/create-edit-view.test.ts +2 -3
  320. package/mixins/auth-config.js +3 -2
  321. package/mixins/brand.js +75 -57
  322. package/mixins/chart.js +27 -13
  323. package/mixins/create-edit-view/index.js +2 -2
  324. package/mixins/fetch.client.js +42 -48
  325. package/mixins/labeled-form-element.ts +21 -1
  326. package/mixins/page-actions.js +7 -5
  327. package/mixins/resource-fetch-api-pagination.js +304 -0
  328. package/mixins/resource-fetch-namespaced.js +1 -1
  329. package/mixins/resource-fetch.js +46 -5
  330. package/models/__tests__/cluster.test.ts +44 -0
  331. package/models/__tests__/fleet.cattle.io.cluster.test.ts +36 -0
  332. package/models/__tests__/schema.tests.ts +24 -0
  333. package/models/__tests__/steve-schema.test.ts +73 -0
  334. package/models/__tests__/workload.test.ts +1 -1
  335. package/models/catalog.cattle.io.app.js +8 -0
  336. package/models/catalog.cattle.io.clusterrepo.js +9 -1
  337. package/models/catalog.cattle.io.uiplugin.js +7 -8
  338. package/models/cis.cattle.io.clusterscan.js +29 -8
  339. package/models/cloudcredential.js +9 -1
  340. package/models/cluster/node.js +4 -0
  341. package/models/cluster/schema.js +6 -0
  342. package/models/cluster.js +33 -0
  343. package/models/driver.js +62 -0
  344. package/models/fleet.cattle.io.cluster.js +23 -11
  345. package/models/fleet.cattle.io.gitrepo.js +10 -0
  346. package/models/helm.cattle.io.projecthelmchart.js +1 -1
  347. package/models/kontainerdriver.js +68 -0
  348. package/models/management/schema.js +6 -0
  349. package/models/management.cattle.io.authconfig.js +3 -2
  350. package/models/management.cattle.io.cluster.js +5 -4
  351. package/models/management.cattle.io.globalrole.js +2 -0
  352. package/models/management.cattle.io.user.js +67 -2
  353. package/models/monitoring.coreos.com.receiver.js +3 -1
  354. package/models/monitoring.coreos.com.route.js +1 -1
  355. package/models/networking.k8s.io.ingress.js +2 -1
  356. package/models/nodedriver.js +68 -0
  357. package/models/provisioning.cattle.io.cluster.js +34 -1
  358. package/models/schema.js +28 -7
  359. package/models/service.js +2 -0
  360. package/models/steve-schema.ts +254 -0
  361. package/models/workload.js +1 -0
  362. package/package.json +6 -5
  363. package/pages/about.vue +12 -5
  364. package/pages/account/index.vue +7 -2
  365. package/pages/auth/login.vue +106 -102
  366. package/pages/auth/logout.vue +2 -2
  367. package/pages/auth/setup.vue +57 -64
  368. package/pages/auth/verify.vue +17 -17
  369. package/pages/c/_cluster/apps/charts/chart.vue +54 -9
  370. package/pages/c/_cluster/apps/charts/index.vue +37 -13
  371. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  372. package/pages/c/_cluster/auth/config/_id.vue +0 -6
  373. package/pages/c/_cluster/auth/config/index.vue +15 -9
  374. package/pages/c/_cluster/auth/roles/index.vue +8 -10
  375. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  376. package/pages/c/_cluster/explorer/ConfigBadge.vue +13 -8
  377. package/pages/c/_cluster/explorer/EventsTable.vue +18 -0
  378. package/pages/c/_cluster/explorer/__tests__/index.test.ts +181 -0
  379. package/pages/c/_cluster/explorer/index.vue +231 -72
  380. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +69 -0
  381. package/pages/c/_cluster/explorer/tools/index.vue +12 -176
  382. package/pages/c/_cluster/fleet/index.vue +88 -93
  383. package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +89 -0
  384. package/pages/c/_cluster/longhorn/index.vue +52 -17
  385. package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -25
  386. package/pages/c/_cluster/manager/drivers/kontainerDriver/_id.vue +12 -0
  387. package/pages/c/_cluster/manager/drivers/kontainerDriver/create.vue +15 -0
  388. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +94 -0
  389. package/pages/c/_cluster/manager/drivers/nodeDriver/_id.vue +12 -0
  390. package/pages/c/_cluster/manager/drivers/nodeDriver/create.vue +15 -0
  391. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +63 -0
  392. package/pages/c/_cluster/manager/jwt.authentication/index.vue +235 -0
  393. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +4 -0
  394. package/pages/c/_cluster/monitoring/index.vue +1 -17
  395. package/pages/c/_cluster/monitoring/route-receiver/index.vue +2 -2
  396. package/pages/c/_cluster/neuvector/index.vue +1 -0
  397. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
  398. package/pages/c/_cluster/settings/banners.vue +86 -8
  399. package/pages/c/_cluster/settings/brand.vue +258 -36
  400. package/pages/c/_cluster/settings/index.vue +4 -4
  401. package/pages/c/_cluster/settings/links.vue +5 -3
  402. package/pages/c/_cluster/settings/performance.vue +71 -2
  403. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +5 -2
  404. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +10 -7
  405. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +9 -6
  406. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +11 -5
  407. package/pages/c/_cluster/uiplugins/InstallDialog.vue +53 -18
  408. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +36 -301
  409. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +14 -6
  410. package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +52 -106
  411. package/pages/c/_cluster/uiplugins/index.vue +38 -52
  412. package/pages/diagnostic.vue +1 -0
  413. package/pages/fail-whale.vue +103 -41
  414. package/pages/home.vue +81 -24
  415. package/pages/prefs.vue +8 -3
  416. package/pages/support/index.vue +12 -2
  417. package/plugins/clean-html-directive.js +5 -12
  418. package/plugins/clean-tooltip-directive.js +6 -31
  419. package/plugins/codemirror.js +0 -9
  420. package/plugins/dashboard-store/__tests__/mutations.test.ts +296 -313
  421. package/plugins/dashboard-store/actions.js +140 -32
  422. package/plugins/dashboard-store/getters.js +86 -39
  423. package/plugins/dashboard-store/index.js +0 -99
  424. package/plugins/dashboard-store/mutations.js +150 -48
  425. package/plugins/dashboard-store/resource-class.js +14 -109
  426. package/plugins/directives.js +6 -39
  427. package/plugins/ember-cookie.js +13 -0
  428. package/plugins/global-formatters.js +26 -5
  429. package/plugins/i18n.js +90 -56
  430. package/plugins/int-number.js +6 -20
  431. package/plugins/plugin.js +3 -3
  432. package/plugins/positive-int-number.js +6 -17
  433. package/plugins/steve/__tests__/{getters.spec.ts → getters.test.ts} +124 -31
  434. package/plugins/steve/__tests__/mutations.test.ts +49 -0
  435. package/plugins/steve/__tests__/subscribe.spec.ts +109 -0
  436. package/plugins/steve/__tests__/utils/mutation.test.helpers.ts +105 -0
  437. package/plugins/steve/accept-or-reject-socket-message.ts +103 -0
  438. package/plugins/steve/actions.js +0 -1
  439. package/plugins/steve/getters.js +183 -63
  440. package/plugins/steve/hybrid-class.js +5 -1
  441. package/plugins/steve/mutations.js +29 -5
  442. package/plugins/steve/norman-class.js +123 -2
  443. package/{utils → plugins/steve}/projectAndNamespaceFiltering.utils.ts +28 -10
  444. package/plugins/steve/schema.d.ts +22 -0
  445. package/plugins/steve/steve-pagination-utils.ts +368 -0
  446. package/plugins/steve/subscribe.js +37 -75
  447. package/plugins/trim-whitespace.js +6 -34
  448. package/plugins/vue-js-modal.js +1 -1
  449. package/public/index.html +1 -0
  450. package/rancher-components/Accordion/Accordion.vue +3 -2
  451. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  452. package/rancher-components/Banner/Banner.test.ts +1 -5
  453. package/rancher-components/Banner/Banner.vue +2 -2
  454. package/rancher-components/Card/Card.vue +4 -4
  455. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  456. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  457. package/rancher-components/Form/LabeledInput/LabeledInput.vue +66 -30
  458. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  459. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  460. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  461. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  462. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  463. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  464. package/rancher-components/StringList/StringList.vue +8 -8
  465. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  466. package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
  467. package/rancher-components/components/Banner/Banner.test.ts +1 -5
  468. package/rancher-components/components/Banner/Banner.vue +2 -2
  469. package/rancher-components/components/Card/Card.vue +4 -4
  470. package/rancher-components/components/Form/Checkbox/Checkbox.vue +4 -3
  471. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  472. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +66 -30
  473. package/rancher-components/components/Form/Radio/RadioButton.test.ts +1 -3
  474. package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
  475. package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
  476. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  477. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  478. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
  479. package/rancher-components/components/StringList/StringList.vue +8 -8
  480. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +27 -8
  481. package/scripts/clean +1 -1
  482. package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +11 -0
  483. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -0
  484. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  485. package/scripts/extension/helm/package/Dockerfile +1 -1
  486. package/scripts/extension/helm/scripts/patch +27 -0
  487. package/scripts/extension/publish +6 -6
  488. package/scripts/serve-pkgs +0 -2
  489. package/scripts/test-plugins-build.sh +6 -6
  490. package/scripts/vue-migrate.js +683 -0
  491. package/store/__tests__/catalog.test.ts +224 -0
  492. package/store/auth.js +23 -4
  493. package/store/aws.js +53 -6
  494. package/store/catalog.js +21 -5
  495. package/store/cru-resource.ts +26 -0
  496. package/store/customisation.js +35 -0
  497. package/store/features.js +6 -4
  498. package/store/index.js +132 -39
  499. package/store/plugins.js +8 -4
  500. package/store/type-map.js +143 -143
  501. package/store/type-map.utils.ts +226 -0
  502. package/tsconfig.json +0 -1
  503. package/tsconfig.paths.json +4 -1
  504. package/types/components/labeledSelect.ts +50 -0
  505. package/types/resources/settings.d.ts +32 -0
  506. package/types/{userPreferences.d.ts → resources/userPreferences.d.ts} +0 -1
  507. package/types/shell/index.d.ts +996 -782
  508. package/types/store/dashboard-store.types.ts +42 -0
  509. package/types/store/pagination.types.ts +457 -0
  510. package/types/store/type-map.ts +30 -0
  511. package/types/store/vuex.d.ts +9 -0
  512. package/types/vue-shim.d.ts +51 -0
  513. package/utils/__tests__/cluster.test.ts +20 -18
  514. package/utils/__tests__/create-yaml.test.ts +359 -2
  515. package/utils/__tests__/kontainer.test.ts +92 -0
  516. package/utils/__tests__/pod-security-admission.test.ts +1 -1
  517. package/utils/alertmanagerconfig.js +19 -0
  518. package/utils/array.ts +40 -1
  519. package/utils/async.ts +2 -0
  520. package/utils/auth.js +152 -4
  521. package/utils/axios.js +2 -2
  522. package/utils/banners.js +103 -0
  523. package/utils/cluster.js +1 -1
  524. package/utils/config.js +4 -0
  525. package/utils/create-yaml.js +54 -27
  526. package/utils/error.js +25 -0
  527. package/utils/formatter.js +5 -3
  528. package/utils/git.ts +1 -1
  529. package/utils/install-redirect.js +1 -1
  530. package/utils/kontainer.ts +186 -0
  531. package/utils/monitoring.js +2 -37
  532. package/utils/pagination-utils.ts +154 -0
  533. package/utils/pod-security-admission.ts +1 -1
  534. package/utils/router.js +86 -0
  535. package/utils/settings.ts +46 -0
  536. package/utils/socket.js +1 -0
  537. package/utils/time.js +1 -0
  538. package/utils/title.ts +3 -0
  539. package/utils/unit-tests/ChildRenderingRouterLinkStub.ts +36 -0
  540. package/utils/validators/formRules/__tests__/index.test.ts +21 -0
  541. package/utils/validators/formRules/index.ts +3 -0
  542. package/utils/validators/index.js +1 -0
  543. package/vue.config.js +376 -421
  544. package/assets/styles/vendor/vue-js-modal.scss +0 -16
  545. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  546. package/components/EventsTable.vue +0 -67
  547. package/components/TabbedLinks/index.vue +0 -94
  548. package/components/nuxt/nuxt-link.server.js +0 -16
  549. package/components/nuxt/nuxt.js +0 -101
  550. package/config/router.js +0 -425
  551. package/initialize/App.js +0 -152
  552. package/initialize/client.js +0 -734
  553. package/initialize/index.js +0 -287
  554. package/middleware/i18n.js +0 -10
  555. package/middleware/unauthenticated.js +0 -22
  556. package/mixins/v1-workload-metrics.js +0 -43
  557. package/pages/c/_cluster/apps/index.vue +0 -15
  558. package/pages/c/_cluster/auth/index.vue +0 -17
  559. package/pages/c/_cluster/index.vue +0 -15
  560. package/pages/c/_cluster/legacy/index.vue +0 -22
  561. package/pages/c/_cluster/manager/index.vue +0 -22
  562. package/pages/c/_cluster/mcapps/index.vue +0 -21
  563. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +0 -232
  564. package/plugins/dashboard-store/rehydrate-all.js +0 -44
  565. package/plugins/index.js +0 -11
  566. package/plugins/portal-vue.js +0 -4
  567. package/plugins/portal.js +0 -4
  568. package/plugins/resize.js +0 -5
  569. package/plugins/shortkey.js +0 -4
  570. package/plugins/tooltip.js +0 -4
  571. package/plugins/v-select.js +0 -4
  572. package/utils/group.js +0 -70
  573. package/utils/nuxt.js +0 -638
  574. package/utils/router.scrollBehavior.js +0 -78
  575. /package/components/__tests__/{Collapse.spec.ts → Collapse.test.ts} +0 -0
  576. /package/models/__tests__/{node.ts → node.test.ts} +0 -0
  577. /package/plugins/steve/__tests__/{header-warnings.spec.ts → header-warnings.test.ts} +0 -0
  578. /package/plugins/steve/__tests__/{steve-class.spec.ts → steve-class.test.ts} +0 -0
  579. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  580. /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  581. /package/types/{pod-security-admission.ts → resources/pod-security-admission.ts} +0 -0
@@ -1,167 +1,362 @@
1
- import { mount, RouterLinkStub } from '@vue/test-utils';
1
+ import { shallowMount, RouterLinkStub, createLocalVue } from '@vue/test-utils';
2
2
  import Type from '@shell/components/nav/Type.vue';
3
+ import { createChildRenderingRouterLinkStub } from '@shell/utils/unit-tests/ChildRenderingRouterLinkStub';
4
+ import { TYPE_MODES } from '@shell/store/type-map';
3
5
 
4
- // Mandatory to mock vue-router in this test
5
- jest.mock('vue-router');
6
-
7
- // Configuration text
8
- const className = 'router-link-active';
6
+ // Configuration
7
+ const activeClass = 'router-link-active';
8
+ const exactActiveClass = 'router-link-exact-active';
9
+ const rootClass = 'root';
10
+ const favoriteClass = 'favorite';
9
11
 
10
12
  describe('component: Type', () => {
11
- describe('should not use highlight class', () => {
12
- it('given no hash', () => {
13
- const wrapper = mount(Type, {
14
- propsData: { type: { route: 'something else' } },
15
- stubs: { nLink: RouterLinkStub },
16
- mocks: {
17
- $route: { path: 'whatever' },
18
- $router: { resolve: () => ({ route: { path: 'whatever' } }) },
19
- $store: {
20
- getters: {
21
- currentStore: () => 'cluster',
22
- 'cluster/count': () => 1,
23
- }
24
- }
25
- },
13
+ describe('testing router-link type', () => {
14
+ const localVue = createLocalVue();
15
+
16
+ localVue.directive('cleanHtml', (identity) => identity);
17
+
18
+ const defaultRouteTypeProp = {
19
+ name: 'route-type',
20
+ route: 'route',
21
+ exact: true,
22
+ mode: TYPE_MODES.FAVORITE
23
+ };
24
+
25
+ const defaultCount = 1;
26
+ const storeMock = {
27
+ getters: {
28
+ currentStore: () => 'cluster',
29
+ 'cluster/count': () => defaultCount,
30
+ }
31
+ };
32
+
33
+ describe('should pass props correctly', () => {
34
+ it('should forward Type props to router-link', () => {
35
+ const wrapper = shallowMount(Type as any, {
36
+ localVue,
37
+ propsData: { type: defaultRouteTypeProp },
38
+ stubs: { routerLink: RouterLinkStub },
39
+ });
40
+
41
+ const linkStub = wrapper.findComponent(RouterLinkStub);
42
+
43
+ expect(linkStub.props().to).toBe(defaultRouteTypeProp.route);
44
+ expect(linkStub.props().exact).toBe(defaultRouteTypeProp.exact);
26
45
  });
27
46
 
28
- const highlight = wrapper.find(`.${ className }`);
47
+ it('should use router-link-slot href prop', () => {
48
+ const fakeHref = 'fake-href';
49
+ const wrapper = shallowMount(Type as any, {
50
+ localVue,
51
+ propsData: { type: defaultRouteTypeProp },
52
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ href: fakeHref }) },
53
+ mocks: { $store: storeMock }
54
+ });
55
+
56
+ const elementWithSelector = wrapper.find(`a[href='${ fakeHref }']`);
29
57
 
30
- expect(highlight.exists()).toBe(false);
58
+ expect(elementWithSelector.exists()).toBe(true);
59
+ });
60
+
61
+ it('should use router-link-slot navigate prop', () => {
62
+ const navigate = jest.fn();
63
+ const wrapper = shallowMount(Type as any, {
64
+ localVue,
65
+ propsData: { type: defaultRouteTypeProp },
66
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isActive: true, navigate }) },
67
+ mocks: { $store: storeMock }
68
+ });
69
+
70
+ const elementWithSelector = wrapper.find(`.${ activeClass }`);
71
+
72
+ elementWithSelector.trigger('click');
73
+
74
+ expect(navigate).toHaveBeenCalledTimes(1);
75
+ });
31
76
  });
32
77
 
33
- it('given no path', () => {
34
- const wrapper = mount(Type, {
35
- propsData: { type: { route: 'something else' } },
36
- stubs: { nLink: RouterLinkStub },
37
- mocks: {
38
- $route: { hash: 'whatever' },
39
- $router: { resolve: () => ({ route: { path: 'whatever' } }) },
40
- $store: {
41
- getters: {
42
- currentStore: () => 'cluster',
43
- 'cluster/count': () => 1,
44
- }
45
- }
46
- },
78
+ describe('should not use classes if preconditions are not met', () => {
79
+ it('should not use active class if the link is not active', () => {
80
+ const wrapper = shallowMount(Type as any, {
81
+ localVue,
82
+ propsData: { type: defaultRouteTypeProp },
83
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isActive: false }) },
84
+ mocks: { $store: storeMock }
85
+ });
86
+
87
+ const elementWithSelector = wrapper.find(`.${ activeClass }`);
88
+
89
+ expect(elementWithSelector.exists()).toBe(false);
47
90
  });
48
91
 
49
- const highlight = wrapper.find(`.${ className }`);
92
+ it('should not use exact active class if the link is not active', () => {
93
+ const wrapper = shallowMount(Type as any, {
94
+ localVue,
95
+ propsData: { type: defaultRouteTypeProp },
96
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isExactActive: false }) },
97
+ mocks: { $store: storeMock }
98
+ });
99
+
100
+ const elementWithSelector = wrapper.find(`.${ exactActiveClass }`);
50
101
 
51
- expect(highlight.exists()).toBe(false);
102
+ expect(elementWithSelector.exists()).toBe(false);
103
+ });
104
+
105
+ it('should not use root class if the isRoot prop is false', () => {
106
+ const wrapper = shallowMount(Type as any, {
107
+ localVue,
108
+ propsData: { type: defaultRouteTypeProp, isRoot: false },
109
+ stubs: { routerLink: createChildRenderingRouterLinkStub() },
110
+ mocks: { $store: storeMock }
111
+ });
112
+
113
+ const elementWithSelector = wrapper.find(`.${ rootClass }`);
114
+
115
+ expect(elementWithSelector.exists()).toBe(false);
116
+ });
52
117
  });
53
118
 
54
- it('given no matching values', () => {
55
- const wrapper = mount(Type, {
56
- propsData: { type: {} },
57
- stubs: { nLink: RouterLinkStub },
58
- mocks: {
59
- $route: {
60
- hash: 'hash',
61
- path: 'path',
62
- },
63
- $router: { resolve: () => ({ route: { path: 'whatever' } }) },
64
- },
119
+ describe('should use classes if preconditions are met', () => {
120
+ it('should use active class if the link is active', () => {
121
+ const wrapper = shallowMount(Type as any, {
122
+ localVue,
123
+ propsData: { type: defaultRouteTypeProp },
124
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isActive: true }) },
125
+ mocks: { $store: storeMock }
126
+ });
127
+
128
+ const elementWithSelector = wrapper.find(`.${ activeClass }`);
129
+
130
+ expect(elementWithSelector.exists()).toBe(true);
131
+ });
132
+
133
+ it('should use exact active class if the link is active', () => {
134
+ const wrapper = shallowMount(Type as any, {
135
+ localVue,
136
+ propsData: { type: defaultRouteTypeProp },
137
+ stubs: { routerLink: createChildRenderingRouterLinkStub({ isExactActive: true }) },
138
+ mocks: { $store: storeMock }
139
+ });
140
+
141
+ const elementWithSelector = wrapper.find(`.${ exactActiveClass }`);
142
+
143
+ expect(elementWithSelector.exists()).toBe(true);
144
+ });
145
+
146
+ it('should use root class if the isRoot prop is true', () => {
147
+ const wrapper = shallowMount(Type as any, {
148
+ localVue,
149
+ propsData: { type: defaultRouteTypeProp, isRoot: true },
150
+ stubs: { routerLink: createChildRenderingRouterLinkStub() },
151
+ mocks: { $store: storeMock }
152
+ });
153
+
154
+ const elementWithSelector = wrapper.find(`.${ rootClass }`);
155
+
156
+ expect(elementWithSelector.exists()).toBe(true);
65
157
  });
66
158
 
67
- const highlight = wrapper.find(`.${ className }`);
159
+ it('should show depth-0 class if depth prop is not defined', () => {
160
+ const wrapper = shallowMount(Type as any, {
161
+ localVue,
162
+ propsData: { type: defaultRouteTypeProp },
163
+ stubs: { routerLink: createChildRenderingRouterLinkStub() },
164
+ mocks: { $store: storeMock }
165
+ });
166
+
167
+ const elementWithSelector = wrapper.find(`.depth-0`);
168
+
169
+ expect(elementWithSelector.exists()).toBe(true);
170
+ });
171
+
172
+ it('should show depth-1 class if depth prop is defined as 1', () => {
173
+ const wrapper = shallowMount(Type as any, {
174
+ localVue,
175
+ propsData: { type: defaultRouteTypeProp, depth: 1 },
176
+ stubs: { routerLink: createChildRenderingRouterLinkStub() },
177
+ mocks: { $store: storeMock }
178
+ });
179
+
180
+ const elementWithSelector = wrapper.find(`.depth-1`);
68
181
 
69
- expect(highlight.exists()).toBe(false);
182
+ expect(elementWithSelector.exists()).toBe(true);
183
+ });
70
184
  });
71
185
 
72
- it('given navigation path is bigger than current page route path', () => {
73
- const wrapper = mount(Type, {
74
- propsData: { type: { route: 'not empty' } },
75
- stubs: { nLink: RouterLinkStub },
76
- mocks: {
77
- $route: {
78
- hash: 'not empty',
79
- path: 'whatever',
186
+ describe('should handle the favorite icon appropriately', () => {
187
+ it('should show favorite icon if mouse is over and type is favorite', async() => {
188
+ const wrapper = shallowMount(Type as any, {
189
+ localVue,
190
+ propsData: { type: defaultRouteTypeProp },
191
+ stubs: {
192
+ routerLink: createChildRenderingRouterLinkStub(),
193
+ Favorite: { template: `<div class=${ favoriteClass } />` }
80
194
  },
81
- $router: { resolve: () => ({ route: { path: 'many/parts' } }) },
82
- $store: {
83
- getters: {
84
- currentStore: () => 'cluster',
85
- 'cluster/count': () => 1,
86
- }
87
- }
88
- },
195
+ mocks: { $store: storeMock }
196
+ });
197
+
198
+ const aElement = wrapper.find(`a`);
199
+
200
+ aElement.trigger('mouseenter');
201
+ await wrapper.vm.$nextTick();
202
+
203
+ const favoriteElement = wrapper.find(`.${ favoriteClass }`);
204
+
205
+ expect(favoriteElement.exists()).toBe(true);
89
206
  });
90
207
 
91
- const highlight = wrapper.find(`.${ className }`);
208
+ it('should not show favorite icon if mouse is not over and type is favorite', async() => {
209
+ const wrapper = shallowMount(Type as any, {
210
+ localVue,
211
+ propsData: { type: defaultRouteTypeProp },
212
+ stubs: {
213
+ routerLink: createChildRenderingRouterLinkStub(),
214
+ Favorite: { template: `<div class=${ favoriteClass } />` }
215
+ },
216
+ mocks: { $store: storeMock }
217
+ });
218
+
219
+ const favoriteElement = wrapper.find(`.${ favoriteClass }`);
220
+
221
+ expect(favoriteElement.exists()).toBe(false);
222
+ });
92
223
 
93
- expect(highlight.exists()).toBe(false);
224
+ it('should not show favorite icon if mouse is over and type is not favorite', async() => {
225
+ const wrapper = shallowMount(Type as any, {
226
+ localVue,
227
+ propsData: { type: { ...defaultRouteTypeProp, mode: null } },
228
+ stubs: {
229
+ routerLink: createChildRenderingRouterLinkStub(),
230
+ Favorite: { template: `<div class=${ favoriteClass } />` }
231
+ },
232
+ mocks: { $store: storeMock }
233
+ });
234
+
235
+ const aElement = wrapper.find(`a`);
236
+
237
+ aElement.trigger('mouseenter');
238
+ await wrapper.vm.$nextTick();
239
+
240
+ const favoriteElement = wrapper.find(`.${ favoriteClass }`);
241
+
242
+ expect(favoriteElement.exists()).toBe(false);
243
+ });
94
244
  });
95
245
 
96
- it.each([
97
- // URL with fragments like anchors
98
- [
99
- '/c/c-m-hzqf4tqt/explorer/members#project-membership',
100
- '/c/c-m-hzqf4tqt/explorer/members'
101
- ],
102
- // Similar paths
103
- [
104
- '/c/c-m-hzqf4tqt/fleet/fleet.cattle.io.bundlenamespacemapping',
105
- '/c/c-m-hzqf4tqt/fleet/fleet.cattle.io.bundle'
106
- ],
107
- // paths with same parts, e.g. parents
108
- [
109
- '/c/c-m-hzqf4tqt/fleet',
110
- '/c/c-m-hzqf4tqt/fleet/management.cattle.io.fleetworkspace'
111
- ],
112
- ])('given different current path %p and menu path %p', (currentPath, menuPath) => {
113
- const wrapper = mount(Type, {
114
- propsData: { type: { route: 'not empty' } },
115
- stubs: { nLink: RouterLinkStub },
116
- mocks: {
117
- $route: {
118
- hash: 'not empty',
119
- path: currentPath,
246
+ describe('should handle count appropriately', () => {
247
+ it('should show count if on type', async() => {
248
+ const count = 2;
249
+ const wrapper = shallowMount(Type as any, {
250
+ localVue,
251
+ propsData: { type: { ...defaultRouteTypeProp, count } },
252
+ stubs: {
253
+ routerLink: createChildRenderingRouterLinkStub(),
254
+ Favorite: { template: `<div class=${ favoriteClass } />` }
255
+ },
256
+ mocks: { $store: storeMock }
257
+ });
258
+
259
+ const typeCount = wrapper.find(`span[data-testid="type-count"]`);
260
+
261
+ expect(Number.parseInt(typeCount.text())).toBe(count);
262
+ });
263
+
264
+ it('should show count if in store', async() => {
265
+ const wrapper = shallowMount(Type as any, {
266
+ localVue,
267
+ propsData: { type: defaultRouteTypeProp },
268
+ stubs: {
269
+ routerLink: createChildRenderingRouterLinkStub(),
270
+ Favorite: { template: `<div class=${ favoriteClass } />` }
120
271
  },
121
- $router: { resolve: () => ({ route: { path: menuPath } }) },
122
- $store: {
123
- getters: {
124
- currentStore: () => 'cluster',
125
- 'cluster/count': () => 1,
272
+ mocks: { $store: storeMock }
273
+ });
274
+
275
+ const typeCount = wrapper.find(`span[data-testid="type-count"]`);
276
+
277
+ expect(Number.parseInt(typeCount.text())).toBe(defaultCount);
278
+ });
279
+
280
+ it('should not show count if not in type or store', async() => {
281
+ const wrapper = shallowMount(Type as any, {
282
+ localVue,
283
+ propsData: { type: defaultRouteTypeProp },
284
+ stubs: {
285
+ routerLink: createChildRenderingRouterLinkStub(),
286
+ Favorite: { template: `<div class=${ favoriteClass } />` }
287
+ },
288
+ mocks: {
289
+
290
+ $store: {
291
+ getters: {
292
+ currentStore: () => 'cluster',
293
+ 'cluster/count': () => null,
294
+ }
126
295
  }
127
296
  }
128
- },
297
+ });
298
+
299
+ const typeCount = wrapper.find(`span[data-testid="type-count"]`);
300
+
301
+ expect(typeCount.exists()).toBe(false);
302
+ });
303
+ });
304
+
305
+ describe('should handle namespace appropriately', () => {
306
+ it('should show namespace if on type', async() => {
307
+ const wrapper = shallowMount(Type as any, {
308
+ localVue,
309
+ propsData: { type: { ...defaultRouteTypeProp, namespaced: true } },
310
+ stubs: {
311
+ routerLink: createChildRenderingRouterLinkStub(),
312
+ Favorite: { template: `<div class=${ favoriteClass } />` }
313
+ },
314
+ mocks: { $store: storeMock }
315
+ });
316
+
317
+ const namespaced = wrapper.find(`i[data-testid="type-namespaced"]`);
318
+
319
+ expect(namespaced.exists()).toBe(true);
129
320
  });
130
321
 
131
- const highlight = wrapper.find(`.${ className }`);
322
+ it('should not show namespace if not on type', async() => {
323
+ const wrapper = shallowMount(Type as any, {
324
+ localVue,
325
+ propsData: { type: { ...defaultRouteTypeProp, namespaced: false } },
326
+ stubs: {
327
+ routerLink: createChildRenderingRouterLinkStub(),
328
+ Favorite: { template: `<div class=${ favoriteClass } />` }
329
+ },
330
+ mocks: { $store: storeMock }
331
+ });
332
+
333
+ const namespaced = wrapper.find(`i[data-testid="type-namespaced"]`);
132
334
 
133
- expect(highlight.exists()).toBe(false);
335
+ expect(namespaced.exists()).toBe(false);
336
+ });
134
337
  });
135
338
  });
136
339
 
137
- describe('should use highlight class', () => {
138
- it.each([
139
- [
140
- 'same',
141
- 'same'
142
- ],
143
- ])('given same current path %p and menu path %p (on first load)', (currentPath, menuPath) => {
144
- const wrapper = mount(Type, {
145
- propsData: { type: { route: 'not empty' } },
146
- stubs: { nLink: RouterLinkStub },
147
- mocks: {
148
- $route: {
149
- hash: 'not empty',
150
- path: currentPath,
151
- },
152
- $router: { resolve: () => ({ route: { path: menuPath } }) },
153
- $store: {
154
- getters: {
155
- currentStore: () => 'cluster',
156
- 'cluster/count': () => 1,
157
- }
158
- }
340
+ describe('testing link type', () => {
341
+ it('should show the link type element if link is present on type with the specified label and target', () => {
342
+ const defaultLinkTypeProp = {
343
+ link: 'link-type-link',
344
+ label: 'link-type-label',
345
+ target: 'link-type-target'
346
+ };
347
+
348
+ const wrapper = shallowMount(Type as any, {
349
+ propsData: { type: defaultLinkTypeProp },
350
+ stubs: {
351
+ routerLink: createChildRenderingRouterLinkStub(),
352
+ Favorite: { template: `<div class=${ favoriteClass } />` }
159
353
  },
160
354
  });
161
355
 
162
- const highlight = wrapper.find(`.${ className }`);
356
+ const link = wrapper.find(`li[data-testid="link-type"]`);
163
357
 
164
- expect(highlight.exists()).toBe(true);
358
+ expect(link.text()).toBe(defaultLinkTypeProp.label);
359
+ expect(link.find('a').attributes('target')).toBe(defaultLinkTypeProp.target);
165
360
  });
166
361
  });
167
362
  });
@@ -30,13 +30,8 @@ export default {
30
30
 
31
31
  const listeners = {}
32
32
 
33
- // Add triggerScroll event on beforeEnter (fix #1376)
34
33
  const beforeEnter = listeners.beforeEnter
35
34
  listeners.beforeEnter = (el) => {
36
- // Ensure to trigger scroll event after calling scrollBehavior
37
- window.$nuxt.$nextTick(() => {
38
- window.$nuxt.$emit('triggerScroll')
39
- })
40
35
  if (beforeEnter) {
41
36
  return beforeEnter.call(_parent, el)
42
37
  }
@@ -8,7 +8,7 @@
8
8
  <div class="title">{{ message }}</div>
9
9
  <p v-if="statusCode === 404" class="description">
10
10
  <a v-if="typeof $route === 'undefined'" class="error-link" href="/"></a>
11
- <NuxtLink v-else class="error-link" to="/">Back to the home page</NuxtLink>
11
+ <router-link v-else class="error-link" to="/">Back to the home page</router-link>
12
12
  </p>
13
13
 
14
14
  <p class="description" v-else>An error occurred while rendering the page. Check developer tools console for details.</p>
@@ -1,98 +1,16 @@
1
- import Vue from 'vue'
2
-
3
- const requestIdleCallback = window.requestIdleCallback ||
4
- function (cb) {
5
- const start = Date.now()
6
- return setTimeout(function () {
7
- cb({
8
- didTimeout: false,
9
- timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
10
- })
11
- }, 1)
12
- }
13
-
14
- const cancelIdleCallback = window.cancelIdleCallback || function (id) {
15
- clearTimeout(id)
16
- }
17
-
18
- const observer = window.IntersectionObserver && new window.IntersectionObserver((entries) => {
19
- entries.forEach(({ intersectionRatio, target: link }) => {
20
- if (intersectionRatio <= 0 || !link.__prefetch) {
21
- return
22
- }
23
- link.__prefetch()
24
- })
25
- })
26
-
27
- export default {
28
- name: 'NuxtLink',
29
- extends: Vue.component('RouterLink'),
30
- props: {
31
- prefetch: {
32
- type: Boolean,
33
- default: false
34
- },
35
- noPrefetch: {
36
- type: Boolean,
37
- default: false
38
- }
39
- },
40
- mounted () {
41
- if (this.prefetch && !this.noPrefetch) {
42
- this.handleId = requestIdleCallback(this.observe, { timeout: 2e3 })
43
- }
44
- },
45
- beforeDestroy () {
46
- cancelIdleCallback(this.handleId)
47
-
48
- if (this.__observed) {
49
- observer.unobserve(this.$el)
50
- delete this.$el.__prefetch
51
- }
52
- },
53
- methods: {
54
- observe () {
55
- // If no IntersectionObserver, avoid prefetching
56
- if (!observer) {
57
- return
58
- }
59
- // Add to observer
60
- if (this.shouldPrefetch()) {
61
- this.$el.__prefetch = this.prefetchLink.bind(this)
62
- observer.observe(this.$el)
63
- this.__observed = true
64
- }
65
- },
66
- shouldPrefetch () {
67
- return this.getPrefetchComponents().length > 0
68
- },
69
- canPrefetch () {
70
- const conn = navigator.connection
71
- const hasBadConnection = this.$nuxt.isOffline || (conn && ((conn.effectiveType || '').includes('2g') || conn.saveData))
72
-
73
- return !hasBadConnection
74
- },
75
- getPrefetchComponents () {
76
- const ref = this.$router.resolve(this.to, this.$route, this.append)
77
- const Components = ref.resolved.matched.map(r => r.components.default)
78
-
79
- return Components.filter(Component => typeof Component === 'function' && !Component.options && !Component.__prefetched)
80
- },
81
- prefetchLink () {
82
- if (!this.canPrefetch()) {
83
- return
84
- }
85
- // Stop observing this link (in case of internet connection changes)
86
- observer.unobserve(this.$el)
87
- const Components = this.getPrefetchComponents()
88
-
89
- for (const Component of Components) {
90
- const componentOrPromise = Component()
91
- if (componentOrPromise instanceof Promise) {
92
- componentOrPromise.catch(() => {})
93
- }
94
- Component.__prefetched = true
95
- }
1
+ // TODO: #9541 Remove for Vue 3 migration
2
+ /**
3
+ * Prints a deprecation warning for any extensions that might be using NuxtLink
4
+ * @param {string} aliasName The alias that will print the deprecation warning
5
+ * @returns Functional component that prints a deprecation warning and renders a
6
+ * `router-link` instead
7
+ */
8
+ export const nuxtLinkAlias = (aliasName) => {
9
+ return {
10
+ functional: true,
11
+ render(createElement, context) {
12
+ console.warn(`${aliasName} is deprecated in Rancher Dashboard. Use 'router-link' instead.`);
13
+ return createElement('router-link', context.data, context.children);
96
14
  }
97
15
  }
98
16
  }
@@ -24,7 +24,7 @@ import isEqual from 'lodash/isEqual';
24
24
  import { markSeenReleaseNotes } from '@shell/utils/version';
25
25
  import PageHeaderActions from '@shell/mixins/page-actions';
26
26
  import BrowserTabVisibility from '@shell/mixins/browser-tab-visibility';
27
- import { getClusterFromRoute, getProductFromRoute } from '@shell/middleware/authenticated';
27
+ import { getClusterFromRoute, getProductFromRoute } from '@shell/utils/router';
28
28
  import { BOTTOM } from '@shell/utils/position';
29
29
  import SideNav from '@shell/components/SideNav';
30
30
  import { BLANK_CLUSTER } from '@shell/store/store-types.js';
@@ -70,7 +70,7 @@ export default {
70
70
 
71
71
  computed: {
72
72
  ...mapState(['managementReady', 'clusterReady']),
73
- ...mapGetters(['clusterId', 'currentProduct', 'isRancherInHarvester', 'showTopLevelMenu']),
73
+ ...mapGetters(['clusterId', 'currentProduct', 'rootProduct', 'isRancherInHarvester', 'showTopLevelMenu']),
74
74
 
75
75
  afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
76
76
 
@@ -78,7 +78,7 @@ export default {
78
78
 
79
79
  pageActions() {
80
80
  const pageActions = [];
81
- const product = this.currentProduct;
81
+ const product = this.rootProduct;
82
82
 
83
83
  if ( !product ) {
84
84
  return [];