dashboard-shell-shell 3.0.2-test.20250913 → 3.0.5-test.2

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 (628) hide show
  1. package/assets/data/aws-regions.json +3 -0
  2. package/assets/icons/demo.css:Zone.Identifier +0 -0
  3. package/assets/icons/demo_index.html:Zone.Identifier +0 -0
  4. package/assets/icons/iconfont.css:Zone.Identifier +0 -0
  5. package/assets/icons/iconfont.js:Zone.Identifier +0 -0
  6. package/assets/icons/iconfont.json:Zone.Identifier +0 -0
  7. package/assets/icons/iconfont.ttf:Zone.Identifier +0 -0
  8. package/assets/icons/iconfont.woff2:Zone.Identifier +0 -0
  9. package/assets/icons/iconfont.woff:Zone.Identifier +0 -0
  10. package/assets/images/icons/document.svg +3 -0
  11. package/assets/images/key.svg +17 -0
  12. package/assets/images/providers/sks.svg +1 -0
  13. package/assets/images/vendor/cognito.svg +1 -0
  14. package/assets/styles/app.scss +3 -0
  15. package/assets/styles/base/_basic.scss +10 -0
  16. package/assets/styles/base/_spacing.scss +29 -0
  17. package/assets/styles/base/_variables.scss +16 -10
  18. package/assets/styles/global/_labeled-input.scss +1 -1
  19. package/assets/styles/global/_layout.scss +1 -1
  20. package/assets/styles/themes/_dark.scss +30 -0
  21. package/assets/styles/themes/_light.scss +80 -2
  22. package/assets/translations/en-us.yaml +822 -105
  23. package/assets/translations/zh-hans.yaml +13 -3
  24. package/chart/__tests__/S3.test.ts +2 -1
  25. package/chart/monitoring/index.vue +1 -1
  26. package/cloud-credential/gcp.vue +9 -1
  27. package/components/ActionMenuShell.vue +3 -7
  28. package/components/AppModal.vue +9 -28
  29. package/components/AsyncButton.vue +2 -0
  30. package/components/BrandImage.vue +0 -21
  31. package/components/Certificates.vue +5 -0
  32. package/components/CodeMirror.vue +3 -3
  33. package/components/CommunityLinks.vue +3 -58
  34. package/components/ConfigMapSettings/Settings.vue +377 -0
  35. package/components/ConfigMapSettings/index.vue +354 -0
  36. package/components/CruResource.vue +103 -16
  37. package/components/DetailText.vue +61 -11
  38. package/components/Drawer/Chrome.vue +115 -0
  39. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  40. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  41. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  42. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  43. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +106 -0
  44. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  45. package/components/Drawer/ResourceDetailDrawer/composables.ts +53 -0
  46. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  47. package/components/Drawer/ResourceDetailDrawer/index.vue +123 -0
  48. package/components/ExplorerProjectsNamespaces.vue +46 -29
  49. package/components/FilterPanel.vue +156 -0
  50. package/components/FixedBanner.vue +19 -5
  51. package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
  52. package/components/GrowlManager.vue +16 -15
  53. package/components/IconOrSvg.vue +19 -35
  54. package/components/KeyValueView.vue +1 -1
  55. package/components/LandingPagePreference.vue +2 -0
  56. package/components/Loading.vue +1 -1
  57. package/components/LocaleSelector.vue +10 -2
  58. package/components/PaginatedResourceTable.vue +53 -1
  59. package/components/ProgressBarMulti.vue +1 -0
  60. package/components/PromptModal.vue +38 -7
  61. package/components/PromptRemove.vue +5 -1
  62. package/components/PromptRestore.vue +22 -44
  63. package/components/RelatedResources.vue +4 -12
  64. package/components/Resource/Detail/Additional.vue +46 -0
  65. package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
  66. package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
  67. package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
  68. package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
  69. package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
  70. package/components/Resource/Detail/Card/Scaler.vue +89 -0
  71. package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
  72. package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
  73. package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
  74. package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
  75. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
  76. package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
  77. package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
  78. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
  79. package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
  80. package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
  81. package/components/Resource/Detail/Card/index.vue +56 -0
  82. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
  83. package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
  84. package/components/Resource/Detail/Metadata/Annotations/index.vue +31 -0
  85. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  86. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
  87. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +72 -0
  88. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +317 -0
  89. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +140 -0
  90. package/components/Resource/Detail/Metadata/KeyValue.vue +140 -0
  91. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
  92. package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
  93. package/components/Resource/Detail/Metadata/Labels/index.vue +31 -0
  94. package/components/Resource/Detail/Metadata/Rectangle.vue +34 -0
  95. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
  96. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
  97. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  98. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
  99. package/components/Resource/Detail/Metadata/composables.ts +81 -0
  100. package/components/Resource/Detail/Metadata/index.vue +88 -0
  101. package/components/Resource/Detail/Page.vue +37 -0
  102. package/components/Resource/Detail/PercentageBar.vue +40 -0
  103. package/components/Resource/Detail/ResourceRow.vue +138 -0
  104. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  105. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  106. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  107. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  108. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  109. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  110. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  111. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  112. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  113. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  114. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  115. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  116. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  117. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  118. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  119. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  120. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  121. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  122. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  123. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  124. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  125. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  126. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  127. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  128. package/components/Resource/Detail/SpacedRow.vue +14 -0
  129. package/components/Resource/Detail/StatusBar.vue +59 -0
  130. package/components/Resource/Detail/StatusRow.vue +61 -0
  131. package/components/Resource/Detail/TitleBar/Title.vue +14 -0
  132. package/components/Resource/Detail/TitleBar/Top.vue +14 -0
  133. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
  134. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
  135. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  136. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
  137. package/components/Resource/Detail/TitleBar/composables.ts +46 -0
  138. package/components/Resource/Detail/TitleBar/index.vue +204 -0
  139. package/components/Resource/Detail/Top/index.vue +34 -0
  140. package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
  141. package/components/Resource/Detail/composables.ts +45 -0
  142. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  143. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  144. package/components/ResourceDetail/Masthead/index.vue +65 -0
  145. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  146. package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -1
  147. package/components/ResourceDetail/__tests__/index.test.ts +135 -0
  148. package/components/ResourceDetail/index.vue +75 -575
  149. package/components/ResourceDetail/legacy.vue +564 -0
  150. package/components/ResourceList/Masthead.vue +69 -20
  151. package/components/ResourceList/index.vue +3 -2
  152. package/components/ResourceTable.vue +59 -85
  153. package/components/ResourceYaml.vue +15 -2
  154. package/components/RichTranslation.vue +106 -0
  155. package/components/SlideInPanelManager.vue +116 -14
  156. package/components/SortableTable/index.vue +10 -2
  157. package/components/SortableTable/paging.js +15 -16
  158. package/components/SortableTable/selection.js +22 -10
  159. package/components/StateDot/index.vue +28 -0
  160. package/components/StatusBadge.vue +6 -4
  161. package/components/SubtleLink.vue +25 -0
  162. package/components/Tabbed/index.vue +38 -22
  163. package/components/Wizard.vue +16 -3
  164. package/components/YamlEditor.vue +1 -2
  165. package/components/__tests__/AsyncButton.test.ts +39 -0
  166. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  167. package/components/__tests__/CruResource.test.ts +63 -0
  168. package/components/__tests__/FilterPanel.test.ts +81 -0
  169. package/components/__tests__/GrowlManager.test.ts +0 -25
  170. package/components/__tests__/PromptModal.test.ts +146 -0
  171. package/components/__tests__/PromptRestore.test.ts +1 -65
  172. package/components/__tests__/RichTranslation.test.ts +115 -0
  173. package/components/auth/AuthBanner.vue +15 -14
  174. package/components/auth/Principal.vue +0 -1
  175. package/components/auth/RoleDetailEdit.vue +44 -4
  176. package/components/auth/login/ldap.vue +2 -2
  177. package/components/auth/login/oidc.vue +6 -1
  178. package/components/fleet/FleetApplications.vue +174 -0
  179. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  180. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  181. package/components/fleet/FleetClusters.vue +25 -6
  182. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  183. package/components/fleet/FleetHelmOps.vue +123 -0
  184. package/components/fleet/FleetIntro.vue +58 -28
  185. package/components/fleet/FleetNoWorkspaces.vue +5 -1
  186. package/components/fleet/FleetOCIStorageSecret.vue +171 -0
  187. package/components/fleet/FleetRepos.vue +37 -80
  188. package/components/fleet/FleetResources.vue +69 -27
  189. package/components/fleet/FleetSummary.vue +26 -51
  190. package/components/fleet/FleetValuesFrom.vue +295 -0
  191. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  192. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  193. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
  194. package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
  195. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  196. package/components/fleet/dashboard/Empty.vue +73 -0
  197. package/components/fleet/dashboard/ResourceCard.vue +184 -0
  198. package/components/fleet/dashboard/ResourceCardSummary.vue +195 -0
  199. package/components/fleet/dashboard/ResourceDetails.vue +194 -0
  200. package/components/fleet/dashboard/ResourcePanel.vue +384 -0
  201. package/components/form/ArrayList.vue +144 -116
  202. package/components/form/BannerSettings.vue +117 -50
  203. package/components/form/ChangePassword.vue +3 -1
  204. package/components/form/ColorInput.vue +35 -6
  205. package/components/form/FileImageSelector.vue +1 -1
  206. package/components/form/Footer.vue +10 -4
  207. package/components/form/KeyValue.vue +92 -51
  208. package/components/form/LabeledSelect.vue +72 -54
  209. package/components/form/Labels.vue +91 -21
  210. package/components/form/MatchExpressions.vue +56 -9
  211. package/components/form/NameNsDescription.vue +12 -8
  212. package/components/form/Networking.vue +24 -19
  213. package/components/form/NotificationSettings.vue +15 -1
  214. package/components/form/ResourceLabeledSelect.vue +22 -8
  215. package/components/form/ResourceSelector.vue +27 -23
  216. package/components/form/ResourceTabs/index.vue +7 -1
  217. package/components/form/SSHKnownHosts/index.vue +14 -11
  218. package/components/form/SecretSelector.vue +18 -2
  219. package/components/form/Select.vue +57 -26
  220. package/components/form/SelectOrCreateAuthSecret.vue +6 -3
  221. package/components/form/SimpleSecretSelector.vue +17 -4
  222. package/components/form/Taints.vue +21 -2
  223. package/components/form/UnitInput.vue +21 -0
  224. package/components/form/ValueFromResource.vue +31 -19
  225. package/components/form/__tests__/ArrayList.test.ts +32 -0
  226. package/components/form/__tests__/ColorInput.test.ts +35 -0
  227. package/components/form/__tests__/KeyValue.test.ts +36 -0
  228. package/components/form/__tests__/LabeledSelect.test.ts +79 -2
  229. package/components/form/__tests__/Labels.test.ts +360 -0
  230. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  231. package/components/form/__tests__/Networking.test.ts +116 -0
  232. package/components/form/__tests__/SSHKnownHosts.test.ts +11 -2
  233. package/components/form/__tests__/Select.test.ts +37 -1
  234. package/components/form/__tests__/UnitInput.test.ts +23 -1
  235. package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
  236. package/components/formatter/ClusterLink.vue +5 -8
  237. package/components/formatter/Description.vue +30 -0
  238. package/components/formatter/FleetApplicationClustersReady.vue +77 -0
  239. package/components/formatter/FleetApplicationSource.vue +79 -0
  240. package/components/formatter/FleetSummaryGraph.vue +7 -0
  241. package/components/formatter/PodImages.vue +1 -1
  242. package/components/formatter/WorkloadHealthScale.vue +1 -1
  243. package/components/formatter/__tests__/ClusterLink.test.ts +2 -32
  244. package/components/formatter/__tests__/LiveDate.test.ts +10 -2
  245. package/components/google/AccountAccess.vue +209 -0
  246. package/components/google/types/gcp.d.ts +136 -0
  247. package/components/google/types/index.d.ts +101 -0
  248. package/components/google/util/__mocks__/gcp.ts +465 -0
  249. package/components/google/util/formatter.ts +82 -0
  250. package/components/google/util/gcp.ts +134 -0
  251. package/components/google/util/index.d.ts +11 -0
  252. package/components/nav/Favorite.vue +1 -1
  253. package/components/nav/Group.vue +5 -0
  254. package/components/nav/Header.vue +24 -38
  255. package/components/nav/NamespaceFilter.vue +141 -84
  256. package/components/nav/NotificationCenter/Notification.vue +484 -0
  257. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  258. package/components/nav/NotificationCenter/index.vue +148 -0
  259. package/components/nav/TopLevelMenu.helper.ts +55 -34
  260. package/components/nav/TopLevelMenu.vue +11 -0
  261. package/components/nav/Type.vue +4 -1
  262. package/components/nav/WindowManager/ContainerLogs.vue +87 -61
  263. package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
  264. package/components/nav/WindowManager/index.vue +3 -2
  265. package/components/templates/default.vue +0 -3
  266. package/components/templates/plain.vue +0 -3
  267. package/composables/drawer.ts +26 -0
  268. package/composables/focusTrap.ts +3 -3
  269. package/composables/resources.test.ts +63 -0
  270. package/composables/resources.ts +38 -0
  271. package/composables/useI18n.ts +12 -11
  272. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  273. package/config/labels-annotations.js +22 -11
  274. package/config/pagination-table-headers.js +8 -1
  275. package/config/private-label.js +0 -1
  276. package/config/product/auth.js +20 -3
  277. package/config/product/{cis.js → compliance.js} +23 -26
  278. package/config/product/explorer.js +49 -17
  279. package/config/product/fleet.js +77 -17
  280. package/config/product/manager.js +1 -29
  281. package/config/product/settings.js +23 -11
  282. package/config/query-params.js +16 -1
  283. package/config/roles.ts +2 -1
  284. package/config/router/navigation-guards/authentication.js +51 -2
  285. package/config/router/navigation-guards/index.js +5 -67
  286. package/config/router/routes.js +65 -31
  287. package/config/secret.ts +15 -0
  288. package/config/settings.ts +33 -16
  289. package/config/store.js +2 -0
  290. package/config/system-namespaces.js +1 -1
  291. package/config/table-headers.js +91 -30
  292. package/config/types.js +18 -7
  293. package/config/version.js +1 -1
  294. package/core/plugin-helpers.ts +3 -2
  295. package/core/plugin.ts +32 -7
  296. package/core/types.ts +25 -7
  297. package/detail/catalog.cattle.io.app.vue +5 -1
  298. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  299. package/detail/fleet.cattle.io.bundle.vue +70 -6
  300. package/detail/fleet.cattle.io.cluster.vue +28 -15
  301. package/detail/fleet.cattle.io.gitrepo.vue +11 -2
  302. package/detail/fleet.cattle.io.helmop.vue +157 -0
  303. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  304. package/detail/management.cattle.io.oidcclient.vue +369 -0
  305. package/detail/namespace.vue +0 -3
  306. package/detail/node.vue +20 -16
  307. package/detail/pod.vue +2 -2
  308. package/detail/provisioning.cattle.io.cluster.vue +16 -50
  309. package/detail/service.vue +10 -2
  310. package/detail/workload/index.vue +48 -39
  311. package/dialog/AddCustomBadgeDialog.vue +0 -1
  312. package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
  313. package/dialog/AddonConfigConfirmationDialog.vue +1 -1
  314. package/dialog/AssignToDialog.vue +176 -0
  315. package/dialog/ChangePasswordDialog.vue +106 -0
  316. package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
  317. package/dialog/DisableAuthProviderDialog.vue +101 -0
  318. package/dialog/DrainNode.vue +1 -1
  319. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
  320. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +87 -66
  321. package/dialog/FeatureFlagListDialog.vue +288 -0
  322. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  323. package/dialog/GenericPrompt.vue +1 -1
  324. package/dialog/HelmOpForceUpdateDialog.vue +132 -0
  325. package/{components/Import.vue → dialog/ImportDialog.vue} +8 -13
  326. package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
  327. package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -62
  328. package/dialog/MoveNamespaceDialog.vue +157 -0
  329. package/dialog/OidcClientSecretDialog.vue +117 -0
  330. package/dialog/RedeployWorkloadDialog.vue +164 -0
  331. package/dialog/RotateEncryptionKeyDialog.vue +10 -30
  332. package/dialog/ScalePoolDownDialog.vue +1 -1
  333. package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
  334. package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
  335. package/dialog/WechatDialog.vue +57 -0
  336. package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +15 -34
  337. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  338. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +60 -68
  339. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  340. package/edit/__tests__/service.test.ts +2 -1
  341. package/edit/auth/ldap/__tests__/config.test.ts +14 -0
  342. package/edit/auth/ldap/config.vue +24 -0
  343. package/edit/auth/oidc.vue +159 -93
  344. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  345. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  346. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  347. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  348. package/edit/configmap.vue +8 -2
  349. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  350. package/edit/fleet.cattle.io.gitrepo.vue +70 -256
  351. package/edit/fleet.cattle.io.helmop.vue +786 -0
  352. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  353. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  354. package/edit/logging-flow/index.vue +1 -0
  355. package/edit/logging.banzaicloud.io.output/index.vue +2 -1
  356. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
  357. package/edit/management.cattle.io.fleetworkspace.vue +44 -10
  358. package/edit/management.cattle.io.oidcclient.vue +162 -0
  359. package/edit/management.cattle.io.project.vue +4 -1
  360. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  361. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  362. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  363. package/edit/monitoring.coreos.com.receiver/auth.vue +3 -3
  364. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  365. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  366. package/edit/monitoring.coreos.com.route.vue +1 -0
  367. package/edit/namespace.vue +2 -4
  368. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  369. package/edit/networking.k8s.io.ingress/Certificate.vue +11 -3
  370. package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +37 -0
  371. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  372. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -14
  373. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +57 -62
  374. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +10 -16
  375. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.test.ts +72 -41
  376. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +17 -1
  377. package/edit/networking.k8s.io.networkpolicy/index.vue +23 -31
  378. package/edit/node.vue +1 -0
  379. package/edit/persistentvolume/index.vue +4 -1
  380. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
  381. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +69 -2
  382. package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
  383. package/edit/provisioning.cattle.io.cluster/index.vue +21 -73
  384. package/edit/provisioning.cattle.io.cluster/rke2.vue +535 -428
  385. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +48 -39
  386. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
  387. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  388. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -2
  389. package/edit/resources.cattle.io.restore.vue +1 -1
  390. package/edit/secret/basic.vue +1 -0
  391. package/edit/secret/index.vue +127 -15
  392. package/edit/service.vue +17 -29
  393. package/edit/serviceaccount.vue +4 -1
  394. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  395. package/edit/workload/index.vue +11 -15
  396. package/edit/workload/mixins/workload.js +0 -2
  397. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  398. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  399. package/list/fleet.cattle.io.helmop.vue +108 -0
  400. package/list/harvesterhci.io.management.cluster.vue +0 -17
  401. package/list/management.cattle.io.feature.vue +4 -288
  402. package/list/management.cattle.io.oidcclient.vue +108 -0
  403. package/list/management.cattle.io.user.vue +13 -20
  404. package/list/namespace.vue +6 -2
  405. package/list/node.vue +2 -0
  406. package/list/projectsecret.vue +345 -0
  407. package/list/secret.vue +109 -0
  408. package/list/workload.vue +6 -2
  409. package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
  410. package/machine-config/amazonec2.vue +3 -24
  411. package/machine-config/components/GCEImage.vue +374 -0
  412. package/machine-config/google.vue +617 -0
  413. package/machine-config/vmwarevsphere.vue +7 -17
  414. package/mixins/__tests__/brand.spec.ts +170 -0
  415. package/mixins/auth-config.js +8 -1
  416. package/mixins/brand.js +16 -17
  417. package/mixins/create-edit-view/impl.js +10 -1
  418. package/mixins/create-edit-view/index.js +5 -0
  419. package/mixins/preset.js +100 -0
  420. package/mixins/resource-fetch-api-pagination.js +73 -44
  421. package/mixins/resource-fetch.js +18 -8
  422. package/mixins/resource-table-watch.js +45 -0
  423. package/mixins/vue-select-overrides.js +1 -4
  424. package/models/__tests__/chart.test.ts +296 -0
  425. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
  426. package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  427. package/models/__tests__/node.test.ts +7 -63
  428. package/models/__tests__/workload.test.ts +1 -0
  429. package/models/chart.js +157 -2
  430. package/models/cluster/node.js +2 -1
  431. package/models/cluster.js +32 -2
  432. package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
  433. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  434. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  435. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  436. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  437. package/models/fleet-application.js +297 -0
  438. package/models/fleet.cattle.io.bundle.js +9 -8
  439. package/models/fleet.cattle.io.cluster.js +21 -4
  440. package/models/fleet.cattle.io.gitrepo.js +46 -382
  441. package/models/fleet.cattle.io.helmop.js +202 -0
  442. package/models/management.cattle.io.authconfig.js +1 -0
  443. package/models/management.cattle.io.cluster.js +0 -20
  444. package/models/management.cattle.io.feature.js +7 -1
  445. package/models/management.cattle.io.fleetworkspace.js +14 -1
  446. package/models/management.cattle.io.node.js +7 -22
  447. package/models/management.cattle.io.nodepool.js +12 -0
  448. package/models/management.cattle.io.oidcclient.js +18 -0
  449. package/models/management.cattle.io.registration.js +3 -0
  450. package/models/management.cattle.io.setting.js +0 -1
  451. package/models/namespace.js +12 -1
  452. package/models/provisioning.cattle.io.cluster.js +60 -97
  453. package/models/secret.js +157 -2
  454. package/models/service.js +28 -9
  455. package/models/storage.k8s.io.storageclass.js +2 -2
  456. package/models/workload.js +91 -51
  457. package/package.json +6 -5
  458. package/pages/about.vue +17 -61
  459. package/pages/account/index.vue +9 -1
  460. package/pages/auth/login.vue +2 -3
  461. package/pages/auth/verify.vue +13 -1
  462. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +36 -0
  463. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
  464. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +57 -0
  465. package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
  466. package/pages/c/_cluster/apps/charts/index.vue +501 -468
  467. package/pages/c/_cluster/apps/charts/install.vue +0 -1
  468. package/pages/c/_cluster/auth/roles/index.vue +19 -48
  469. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  470. package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
  471. package/pages/c/_cluster/explorer/index.vue +14 -3
  472. package/pages/c/_cluster/explorer/projectsecret.vue +34 -0
  473. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  474. package/pages/c/_cluster/fleet/__tests__/index.test.ts +720 -0
  475. package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
  476. package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
  477. package/pages/c/_cluster/fleet/application/create.vue +341 -0
  478. package/pages/c/_cluster/fleet/application/index.vue +139 -0
  479. package/pages/c/_cluster/fleet/graph/config.js +277 -0
  480. package/pages/c/_cluster/fleet/index.vue +866 -328
  481. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  482. package/pages/c/_cluster/longhorn/index.vue +5 -2
  483. package/pages/c/_cluster/settings/banners.vue +56 -2
  484. package/pages/c/_cluster/settings/brand.vue +2 -1
  485. package/pages/c/_cluster/settings/performance.vue +7 -26
  486. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  487. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  488. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
  489. package/pages/c/_cluster/uiplugins/index.vue +98 -55
  490. package/pages/explorer/resource/detail/configmap.vue +42 -0
  491. package/pages/explorer/resource/detail/projectsecret.vue +9 -0
  492. package/pages/explorer/resource/detail/secret.vue +63 -0
  493. package/pages/home.vue +8 -104
  494. package/pages/prefs.vue +0 -1
  495. package/pages/support/index.vue +4 -6
  496. package/plugins/clean-html.js +2 -0
  497. package/plugins/dashboard-store/__tests__/actions.test.ts +4 -1
  498. package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
  499. package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
  500. package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
  501. package/plugins/dashboard-store/actions.js +212 -55
  502. package/plugins/dashboard-store/getters.js +112 -24
  503. package/plugins/dashboard-store/mutations.js +61 -12
  504. package/plugins/dashboard-store/normalize.js +29 -19
  505. package/plugins/dashboard-store/resource-class.js +132 -49
  506. package/plugins/steve/__tests__/getters.test.ts +19 -12
  507. package/plugins/steve/__tests__/steve-class.test.ts +1 -0
  508. package/plugins/steve/__tests__/subscribe.spec.ts +324 -1
  509. package/plugins/steve/actions.js +37 -24
  510. package/plugins/steve/getters.js +47 -12
  511. package/plugins/steve/resourceWatcher.js +10 -3
  512. package/plugins/steve/steve-class.js +5 -0
  513. package/plugins/steve/steve-pagination-utils.ts +225 -43
  514. package/plugins/steve/subscribe.js +418 -53
  515. package/plugins/steve/worker/web-worker.advanced.js +5 -1
  516. package/rancher-components/Banner/Banner.test.ts +51 -3
  517. package/rancher-components/Banner/Banner.vue +37 -6
  518. package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
  519. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -9
  520. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +51 -0
  521. package/rancher-components/Form/LabeledInput/LabeledInput.vue +21 -3
  522. package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
  523. package/rancher-components/Form/Radio/RadioButton.vue +21 -5
  524. package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
  525. package/rancher-components/Form/Radio/RadioGroup.vue +81 -38
  526. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +4 -0
  527. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +22 -1
  528. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  529. package/rancher-components/RcButton/RcButton.vue +1 -1
  530. package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
  531. package/rancher-components/RcDropdown/RcDropdown.vue +6 -0
  532. package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -55
  533. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +69 -0
  534. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +93 -0
  535. package/rancher-components/RcDropdown/RcDropdownMenu.vue +7 -8
  536. package/rancher-components/RcDropdown/index.ts +2 -0
  537. package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
  538. package/rancher-components/RcDropdown/useDropdownItem.ts +92 -0
  539. package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
  540. package/rancher-components/RcItemCard/RcItemCard.vue +430 -0
  541. package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
  542. package/rancher-components/RcItemCard/index.ts +2 -0
  543. package/rancher-components/StringList/StringList.vue +1 -1
  544. package/scripts/extension/publish +1 -1
  545. package/static/loading-indicator.html +1 -1
  546. package/store/action-menu.js +26 -56
  547. package/store/auth.js +3 -0
  548. package/store/catalog.js +85 -25
  549. package/store/features.js +0 -1
  550. package/store/growl.js +97 -8
  551. package/store/i18n.js +1 -1
  552. package/store/index.js +44 -14
  553. package/store/notifications.ts +426 -0
  554. package/store/prefs.js +2 -8
  555. package/store/slideInPanel.ts +6 -0
  556. package/store/type-map.js +34 -17
  557. package/store/type-map.utils.ts +49 -6
  558. package/store/uiplugins.ts +15 -1
  559. package/types/fleet.d.ts +60 -1
  560. package/types/kube/kube-api.ts +34 -0
  561. package/types/notifications/index.ts +74 -0
  562. package/types/resources/fleet.d.ts +43 -0
  563. package/types/resources/pod-security-admission.ts +36 -0
  564. package/types/resources/settings.d.ts +107 -0
  565. package/types/resources/userPreferences.d.ts +13 -0
  566. package/types/shell/index.d.ts +971 -745
  567. package/types/store/dashboard-store.types.ts +57 -4
  568. package/types/store/pagination.types.ts +41 -9
  569. package/types/store/subscribe.types.ts +50 -0
  570. package/utils/__mocks__/tabbable.js +13 -0
  571. package/utils/__tests__/back-off.test.ts +354 -0
  572. package/utils/__tests__/create-yaml.test.ts +235 -0
  573. package/utils/__tests__/fleet.test.ts +148 -0
  574. package/utils/__tests__/kontainer.test.ts +19 -0
  575. package/utils/__tests__/object.test.ts +54 -1
  576. package/utils/__tests__/string.test.ts +273 -1
  577. package/utils/__tests__/time.test.ts +31 -0
  578. package/utils/auth.js +41 -6
  579. package/utils/back-off.ts +176 -0
  580. package/utils/cluster.js +24 -20
  581. package/utils/create-yaml.js +103 -9
  582. package/utils/crypto/encryption.ts +103 -0
  583. package/utils/cspAdaptor.ts +51 -0
  584. package/utils/error.js +0 -5
  585. package/utils/fleet-types.ts +0 -0
  586. package/utils/fleet.ts +204 -74
  587. package/utils/grafana.js +1 -0
  588. package/utils/kontainer.ts +3 -5
  589. package/utils/object.js +36 -12
  590. package/utils/pagination-utils.ts +50 -3
  591. package/utils/pagination-wrapper.ts +132 -50
  592. package/utils/perf-setting.utils.ts +28 -0
  593. package/utils/release-notes.ts +48 -0
  594. package/utils/selector-typed.ts +210 -0
  595. package/utils/selector.js +29 -6
  596. package/utils/settings.ts +4 -1
  597. package/utils/string.js +24 -0
  598. package/utils/style.ts +39 -0
  599. package/utils/{time.js → time.ts} +25 -6
  600. package/utils/uiplugins.ts +41 -8
  601. package/utils/v-sphere.ts +5 -1
  602. package/utils/validators/formRules/__tests__/index.test.ts +76 -6
  603. package/utils/validators/formRules/index.ts +99 -4
  604. package/utils/window.js +11 -7
  605. package/.DS_Store +0 -0
  606. package/components/AssignTo.vue +0 -199
  607. package/components/DisableAuthProviderModal.vue +0 -115
  608. package/components/MoveModal.vue +0 -167
  609. package/components/PromptChangePassword.vue +0 -123
  610. package/components/ResourceList/Masthead-btn.vue +0 -225
  611. package/components/__tests__/ApplicationCard.test.ts +0 -27
  612. package/components/cards/ApplicationCard.vue +0 -145
  613. package/components/fleet/FleetBundleResources.vue +0 -86
  614. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
  615. package/components/formatter/RKETemplateName.vue +0 -37
  616. package/config/product/legacy.js +0 -62
  617. package/config/secret.js +0 -14
  618. package/dialog/SaveAsRKETemplateDialog.vue +0 -139
  619. package/models/etcdbackup.js +0 -45
  620. package/pages/auth copy/login.vue +0 -595
  621. package/pages/auth copy/logout.vue +0 -47
  622. package/pages/auth copy/setup.vue +0 -523
  623. package/pages/auth copy/verify.vue +0 -203
  624. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
  625. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  626. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  627. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  628. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
@@ -3,6 +3,8 @@
3
3
  * relocates cluster resource sockets off the UI thread and into a webworker
4
4
  */
5
5
 
6
+ // Status of this is TBD - https://github.com/rancher/dashboard/issues/15111
7
+
6
8
  import { SCHEMA, COUNT } from '@shell/config/types';
7
9
  import ResourceWatcher, { watchKeyFromMessage } from '@shell/plugins/steve/resourceWatcher';
8
10
  import ResourceCache from '@shell/plugins/steve/caches/resourceCache';
@@ -314,7 +316,9 @@ self.onmessage = (e) => {
314
316
  if (workerActions[action]) {
315
317
  workerActions[action](e?.data[action]);
316
318
  } else {
317
- console.warn('no associated action for:', action); // eslint-disable-line no-console
319
+ // This catches any window sendMessage event. We're hitting this on hot-reload of code where somehow this file is loaded
320
+ // Could be related to extensions, which have their own version of this
321
+ console.debug('no associated action for:', action); // eslint-disable-line no-console
318
322
  }
319
323
  });
320
324
  }; // bind everything to the worker's onmessage handler via the workerActions
@@ -3,14 +3,23 @@ import { Banner } from './index';
3
3
 
4
4
  describe('component: Banner', () => {
5
5
  it('should display text based on label', () => {
6
- const label = 'test';
6
+ const label = 'some-label-test';
7
7
  const wrapper = mount(
8
8
  Banner,
9
9
  { propsData: { label } });
10
10
 
11
- const element = wrapper.find('span').element;
11
+ expect(wrapper.html()).toContain(label);
12
+ });
13
+
14
+ it('should display text based on default slot', () => {
15
+ const slotText = 'some-test';
16
+
17
+ const wrapper = mount(
18
+ Banner,
19
+ { slots: { default: slotText } }
20
+ );
12
21
 
13
- expect(element.textContent).toBe(label);
22
+ expect(wrapper.html()).toContain(slotText);
14
23
  });
15
24
 
16
25
  it('should display an icon', () => {
@@ -56,4 +65,43 @@ describe('component: Banner', () => {
56
65
 
57
66
  expect(element.classList).toContain('stacked');
58
67
  });
68
+
69
+ it('a11y: adding ARIA props should correctly fill out the appropriate fields on the component', () => {
70
+ const label = 'test';
71
+ const icon = 'my-icon';
72
+ const closable = true;
73
+
74
+ const wrapper = mount(
75
+ Banner,
76
+ {
77
+ propsData: {
78
+ label, icon, closable
79
+ }
80
+ });
81
+
82
+ const mainContainer = wrapper.find('.banner');
83
+ const bannerIcon = wrapper.find('.banner__icon i');
84
+ const bannerContent = wrapper.find('.banner__content');
85
+ const bannerCloseBtn = wrapper.find('.banner__content__closer');
86
+ const bannerCloseIcon = wrapper.find('.icon-close.closer-icon');
87
+
88
+ const mainContainerRole = mainContainer.attributes('role');
89
+ const mainContainerAriaLabelledBy = mainContainer.attributes('aria-labelledby');
90
+
91
+ const bannerIconAlt = bannerIcon.attributes('alt');
92
+
93
+ const bannerContentId = bannerContent.attributes('id');
94
+
95
+ const bannerCloseBtnRole = bannerCloseBtn.attributes('role');
96
+ const bannerCloseBtnAriaLabel = bannerCloseBtn.attributes('aria-label');
97
+
98
+ const bannerCloseIconAlt = bannerCloseIcon.attributes('alt');
99
+
100
+ expect(mainContainerRole).toBe('region');
101
+ expect(mainContainerAriaLabelledBy).toBe(bannerContentId);
102
+ expect(bannerIconAlt).toBeDefined();
103
+ expect(bannerCloseIconAlt).toBeDefined();
104
+ expect(bannerCloseBtnRole).toBe('button');
105
+ expect(bannerCloseBtnAriaLabel).toBeDefined();
106
+ });
59
107
  });
@@ -1,8 +1,21 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue';
3
- import { nlToBr } from '@shell/utils/string';
3
+ import { nlToBr, generateRandomAlphaString } from '@shell/utils/string';
4
4
  import { stringify } from '@shell/utils/error';
5
5
 
6
+ /**
7
+ * These should eventually be used when making this component use the composable api but I need the props elsewhere so I'm defining them here.
8
+ */
9
+ export interface Props {
10
+ color?: string;
11
+ label?: string | Error | Object;
12
+ labelKey?: string;
13
+ icon?: string;
14
+ closable?: boolean;
15
+ stacked?: boolean;
16
+ disabled?: boolean;
17
+ }
18
+
6
19
  export default defineComponent({
7
20
  props: {
8
21
  /**
@@ -47,16 +60,26 @@ export default defineComponent({
47
60
  stacked: {
48
61
  type: Boolean,
49
62
  default: false
50
- }
63
+ },
64
+ /**
65
+ * Disabled banner - banner is shown greyed out
66
+ */
67
+ disabled: {
68
+ type: Boolean,
69
+ default: false
70
+ },
71
+ },
72
+ emits: ['close'],
73
+ data() {
74
+ return { labelledbyId: `banner-labelledby-${ generateRandomAlphaString(12) }` };
51
75
  },
52
- emits: ['close'],
53
76
  computed: {
54
77
  /**
55
78
  * Return message text as label.
56
79
  */
57
80
  messageLabel(): string | void {
58
81
  return !(typeof this.label === 'string') ? stringify(this.label) : undefined;
59
- }
82
+ },
60
83
  },
61
84
  methods: { nlToBr }
62
85
  });
@@ -66,8 +89,11 @@ export default defineComponent({
66
89
  class="banner"
67
90
  :class="{
68
91
  [color]: true,
92
+ 'banner-disabled': disabled
69
93
  }"
70
- role="banner"
94
+ role="region"
95
+ :aria-labelledby="labelledbyId"
96
+ tabindex="0"
71
97
  >
72
98
  <div
73
99
  v-if="icon"
@@ -77,9 +103,11 @@ export default defineComponent({
77
103
  <i
78
104
  class="icon icon-2x"
79
105
  :class="icon"
106
+ :alt="t('generic.banners.bannerIcon')"
80
107
  />
81
108
  </div>
82
109
  <div
110
+ :id="labelledbyId"
83
111
  class="banner__content"
84
112
  data-testid="banner-content"
85
113
  :class="{
@@ -94,7 +122,9 @@ export default defineComponent({
94
122
  :k="labelKey"
95
123
  :raw="true"
96
124
  />
97
- <span v-else-if="messageLabel">{{ messageLabel }}</span>
125
+ <span
126
+ v-else-if="messageLabel"
127
+ >{{ messageLabel }}</span>
98
128
  <span
99
129
  v-else
100
130
  v-clean-html="nlToBr(label)"
@@ -113,6 +143,7 @@ export default defineComponent({
113
143
  <i
114
144
  data-testid="banner-close"
115
145
  class="icon icon-close closer-icon"
146
+ :alt="t('generic.banners.altCloseBanner')"
116
147
  />
117
148
  </div>
118
149
  </div>
@@ -1,4 +1,4 @@
1
- import { shallowMount, Wrapper } from '@vue/test-utils';
1
+ import { shallowMount, Wrapper, mount } from '@vue/test-utils';
2
2
  import { Checkbox } from './index';
3
3
 
4
4
  describe('checkbox.vue', () => {
@@ -65,4 +65,62 @@ describe('checkbox.vue', () => {
65
65
 
66
66
  expect(wrapper.emitted('update:value')[0][0]).toBeNull();
67
67
  });
68
+
69
+ it('a11y: adding ARIA props should correctly fill out the appropriate fields on the component', async() => {
70
+ const alternateLabel = 'some-alternate-aria-label';
71
+ const description = 'some-description';
72
+ const ariaDescribedById = 'some-external-id';
73
+
74
+ const wrapper: Wrapper<InstanceType<typeof Checkbox>> = mount(
75
+ Checkbox,
76
+ {
77
+ propsData: {
78
+ value: false, alternateLabel, description
79
+ },
80
+ attrs: { 'aria-describedby': ariaDescribedById },
81
+ }
82
+ );
83
+
84
+ const field = wrapper.find('.checkbox-custom');
85
+ const ariaChecked = field.attributes('aria-checked');
86
+ const ariaLabel = field.attributes('aria-label');
87
+ const ariaLabelledBy = field.attributes('aria-labelledby');
88
+ const ariaDescribedBy = field.attributes('aria-describedby');
89
+
90
+ // validates type of input rendered
91
+ expect(ariaChecked).toBe('false');
92
+ expect(ariaLabelledBy).toBeUndefined();
93
+ expect(ariaLabel).toBe(alternateLabel);
94
+ expect(ariaDescribedBy).toBe(`${ ariaDescribedById } ${ wrapper.vm.describedById }`);
95
+ });
96
+
97
+ it('a11y: having a label should not render "aria-label" prop and have "aria-labelledby"', async() => {
98
+ const label = 'some-label';
99
+
100
+ const wrapper: Wrapper<InstanceType<typeof Checkbox>> = mount(
101
+ Checkbox,
102
+ {
103
+ propsData: {
104
+ value: true, label, disabled: true
105
+ }
106
+ }
107
+ );
108
+
109
+ const field = wrapper.find('.checkbox-custom');
110
+ const ariaChecked = field.attributes('aria-checked');
111
+ const ariaLabel = field.attributes('aria-label');
112
+ const ariaLabelledBy = field.attributes('aria-labelledby');
113
+ const ariaDisabled = field.attributes('aria-disabled');
114
+ const tabIndex = field.attributes('tabindex');
115
+
116
+ // validates type of input rendered
117
+ expect(field.exists()).toBe(true);
118
+ expect(ariaChecked).toBe('true');
119
+ expect(ariaLabelledBy).toBe(wrapper.vm.idForLabel);
120
+ expect(ariaLabel).toBeUndefined();
121
+ expect(wrapper.find(`#${ wrapper.vm.idForLabel }`).text()).toBe(label);
122
+
123
+ expect(ariaDisabled).toBe('true');
124
+ expect(tabIndex).toBe('-1');
125
+ });
68
126
  });
@@ -13,7 +13,7 @@ export default defineComponent({
13
13
  * The checkbox value.
14
14
  */
15
15
  value: {
16
- type: [Boolean, Array, String] as PropType<boolean | boolean[] | string>,
16
+ type: [Boolean, Array, String] as PropType<boolean | boolean[] | string | string[]>,
17
17
  default: false
18
18
  },
19
19
 
@@ -142,6 +142,18 @@ export default defineComponent({
142
142
  },
143
143
 
144
144
  computed: {
145
+ ariaDescribedBy(): string | undefined {
146
+ const inheritedDescribedBy = this.$attrs['aria-describedby'];
147
+ const internalDescribedBy = this.descriptionKey || this.description ? this.describedById : undefined;
148
+
149
+ if (inheritedDescribedBy && internalDescribedBy) {
150
+ return `${ inheritedDescribedBy } ${ internalDescribedBy }`;
151
+ } else if (inheritedDescribedBy || internalDescribedBy) {
152
+ return `${ inheritedDescribedBy || internalDescribedBy }`;
153
+ }
154
+
155
+ return undefined;
156
+ },
145
157
  /**
146
158
  * Determines if the checkbox is disabled.
147
159
  * @returns boolean: True when the disabled prop is true or when mode is
@@ -176,7 +188,7 @@ export default defineComponent({
176
188
  },
177
189
 
178
190
  idForLabel():string {
179
- return `${ this.id }-label`;
191
+ return `${ generateRandomAlphaString(12) }-checkbox-label`;
180
192
  }
181
193
  },
182
194
 
@@ -233,7 +245,7 @@ export default defineComponent({
233
245
  /**
234
246
  * Determines if there are multiple values for the checkbox.
235
247
  */
236
- isMulti(value: boolean | boolean[] | string): value is boolean[] {
248
+ isMulti(value: boolean | boolean[] | string | string[]): value is boolean[] {
237
249
  return Array.isArray(value);
238
250
  },
239
251
 
@@ -280,10 +292,11 @@ export default defineComponent({
280
292
  class="checkbox-custom"
281
293
  :class="{indeterminate: indeterminate}"
282
294
  :tabindex="isDisabled ? -1 : 0"
295
+ :aria-disabled="isDisabled"
283
296
  :aria-label="replacementLabel"
284
297
  :aria-checked="!!value"
285
298
  :aria-labelledby="labelKey || label ? idForLabel : undefined"
286
- :aria-describedby="descriptionKey || description ? describedById : undefined"
299
+ :aria-describedby="ariaDescribedBy"
287
300
  role="checkbox"
288
301
  />
289
302
  <span
@@ -292,12 +305,15 @@ export default defineComponent({
292
305
  :class="{ 'checkbox-primary': primary }"
293
306
  >
294
307
  <slot name="label">
295
- <t
308
+ <span
296
309
  v-if="labelKey"
297
310
  :id="idForLabel"
298
- :k="labelKey"
299
- :raw="true"
300
- />
311
+ >
312
+ <t
313
+ :k="labelKey"
314
+ :raw="true"
315
+ />
316
+ </span>
301
317
  <span
302
318
  v-else-if="label"
303
319
  :id="idForLabel"
@@ -310,6 +326,7 @@ export default defineComponent({
310
326
  class="checkbox-info icon icon-info icon-lg"
311
327
  :data-testid="componentTestid + '-info-icon'"
312
328
  :tabindex="isDisabled ? -1 : 0"
329
+ role="tooltip"
313
330
  />
314
331
  <i
315
332
  v-else-if="tooltip"
@@ -318,6 +335,7 @@ export default defineComponent({
318
335
  class="checkbox-info icon icon-info icon-lg"
319
336
  :data-testid="componentTestid + '-info-icon'"
320
337
  :tabindex="isDisabled ? -1 : 0"
338
+ role="tooltip"
321
339
  />
322
340
  </slot>
323
341
  </span>
@@ -386,7 +404,7 @@ $fontColor: var(--input-label);
386
404
 
387
405
  .checkbox-info {
388
406
  line-height: normal;
389
- margin-left: 2px;
407
+ margin-left: 4px;
390
408
 
391
409
  &:focus-visible {
392
410
  @include focus-outline;
@@ -54,4 +54,55 @@ describe('component: LabeledInput', () => {
54
54
  expect(subLabel.text()).toBe(hint);
55
55
  });
56
56
  });
57
+
58
+ describe('a11y: adding ARIA props', () => {
59
+ const ariaLabelVal = 'some-aria-label';
60
+ const subLabelVal = 'some-sublabel';
61
+ const ariaDescribedByIdVal = 'some-external-id';
62
+ const ariaRequiredVal = 'true';
63
+
64
+ it.each([
65
+ ['text', 'input', ariaLabelVal, subLabelVal, ariaDescribedByIdVal],
66
+ ['cron', 'input', ariaLabelVal, subLabelVal, ariaDescribedByIdVal],
67
+ ['multiline', 'textarea', ariaLabelVal, subLabelVal, ariaDescribedByIdVal],
68
+ ['multiline-password', 'textarea', ariaLabelVal, subLabelVal, ariaDescribedByIdVal],
69
+ ])('for type %p should correctly fill out the appropriate fields on the component', (type, validationType, ariaLabel, subLabel, ariaDescribedById) => {
70
+ const wrapper = mount(LabeledInput, {
71
+ propsData: {
72
+ value: '', type, ariaLabel, subLabel, required: true, mode: 'view'
73
+ },
74
+ attrs: { 'aria-describedby': ariaDescribedById },
75
+ mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
76
+ });
77
+
78
+ const field = wrapper.find(validationType);
79
+ const ariaLabelProp = field.attributes('aria-label');
80
+ const ariaDescribedBy = field.attributes('aria-describedby');
81
+ const ariaRequired = field.attributes('aria-required');
82
+ const ariaDisabled = field.attributes('aria-disabled');
83
+ const disabledAttr = field.attributes('disabled');
84
+
85
+ // validates type of input rendered
86
+ expect(field.exists()).toBe(true);
87
+ expect(ariaLabelProp).toBe(ariaLabel);
88
+ expect(ariaDescribedBy).toBe(`${ ariaDescribedById } ${ wrapper.vm.describedById }`);
89
+ expect(ariaRequired).toBe(ariaRequiredVal);
90
+ expect(ariaDisabled).toBe('true');
91
+ expect(disabledAttr).toBeDefined();
92
+ });
93
+ });
94
+
95
+ it('a11y: rendering a "label" should not render an "aria-label" prop', () => {
96
+ const label = 'some-label';
97
+
98
+ const wrapper = mount(LabeledInput, {
99
+ propsData: { type: 'text', label },
100
+ mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
101
+ });
102
+
103
+ const mainInput = wrapper.find('input[type="text"]');
104
+
105
+ expect(mainInput.attributes('aria-label')).toBeUndefined();
106
+ expect(wrapper.find('label').text()).toBe(label);
107
+ });
57
108
  });
@@ -162,6 +162,19 @@ export default defineComponent({
162
162
  return this.isCompact ? false : !!this.label || !!this.labelKey || !!this.$slots.label;
163
163
  },
164
164
 
165
+ ariaDescribedBy(): string | undefined {
166
+ const inheritedDescribedBy = this.$attrs['aria-describedby'];
167
+ const internalDescribedBy = this.cronHint || this.subLabel ? this.describedById : undefined;
168
+
169
+ if (inheritedDescribedBy && internalDescribedBy) {
170
+ return `${ inheritedDescribedBy } ${ internalDescribedBy }`;
171
+ } else if (inheritedDescribedBy || internalDescribedBy) {
172
+ return `${ inheritedDescribedBy || internalDescribedBy }`;
173
+ }
174
+
175
+ return undefined;
176
+ },
177
+
165
178
  /**
166
179
  * Determines if the Labeled Input should display a tooltip.
167
180
  */
@@ -382,6 +395,7 @@ export default defineComponent({
382
395
  <span
383
396
  v-if="requiredField"
384
397
  class="required"
398
+ :aria-hidden="true"
385
399
  >*</span>
386
400
  </label>
387
401
  </slot> -->
@@ -397,11 +411,13 @@ export default defineComponent({
397
411
  v-stripped-aria-label="!hasLabel && ariaLabel ? ariaLabel : undefined"
398
412
  :maxlength="_maxlength"
399
413
  :disabled="isDisabled"
414
+ :aria-disabled="isDisabled"
400
415
  :value="value || ''"
401
416
  :placeholder="_placeholder"
402
417
  autocapitalize="off"
403
418
  :class="{ conceal: type === 'multiline-password' }"
404
- :aria-describedby="cronHint || subLabel ? describedById : undefined"
419
+ :aria-describedby="ariaDescribedBy"
420
+ :aria-required="requiredField"
405
421
  @update:value="onInput"
406
422
  @focus="onFocus"
407
423
  @blur="onBlur"
@@ -411,18 +427,20 @@ export default defineComponent({
411
427
  :id="inputId"
412
428
  ref="value"
413
429
  v-stripped-aria-label="!hasLabel && ariaLabel ? ariaLabel : undefined"
414
- role="textbox"
430
+ :role="type === 'number' ? undefined : 'textbox'"
415
431
  :class="{ 'no-label': !hasLabel }"
416
432
  v-bind="$attrs"
417
433
  :maxlength="_maxlength"
418
434
  :disabled="isDisabled"
435
+ :aria-disabled="isDisabled"
419
436
  :type="type === 'cron' ? 'text' : type"
420
437
  :value="value"
421
438
  :placeholder="_placeholder"
422
439
  autocomplete="off"
423
440
  autocapitalize="off"
424
441
  :data-lpignore="ignorePasswordManagers"
425
- :aria-describedby="cronHint || subLabel ? describedById : undefined"
442
+ :aria-describedby="ariaDescribedBy"
443
+ :aria-required="requiredField"
426
444
  @input="onInput"
427
445
  @focus="onFocus"
428
446
  @blur="onBlur"
@@ -1,4 +1,4 @@
1
- import { shallowMount } from '@vue/test-utils';
1
+ import { shallowMount, mount } from '@vue/test-utils';
2
2
  import { RadioButton } from './index';
3
3
 
4
4
  describe('radioButton.vue', () => {
@@ -30,4 +30,39 @@ describe('radioButton.vue', () => {
30
30
 
31
31
  expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
32
32
  });
33
+
34
+ it('a11y: adding ARIA props should correctly fill out the appropriate fields on the component', async() => {
35
+ const val = 'foo';
36
+ const value = 'foo';
37
+ const description = 'some-description';
38
+ const itemLabel = 'some-label';
39
+ const radioOptionId = 'some-id-from-parent';
40
+
41
+ const wrapper = mount(
42
+ RadioButton,
43
+ {
44
+ propsData: {
45
+ label: itemLabel,
46
+ val,
47
+ value,
48
+ description,
49
+ radioOptionId
50
+ }
51
+ });
52
+
53
+ const radioInputElem = wrapper.find('span[role="radio"]');
54
+ const role = radioInputElem.attributes('role');
55
+ const ariaLabel = radioInputElem.attributes('aria-label');
56
+ const ariaChecked = radioInputElem.attributes('aria-checked');
57
+ const ariaDisabled = radioInputElem.attributes('aria-disabled');
58
+ const ariaDescribedBy = radioInputElem.attributes('aria-describedby');
59
+ const itemId = radioInputElem.attributes('id');
60
+
61
+ expect(role).toBe('radio');
62
+ expect(ariaLabel).toBe(itemLabel);
63
+ expect(ariaChecked).toBe('true');
64
+ expect(ariaDisabled).toBe('false');
65
+ expect(ariaDescribedBy).toBe(wrapper.vm.describeById);
66
+ expect(itemId).toBe(radioOptionId);
67
+ });
33
68
  });
@@ -1,10 +1,12 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue';
3
3
  import { _VIEW } from '@shell/config/query-params';
4
- import { randomStr } from '@shell/utils/string';
4
+ import { generateRandomAlphaString } from '@shell/utils/string';
5
5
 
6
6
  export default defineComponent({
7
- props: {
7
+
8
+ inheritAttrs: false,
9
+ props: {
8
10
  /**
9
11
  * The name of the input, for grouping.
10
12
  */
@@ -76,7 +78,16 @@ export default defineComponent({
76
78
  preventFocusOnRadioGroups: {
77
79
  type: Boolean,
78
80
  default: false
79
- }
81
+ },
82
+
83
+ /**
84
+ * Radio option Id - used to link to aria-activedescendant
85
+ * when using inside of the context of a Radio Group
86
+ */
87
+ radioOptionId: {
88
+ type: String,
89
+ default: undefined
90
+ },
80
91
  },
81
92
 
82
93
  emits: ['update:value'],
@@ -84,7 +95,8 @@ export default defineComponent({
84
95
  data() {
85
96
  return {
86
97
  isChecked: this.value === this.val,
87
- randomString: `${ randomStr() }-radio`,
98
+ randomString: `${ generateRandomAlphaString(12) }-radio`,
99
+ describeById: `${ generateRandomAlphaString(12) }-radio-described-id`,
88
100
  };
89
101
  },
90
102
 
@@ -165,11 +177,14 @@ export default defineComponent({
165
177
  @click.stop.prevent
166
178
  >
167
179
  <span
180
+ :id="radioOptionId"
168
181
  ref="custom"
169
182
  :class="[ isDisabled ? 'text-muted' : '', 'radio-custom']"
170
183
  :tabindex="isDisabled || preventFocusOnRadioGroups ? -1 : 0"
171
184
  :aria-label="label"
172
185
  :aria-checked="isChecked"
186
+ :aria-disabled="isDisabled"
187
+ :aria-describedby="descriptionKey || description ? describeById : undefined"
173
188
  role="radio"
174
189
  />
175
190
  <div class="labeling">
@@ -183,13 +198,14 @@ export default defineComponent({
183
198
  >
184
199
  <!-- slot content -->
185
200
  </slot>
186
- <span
201
+ <div
187
202
  v-else-if="label"
188
203
  v-clean-html="label"
189
204
  />
190
205
  </label>
191
206
  <div
192
207
  v-if="descriptionKey || description"
208
+ :id="describeById"
193
209
  class="radio-button-outer-container-description"
194
210
  >
195
211
  <t
@@ -24,4 +24,64 @@ describe('component: RadioGroup', () => {
24
24
  expect(slot.disabled).toBe(disabled);
25
25
  });
26
26
  });
27
+
28
+ it('a11y: adding ARIA props should correctly fill out the appropriate fields on the component', async() => {
29
+ const inputLabel = 'some-label';
30
+ const ariaDescribedById = 'some-external-id';
31
+ const currValue = 'whatever';
32
+
33
+ const wrapper = mount(RadioGroup, {
34
+ propsData: {
35
+ name: 'some-name',
36
+ label: inputLabel,
37
+ value: currValue,
38
+ options: [{ label: currValue, value: currValue }]
39
+ },
40
+ attrs: { 'aria-describedby': ariaDescribedById }
41
+ });
42
+
43
+ const field = wrapper.find('[role="radiogroup"]');
44
+ const role = field.attributes('role');
45
+ const ariaLabel = field.attributes('aria-label');
46
+ const ariaDescribedBy = field.attributes('aria-describedby');
47
+ const ariaActiveDescendant = field.attributes('aria-activedescendant');
48
+
49
+ expect(ariaLabel).toBe(inputLabel);
50
+ expect(role).toBe('radiogroup');
51
+ expect(ariaActiveDescendant).toBe(`${ wrapper.vm.radioOptionsIdPrefix }0`);
52
+ expect(ariaDescribedBy).toBe(ariaDescribedById);
53
+
54
+ const radioOption = wrapper.find(`.radio-custom`);
55
+
56
+ // make sure we validate when using RadioGroup without custom slot data
57
+ // we do assign an ID that is important to get 'aria-activedescendant' working
58
+ expect(radioOption.attributes('id')).toBe(`${ wrapper.vm.radioOptionsIdPrefix }0`);
59
+ });
60
+
61
+ it('a11y: adding aria-label ($attrs) from parent should override label-based aria-label', async() => {
62
+ const inputLabel = 'some-label';
63
+ const overrideLabel = 'some-override-label';
64
+ const currValue = 'whatever';
65
+
66
+ const wrapper = mount(RadioGroup, {
67
+ propsData: {
68
+ name: 'some-name',
69
+ label: inputLabel,
70
+ value: currValue,
71
+ disabled: true,
72
+ options: [{ label: currValue, value: currValue }]
73
+ },
74
+ attrs: { 'aria-label': overrideLabel }
75
+ });
76
+
77
+ const field = wrapper.find('[role="radiogroup"]');
78
+ const ariaLabel = field.attributes('aria-label');
79
+ const ariaDisabled = field.attributes('aria-disabled');
80
+ const tabIndex = field.attributes('tabindex');
81
+
82
+ expect(ariaLabel).toBe(overrideLabel);
83
+ expect(ariaLabel).not.toBe(inputLabel);
84
+ expect(ariaDisabled).toBe('true');
85
+ expect(tabIndex).toBe('-1');
86
+ });
27
87
  });