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
@@ -1,4 +1,4 @@
1
- import { decodeHtml, resourceNames } from '@shell/utils/string';
1
+ import { decodeHtml, resourceNames, pathArrayToTree } from '@shell/utils/string';
2
2
 
3
3
  describe('fx: decodeHtml', () => {
4
4
  it('should decode HTML values from escaped string into valid markup', () => {
@@ -89,3 +89,275 @@ describe('fx: resourceNames', () => {
89
89
  });
90
90
  });
91
91
  });
92
+
93
+ describe('fx: pathArrayToTree', () => {
94
+ interface TreeNode {
95
+ name: string;
96
+ children: TreeNode[];
97
+ }
98
+
99
+ function sortTree(nodes: TreeNode[]): void {
100
+ if (!nodes) return;
101
+ nodes.sort((a, b) => a.name.localeCompare(b.name));
102
+ nodes.forEach((node) => {
103
+ if (node.children && node.children.length > 0) {
104
+ sortTree(node.children);
105
+ }
106
+ });
107
+ }
108
+
109
+ it('should return an empty array for an empty input array', () => {
110
+ const paths: string[] = [];
111
+
112
+ expect(pathArrayToTree(paths)).toStrictEqual([]);
113
+ });
114
+
115
+ it('should convert simple single-level paths correctly', () => {
116
+ const paths: string[] = [
117
+ 'file1.txt',
118
+ 'folderA',
119
+ 'itemB'
120
+ ];
121
+ const expected: TreeNode[] = [
122
+ { name: 'file1.txt', children: [] },
123
+ { name: 'folderA', children: [] },
124
+ { name: 'itemB', children: [] },
125
+ ];
126
+ const actual = pathArrayToTree(paths);
127
+
128
+ sortTree(actual); // Sort the actual output for deterministic comparison
129
+ expect(actual).toStrictEqual(expected);
130
+ });
131
+
132
+ it('should convert two-level nested paths correctly', () => {
133
+ const paths: string[] = [
134
+ 'folderA/file1.txt',
135
+ 'folderC/file3.txt'
136
+ ];
137
+ const expected: TreeNode[] = [
138
+ {
139
+ name: 'folderA',
140
+ children: [
141
+ { name: 'file1.txt', children: [] },
142
+ ]
143
+ },
144
+ {
145
+ name: 'folderC',
146
+ children: [
147
+ { name: 'file3.txt', children: [] }
148
+ ]
149
+ },
150
+ ];
151
+ const actual = pathArrayToTree(paths);
152
+
153
+ sortTree(actual);
154
+ expect(actual).toStrictEqual(expected);
155
+ });
156
+
157
+ it('should handle deep nesting and common prefixes correctly', () => {
158
+ const paths: string[] = [
159
+ 'root/level1/level2/file.doc',
160
+ 'root/level1/another_file.txt',
161
+ 'root/diff_level1/config.json'
162
+ ];
163
+ const expected: TreeNode[] = [
164
+ {
165
+ name: 'root',
166
+ children: [
167
+ {
168
+ name: 'diff_level1',
169
+ children: [
170
+ { name: 'config.json', children: [] }
171
+ ]
172
+ },
173
+ {
174
+ name: 'level1',
175
+ children: [
176
+ { name: 'another_file.txt', children: [] },
177
+ {
178
+ name: 'level2',
179
+ children: [
180
+ { name: 'file.doc', children: [] }
181
+ ]
182
+ }
183
+ ]
184
+ }
185
+ ]
186
+ }
187
+ ];
188
+ const actual = pathArrayToTree(paths);
189
+
190
+ sortTree(actual);
191
+ expect(actual).toStrictEqual(expected);
192
+ });
193
+
194
+ it('should handle leading/trailing/multiple slashes by treating them as path segments', () => {
195
+ const paths: string[] = [
196
+ '/path/to/file.txt', // Starts with a slash
197
+ 'path/to/another.txt/', // Ends with a slash (adds an empty segment)
198
+ '//root/item//subitem//', // Multiple slashes (adds empty segments)
199
+ 'root/item/another_subitem'
200
+ ];
201
+ const expected: TreeNode[] = [
202
+ {
203
+ name: '',
204
+ children: [
205
+ {
206
+ name: '',
207
+ children: [
208
+ {
209
+ name: 'root',
210
+ children: [
211
+ {
212
+ name: 'item',
213
+ children: [
214
+ {
215
+ name: '',
216
+ children: [
217
+ {
218
+ name: 'subitem',
219
+ children: [
220
+ {
221
+ name: '',
222
+ children: [
223
+ {
224
+ name: '',
225
+ children: [
226
+ ],
227
+ },
228
+ ],
229
+ },
230
+ ],
231
+ },
232
+ ],
233
+ },
234
+ ],
235
+ },
236
+ ],
237
+ },
238
+ ],
239
+ },
240
+ {
241
+ name: 'path',
242
+ children: [
243
+ {
244
+ name: 'to',
245
+ children: [
246
+ {
247
+ name: 'file.txt',
248
+ children: [
249
+ ],
250
+ },
251
+ ],
252
+ },
253
+ ],
254
+ },
255
+ ],
256
+ },
257
+ {
258
+ name: 'path',
259
+ children: [
260
+ {
261
+ name: 'to',
262
+ children: [
263
+ {
264
+ name: 'another.txt',
265
+ children: [
266
+ {
267
+ name: '',
268
+ children: [
269
+ ],
270
+ },
271
+ ],
272
+ },
273
+ ],
274
+ },
275
+ ],
276
+ },
277
+ {
278
+ name: 'root',
279
+ children: [
280
+ {
281
+ name: 'item',
282
+ children: [
283
+ {
284
+ name: 'another_subitem',
285
+ children: [
286
+ ],
287
+ },
288
+ ],
289
+ },
290
+ ],
291
+ },
292
+ ];
293
+ const actual = pathArrayToTree(paths);
294
+
295
+ sortTree(actual);
296
+ expect(actual).toStrictEqual(expected);
297
+ });
298
+
299
+ it('should produce the same structure regardless of input order', () => {
300
+ const paths1: string[] = ['a/b', 'a/c'];
301
+ const paths2: string[] = ['a/c', 'a/b'];
302
+
303
+ const actual1 = pathArrayToTree(paths1);
304
+
305
+ sortTree(actual1);
306
+ const actual2 = pathArrayToTree(paths2);
307
+
308
+ sortTree(actual2);
309
+
310
+ expect(actual1).toStrictEqual(actual2);
311
+ });
312
+
313
+ it('should handle names with special characters (not slashes) correctly', () => {
314
+ const paths: string[] = [
315
+ 'my-folder/file_name.1.txt',
316
+ 'another folder/item with spaces'
317
+ ];
318
+ const expected: TreeNode[] = [
319
+ {
320
+ name: 'another folder',
321
+ children: [
322
+ { name: 'item with spaces', children: [] }
323
+ ]
324
+ },
325
+ {
326
+ name: 'my-folder',
327
+ children: [
328
+ { name: 'file_name.1.txt', children: [] }
329
+ ]
330
+ }
331
+ ];
332
+ const actual = pathArrayToTree(paths);
333
+
334
+ sortTree(actual);
335
+ expect(actual).toStrictEqual(expected);
336
+ });
337
+
338
+ it('should handle duplicate paths correctly, only adding unique structure', () => {
339
+ const paths: string[] = [
340
+ 'folder/file.txt',
341
+ 'folder/file.txt', // Duplicate
342
+ 'other_folder/another_file.txt'
343
+ ];
344
+ const expected: TreeNode[] = [
345
+ {
346
+ name: 'folder',
347
+ children: [
348
+ { name: 'file.txt', children: [] }
349
+ ]
350
+ },
351
+ {
352
+ name: 'other_folder',
353
+ children: [
354
+ { name: 'another_file.txt', children: [] }
355
+ ]
356
+ }
357
+ ];
358
+ const actual = pathArrayToTree(paths);
359
+
360
+ sortTree(actual);
361
+ expect(actual).toStrictEqual(expected);
362
+ });
363
+ });
@@ -0,0 +1,31 @@
1
+ import { DATE_FORMAT, TIME_FORMAT } from '@shell/store/prefs';
2
+ import { dateTimeFormat } from '@shell/utils/time';
3
+ import { type Store } from 'vuex';
4
+
5
+ describe('function: dateTimeFormat', () => {
6
+ jest.useFakeTimers()
7
+ .setSystemTime(new Date('21-10-2010 4:29:00'));
8
+ const store = {
9
+ getters: {
10
+ 'prefs/get': (key: string) => {
11
+ return {
12
+ [DATE_FORMAT]: 'ddd, MMM D YYYY',
13
+ [TIME_FORMAT]: 'h:mm:ss a',
14
+ }[key];
15
+ },
16
+ },
17
+ } as Store<any>;
18
+
19
+ it('should format date and time correctly', () => {
20
+ const date = new Date('2010-10-21T04:29:00Z');
21
+ const formattedDate = dateTimeFormat(date.toISOString(), store);
22
+
23
+ expect(formattedDate).toBe('Thu, Oct 21 2010 4:29:00 am');
24
+ });
25
+
26
+ it('should return empty string for undefined value', () => {
27
+ const formattedDate = dateTimeFormat(undefined, store);
28
+
29
+ expect(formattedDate).toBe('');
30
+ });
31
+ });
package/utils/auth.js CHANGED
@@ -8,6 +8,9 @@ import { allHash } from '@shell/utils/promise';
8
8
  import { getProductFromRoute, getResourceFromRoute } from '@shell/utils/router';
9
9
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
10
10
  import { findBy } from '@shell/utils/array';
11
+ import { onExtensionsReady } from '@shell/utils/uiplugins';
12
+
13
+ export const AUTH_BROADCAST_CHANNEL_NAME = 'rancher-auth-test-callback';
11
14
 
12
15
  export function openAuthPopup(url, provider) {
13
16
  const popup = new Popup(() => {
@@ -16,19 +19,46 @@ export function openAuthPopup(url, provider) {
16
19
  popup.reject = reject;
17
20
  });
18
21
 
22
+ const bc = new BroadcastChannel(AUTH_BROADCAST_CHANNEL_NAME);
23
+
19
24
  window.onAuthTest = (error, code) => {
20
25
  if (error) {
21
26
  popup.reject(error);
22
27
  }
23
28
 
29
+ bc.close();
24
30
  delete window.onAuthTest;
25
31
  popup.resolve(code);
26
32
  };
27
- }, () => {
28
- popup.reject(new Error('Access was not authorized'));
33
+
34
+ // Broadcast message listener for when the window can not invoke a method on the opener
35
+ bc.onmessage = (msgEvent) => {
36
+ try {
37
+ const obj = JSON.parse(msgEvent.data);
38
+ const { error, code } = obj;
39
+
40
+ window.onAuthTest(error, code);
41
+ } catch (e) {
42
+ window.onAuthTest(new Error(`Access was not authorized (invalid callback metadata)`));
43
+
44
+ console.error('Unable to process message from auth broadcast channel', e); // eslint-disable-line no-console
45
+ }
46
+ };
47
+ }, (e) => {
48
+ let detail = '';
49
+
50
+ // If there was an error and it has a message, add that to the message we send back via the promise
51
+ if (e?.type === 'error' && e?.message) {
52
+ detail = ` (${ e.message })`;
53
+ }
54
+
55
+ popup.reject(new Error(`Access was not authorized${ detail }`));
29
56
  });
30
57
 
31
- popup.open(url, 'auth-test', popupWindowOptions());
58
+ // So far, only Amazon Cognito sets the origin policy that prevents us from detecting when the popup is closed
59
+ const doNotPollForClosure = provider === 'cognito';
60
+
61
+ popup.open(url, 'auth-test', popupWindowOptions(), doNotPollForClosure);
32
62
 
33
63
  return popup.promise;
34
64
  }
@@ -242,7 +272,6 @@ export function setProduct(store, to) {
242
272
  */
243
273
  export function validateResource(store, to) {
244
274
  const product = store.getters['currentProduct'];
245
-
246
275
  const resource = getResourceFromRoute(to);
247
276
 
248
277
  // In order to check a resource is valid we need these
@@ -305,9 +334,15 @@ export async function tryInitialSetup(store, password = 'admin') {
305
334
  /**
306
335
  * Record in our state management that we're indeed logged in
307
336
  */
308
- export function isLoggedIn(store, me) {
337
+ export async function isLoggedIn(store, userData) {
309
338
  store.commit('auth/hasAuth', true);
310
- store.commit('auth/loggedInAs', me.id);
339
+ store.commit('auth/loggedInAs', userData.id);
340
+
341
+ // Init the notification center now that we know who the user is
342
+ await store.dispatch('notifications/init', userData);
343
+
344
+ // Let the extensions know that the user is logged in
345
+ await onExtensionsReady(store);
311
346
  }
312
347
 
313
348
  /**
@@ -0,0 +1,176 @@
1
+ type BackOffEntry = {
2
+ timeoutId?: NodeJS.Timeout,
3
+ try: number,
4
+ retries: number,
5
+ description: string,
6
+ metadata: any,
7
+ }
8
+
9
+ /**
10
+ * Helper class which handles backing off making the supplied request
11
+ *
12
+ * see `execute` for more info
13
+ */
14
+ class BackOff {
15
+ private map: {
16
+ [id: string]: BackOffEntry
17
+ } = {};
18
+
19
+ private log(level: 'error' | 'info' | 'debug', id: string, classDescription: string, description: string, ...args: any[]) {
20
+ console[level](`BackOff... Id: "${ id }". Description: "${ description }"\nStatus: ${ classDescription }\n`, ...args); // eslint-disable-line no-console
21
+ }
22
+
23
+ /**
24
+ * Get a specific back off process
25
+ */
26
+ getBackOff(id: string): BackOffEntry {
27
+ return this.map[id];
28
+ }
29
+
30
+ /**
31
+ * Stop ALL back off processes started since the ui was loaded
32
+ */
33
+ resetAll() {
34
+ Object.keys(this.map).forEach((id) => {
35
+ this.reset(id);
36
+ });
37
+ }
38
+
39
+ /**
40
+ * Stop all back off process with a specific prefix
41
+ */
42
+ resetPrefix(prefix:string) {
43
+ Object.keys(this.map).forEach((id) => {
44
+ if (id.startsWith(prefix)) {
45
+ this.reset(id);
46
+ }
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Stop a back off process with a specific id
52
+ */
53
+ reset(id: string) {
54
+ const backOff: BackOffEntry = this.map[id];
55
+
56
+ if (backOff) {
57
+ if (backOff?.timeoutId) {
58
+ this.log('info', id, 'Stopping (cancelling active back-off)', backOff.description);
59
+
60
+ clearTimeout(backOff.timeoutId);
61
+ }
62
+ this.log('debug', id, 'Reset', backOff.description);
63
+
64
+ delete this.map[id];
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Call a function, but if it's recently been called delay execution aka back off
70
+ *
71
+ * This can be used in a totally disjoined asynchronous way
72
+ *
73
+ * 1. Request function A to be run
74
+ * 2. Entirely separate process requests function A to be run again
75
+ * 3. Back off process waits Xms and then runs function A again
76
+ * 4. Repeat steps 2 and 3, with an exponential increasing delay
77
+ *
78
+ * This can be called repeatedly, if the previous delay is still running new requests will be ignored
79
+ */
80
+ async execute<T = any>({
81
+ id, description, retries = 10, delayedFn, canFn = async() => true, metadata
82
+ }: {
83
+ /**
84
+ * Unique id for the execution of this function.
85
+ *
86
+ * This will be used to delay further executions, and also to cancel it
87
+ */
88
+ id: string,
89
+ /**
90
+ * Basic text description to use in logging
91
+ */
92
+ description: string,
93
+ /**
94
+ * Number of executions allowed before flatly refusing to call more. Defaults to 10
95
+ */
96
+ retries?: number,
97
+ /**
98
+ * Before calling delayedFn check if it can still run
99
+ *
100
+ * Useful for checking state after a looong delay
101
+ */
102
+ canFn?: () => Promise<boolean>,
103
+ /**
104
+ * Call this function
105
+ * - if it's not already waiting to run
106
+ * - if it's passed canFn
107
+ * - if it hasn't been tried over `retries` amount
108
+ *
109
+ * The function will be increasingly (exponentially) delayed if it has previously been called
110
+ */
111
+ delayedFn: () => Promise<any>,
112
+ /**
113
+ * Anything that might be important outside of this file (used with `getBackOff`)
114
+ */
115
+ metadata?: T,
116
+ }): Promise<NodeJS.Timeout | undefined> {
117
+ const backOff: BackOffEntry = this.map[id];
118
+
119
+ const cont = await canFn();
120
+
121
+ if (!cont) {
122
+ this.log('info', id, 'Skipping (can execute fn test failed)', description);
123
+
124
+ return undefined;
125
+ } else if (backOff?.timeoutId) {
126
+ this.log('info', id, 'Skipping (previous back off process still running)', description);
127
+
128
+ return backOff.timeoutId;
129
+ } else {
130
+ const backOffTry = backOff?.try || 0;
131
+
132
+ if (backOffTry + 1 > retries) {
133
+ this.log('error', id, 'Aborting (too many retries)', description);
134
+
135
+ return undefined;
136
+ }
137
+
138
+ // First step is immediate (0.001s)
139
+ // Second and others are exponential
140
+ // 1, 2, 3, 4, 5, 6, 7, 8, 9
141
+ // 1, 4, 9, 16, 25, 36, 49, 64, 81
142
+ // 0.25s, 1s, 2.25s, 4s, 6.25s, 9s, 12.25s, 16s, 20.25s
143
+ const delay = backOffTry === 0 ? 1 : Math.pow(backOffTry, 2) * 250;
144
+
145
+ this.log('info', id, `Delaying call (attempt ${ backOffTry + 1 }, delayed by ${ delay }ms)`, description);
146
+
147
+ const timeout = setTimeout(async() => {
148
+ try {
149
+ this.log('info', id, `Executing call`, description);
150
+
151
+ await delayedFn();
152
+ } catch (e) {
153
+ // Error occurred. Don't clear the map. Next time this is called we'll back off before trying ...
154
+ this.log('error', id, 'Failed call', description, e);
155
+ }
156
+
157
+ // Unblock future calls
158
+ delete this.map[id]?.timeoutId;
159
+ }, delay);
160
+
161
+ this.map[id] = {
162
+ timeoutId: timeout,
163
+ try: backOff?.try ? backOff.try + 1 : 1,
164
+ retries,
165
+ description,
166
+ metadata
167
+ };
168
+
169
+ return timeout;
170
+ }
171
+ }
172
+ }
173
+
174
+ const backOff = new BackOff();
175
+
176
+ export default backOff;
package/utils/cluster.js CHANGED
@@ -6,7 +6,7 @@ import { SETTING } from '@shell/config/settings';
6
6
  import { PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
7
7
  import { compare, sortable } from '@shell/utils/version';
8
8
  import { sortBy } from '@shell/utils/sort';
9
- import { SCHEDULING_CUSTOMIZATION } from '@shell/store/features';
9
+ import { HARVESTER_CONTAINER, SCHEDULING_CUSTOMIZATION } from '@shell/store/features';
10
10
  import { _CREATE, _EDIT } from '@shell/config/query-params';
11
11
  import isEmpty from 'lodash/isEmpty';
12
12
  import { set } from '@shell/utils/object';
@@ -20,15 +20,13 @@ import { set } from '@shell/utils/object';
20
20
  export function paginationFilterClusters(store, filterMgmtCluster = true) {
21
21
  const paginationRequestFilters = [];
22
22
 
23
- // Commenting out for the moment. This is broken for non-paginated world
24
- // filterOnlyKubernetesClusters expects a mgmt cluster, however in the home page it's given a prov cluster
25
- // note - filterHiddenLocalCluster works because it uses model isLocal which is on both cluster types
26
- // const pFilterOnlyKubernetesClusters = paginationFilterOnlyKubernetesClusters(store);
27
- // if (pFilterOnlyKubernetesClusters) {
28
- // paginationRequestFilters.push(pFilterOnlyKubernetesClusters);
29
- // }
23
+ const pFilterOnlyKubernetesClusters = paginationFilterOnlyKubernetesClusters(store);
30
24
  const pFilterHiddenLocalCluster = paginationFilterHiddenLocalCluster(store, filterMgmtCluster);
31
25
 
26
+ if (pFilterOnlyKubernetesClusters) {
27
+ paginationRequestFilters.push(...pFilterOnlyKubernetesClusters);
28
+ }
29
+
32
30
  if (pFilterHiddenLocalCluster) {
33
31
  paginationRequestFilters.push(pFilterHiddenLocalCluster);
34
32
  }
@@ -77,37 +75,43 @@ export function paginationFilterHiddenLocalCluster(store, filterMgmtCluster = tr
77
75
  * @returns PaginationParam | null
78
76
  */
79
77
  export function paginationFilterOnlyKubernetesClusters(store) {
80
- const openHarvesterContainerWorkload = store.getters['features/get']('harvester-baremetal-container-workload');
78
+ const openHarvesterContainerWorkload = store.getters['features/get'](HARVESTER_CONTAINER);
81
79
 
82
- if (!openHarvesterContainerWorkload) {
80
+ if (openHarvesterContainerWorkload) {
81
+ // Show harvester clusters
83
82
  return null;
84
83
  }
85
84
 
86
- return PaginationParamFilter.createMultipleFields([
87
- new PaginationFilterField({
85
+ // Filter out harvester clusters
86
+ return [
87
+ PaginationParamFilter.createSingleField(new PaginationFilterField({
88
88
  field: `metadata.labels[${ CAPI.PROVIDER }]`,
89
89
  equals: false,
90
90
  value: VIRTUAL_HARVESTER_PROVIDER,
91
91
  exact: true
92
- }),
93
- new PaginationFilterField({
92
+ })),
93
+ PaginationParamFilter.createSingleField(new PaginationFilterField({
94
94
  field: `status.provider`,
95
95
  equals: false,
96
96
  value: VIRTUAL_HARVESTER_PROVIDER,
97
97
  exact: true
98
- }),
99
- ]);
98
+ }))
99
+ ];
100
100
  }
101
101
 
102
102
  /**
103
103
  * Filter out any clusters that are not Kubernetes Clusters
104
104
  **/
105
105
  export function filterOnlyKubernetesClusters(mgmtClusters, store) {
106
- const openHarvesterContainerWorkload = store.getters['features/get']('harvester-baremetal-container-workload');
106
+ const openHarvesterContainerWorkload = store.getters['features/get'](HARVESTER_CONTAINER);
107
107
 
108
- return mgmtClusters?.filter((c) => {
109
- return openHarvesterContainerWorkload ? true : !isHarvesterCluster(c);
110
- });
108
+ if (openHarvesterContainerWorkload) {
109
+ // Show harvester clusters
110
+ return mgmtClusters;
111
+ }
112
+
113
+ // Filter out harvester clusters
114
+ return mgmtClusters?.filter((c) => !isHarvesterCluster(c));
111
115
  }
112
116
 
113
117
  export function isHarvesterCluster(mgmtCluster) {