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
@@ -17,11 +17,9 @@ export function syncUpstreamConfig(configPrefix: string, normanCluster: {[key: s
17
17
 
18
18
  if (!isEmpty(upstreamConfig)) {
19
19
  Object.keys(upstreamConfig).forEach((key) => {
20
- if (typeof upstreamConfig[key] === 'object') {
21
- if (isEmpty(rancherConfig[key]) && !isEmpty(upstreamConfig[key])) {
22
- set(rancherConfig, key, upstreamConfig[key]);
23
- }
24
- } else if ((rancherConfig[key] === null || rancherConfig[key] === undefined) && upstreamConfig[key] !== null && upstreamConfig[key] !== undefined) {
20
+ const empty = typeof upstreamConfig[key] === 'object' && isEmpty(upstreamConfig[key]);
21
+
22
+ if ((rancherConfig[key] === null || rancherConfig[key] === undefined) && upstreamConfig[key] !== null && upstreamConfig[key] !== undefined && !empty) {
25
23
  set(rancherConfig, key, upstreamConfig[key]);
26
24
  }
27
25
  });
package/utils/object.js CHANGED
@@ -510,10 +510,6 @@ export function deepToRaw(obj, cache = new WeakSet()) {
510
510
  * with arrays in obj2 when both properties are arrays
511
511
  * false: default lodash merge behavior - recursively merges
512
512
  * array members
513
- * @param {boolean} [options.replaceObjectProps=false] - true: merges objects in
514
- * obj1 with objects in obj2, overwriting duplicate props
515
- * false: default lodash merge behavior - recursively merges
516
- * object props
517
513
  */
518
514
  export function mergeWithReplace(
519
515
  obj1 = {},
@@ -521,7 +517,6 @@ export function mergeWithReplace(
521
517
  {
522
518
  mutateOriginal = false,
523
519
  replaceArray = true,
524
- replaceObjectProps = false,
525
520
  } = {}
526
521
  ) {
527
522
  const destination = mutateOriginal ? obj1 : {};
@@ -530,12 +525,41 @@ export function mergeWithReplace(
530
525
  if (replaceArray && Array.isArray(obj1Value) && Array.isArray(obj2Value)) {
531
526
  return obj2Value;
532
527
  }
533
-
534
- if (replaceObjectProps && isObject(obj1Value) && isObject(obj2Value)) {
535
- return {
536
- ...obj1Value,
537
- ...obj2Value,
538
- };
539
- }
540
528
  });
541
529
  }
530
+ /**
531
+ * Converts Object into a string of a format "key1, val1, key2, val2"
532
+ * @param {Object} input - KV object to convert
533
+ * @returns string
534
+ */
535
+ export const convertKVToString = (input) => {
536
+ if (!input || typeof input !== 'object') return '';
537
+
538
+ return Object.entries(input)
539
+ .flatMap(([key, value]) => [key, String(value)])
540
+ .join(',');
541
+ };
542
+
543
+ /**
544
+ * Converts kv string into object
545
+ * @param {string} input - a string of a format "key1, val1, key2, val2"
546
+ * @returns
547
+ */
548
+ export const convertStringToKV = ( input ) => {
549
+ if (!input?.trim()) return {};
550
+
551
+ const parts = input.split(',').map((part) => part.trim());
552
+ const result = {};
553
+
554
+ for (let i = 0; i < parts.length - 1; i += 2) {
555
+ const key = parts[i];
556
+ const value = parts[i + 1];
557
+
558
+ // Accept empty keys but ignore undefined values
559
+ if (typeof key === 'string') {
560
+ result[key] = value ?? '';
561
+ }
562
+ }
563
+
564
+ return result;
565
+ };
@@ -1,4 +1,4 @@
1
- import { PaginationSettings, PaginationSettingsStore } from '@shell/types/resources/settings';
1
+ import { PaginationFeature, PaginationSettings, PaginationSettingsStore } from '@shell/types/resources/settings';
2
2
  import {
3
3
  NAMESPACE_FILTER_ALL_USER as ALL_USER,
4
4
  NAMESPACE_FILTER_ALL as ALL,
@@ -15,17 +15,22 @@ import { isEqual } from '@shell/utils/object';
15
15
  import { STEVE_CACHE } from '@shell/store/features';
16
16
  import { getPerformanceSetting } from '@shell/utils/settings';
17
17
  import { PAGINATION_SETTINGS_STORE_DEFAULTS } from '@shell/plugins/steve/steve-pagination-utils';
18
+ import { MANAGEMENT } from '@shell/config/types';
18
19
 
19
20
  /**
20
21
  * Helper functions for server side pagination
21
22
  */
22
23
  class PaginationUtils {
24
+ /**
25
+ * In places where we're using paginated features but not in a page... this is what the max results should be
26
+ */
27
+ readonly defaultPageSize = 100000;
23
28
  /**
24
29
  * When a ns filter isn't one or more projects/namespaces... what are the valid values?
25
30
  *
26
31
  * This basically blocks 'Not in a Project'.. which would involve a projectsornamespaces param with every ns not in a project.
27
32
  */
28
- validNsProjectFilters = [ALL, ALL_SYSTEM, ALL_USER, ALL_SYSTEM, NAMESPACE_FILTER_KINDS.NAMESPACE, NAMESPACE_FILTER_KINDS.PROJECT, NAMESPACED_YES, NAMESPACED_NO];
33
+ readonly validNsProjectFilters = [ALL, ALL_SYSTEM, ALL_USER, ALL_SYSTEM, NAMESPACE_FILTER_KINDS.NAMESPACE, NAMESPACE_FILTER_KINDS.PROJECT, NAMESPACED_YES, NAMESPACED_NO];
29
34
 
30
35
  private getSettings({ rootGetters }: any): PaginationSettings {
31
36
  const perf = getPerformanceSetting(rootGetters);
@@ -50,6 +55,23 @@ class PaginationUtils {
50
55
  return rootGetters['features/get']?.(STEVE_CACHE);
51
56
  }
52
57
 
58
+ /**
59
+ * Determine if the downstream cluster has vai enabled
60
+ *
61
+ * Almost all the time the downstream cluster vai state will align with upstream (it manages it)
62
+ * ... unless it's harvester then weird things happen
63
+ */
64
+ async isDownstreamSteveCacheEnabled({ dispatch }: any, clusterId: string): Promise<boolean> {
65
+ const url = `/k8s/clusters/${ clusterId }/v1/${ MANAGEMENT.FEATURE }s/${ STEVE_CACHE }`;
66
+ const entry = await dispatch('cluster/request', { url });
67
+
68
+ if (entry.status.lockedValue !== null) {
69
+ return entry.status.lockedValue;
70
+ }
71
+
72
+ return (entry.spec.value !== null) ? entry.spec.value : entry.status.default;
73
+ }
74
+
53
75
  /**
54
76
  * Is pagination enabled at a global level or for a specific resource
55
77
  */
@@ -62,7 +84,7 @@ class PaginationUtils {
62
84
  const settings = this.getSettings({ rootGetters });
63
85
 
64
86
  // No setting, not enabled
65
- if (!settings?.enabled) {
87
+ if (!settings) {
66
88
  return false;
67
89
  }
68
90
 
@@ -124,6 +146,31 @@ class PaginationUtils {
124
146
  return false;
125
147
  }
126
148
 
149
+ listAutoRefreshToggleEnabled({ rootGetters }: any): boolean {
150
+ return this.isFeatureEnabled({ rootGetters }, 'listAutoRefreshToggle');
151
+ }
152
+
153
+ isListManualRefreshEnabled({ rootGetters }: any): boolean {
154
+ return this.isFeatureEnabled({ rootGetters }, 'listManualRefresh');
155
+ }
156
+
157
+ private isFeatureEnabled({ rootGetters }: any, featureName: PaginationFeature): boolean {
158
+ // Cache must be enabled to support pagination api
159
+ if (!this.isSteveCacheEnabled({ rootGetters })) {
160
+ return false;
161
+ }
162
+
163
+ const settings = this.getSettings({ rootGetters });
164
+
165
+ return !!settings.features?.[featureName]?.enabled;
166
+ }
167
+
168
+ resourceChangesDebounceMs({ rootGetters }: any): number | undefined {
169
+ const settings = this.getSettings({ rootGetters });
170
+
171
+ return settings.resourceChangesDebounceMs;
172
+ }
173
+
127
174
  validateNsProjectFilters(nsProjectFilters: string[]) {
128
175
  return nsProjectFilters?.every((f) => this.validateNsProjectFilter(f));
129
176
  }
@@ -1,70 +1,152 @@
1
1
  import paginationUtils from '@shell/utils/pagination-utils';
2
- import { PaginationArgs, PaginationResourceContext, StorePagination } from '@shell/types/store/pagination.types';
2
+ import { PaginationArgs, PaginationResourceContext } from '@shell/types/store/pagination.types';
3
3
  import { VuexStore } from '@shell/types/store/vuex';
4
- import { ActionFindPageArgs } from '@shell/types/store/dashboard-store.types';
4
+ import { ActionFindPageArgs, ActionFindPageTransientResult } from '@shell/types/store/dashboard-store.types';
5
+ import {
6
+ STEVE_WATCH_EVENT_LISTENER_CALLBACK, STEVE_UNWATCH_EVENT_PARAMS, STEVE_WATCH_EVENT, STEVE_WATCH_EVENT_PARAMS, STEVE_WATCH_EVENT_PARAMS_COMMON, STEVE_WATCH_MODE
7
+ } from '@shell/types/store/subscribe.types';
8
+ import { Reactive, reactive } from 'vue';
5
9
 
6
- interface Result<T> {
7
- data: Array<T>
8
- pagination: StorePagination
10
+ interface Args {
11
+ $store: VuexStore,
12
+ /**
13
+ * Unique ID for this request. Used for watch purposes
14
+ */
15
+ id: string,
16
+ /**
17
+ * Args used when determining if this resource type supports SSP
18
+ */
19
+ enabledFor: PaginationResourceContext,
20
+ /**
21
+ * Callback called when the resource is changed (notified by socket)
22
+ */
23
+ onChange?: () => void,
24
+
25
+ formatResponse?: {
26
+ /**
27
+ * Convert the response into a model class instance
28
+ */
29
+ classify?: boolean,
30
+ reactive?: boolean,
31
+ }
32
+ }
33
+
34
+ interface Result<T> extends Omit<ActionFindPageTransientResult<T>, 'data'> {
35
+ data: Reactive<T[]>
9
36
  }
10
37
 
11
38
  /**
12
- * This is a helper class that will assist in fetching a resource
13
- * - Handle if the resource can be fetched by the new pagination api
14
- * - Make a request to get a page (including classify)
15
- * - Provide updates when the resource changes
39
+ * This is a helper class that will assist in fetching a resource via the new Server-Side Pagination API
16
40
  *
17
41
  * This is designed to work in places where we don't/can't store the resource in the store
18
42
  * - There already exists a resource we don't want to overwrite
19
- * - We're transient and want something nicer than just cluster/request
43
+ * - We're transient and want something nicer than just `cluster/request` + all the trimmings
44
+ *
45
+ * It ...
46
+ * - Handles if the resource can be fetched by the new pagination api
47
+ * - Makes a request to get a page (including optional classify & reactive)
48
+ * - Provide updates when the resource changes
20
49
  */
21
- class PaginationWrapper<T = any> {
22
- private $store: VuexStore;
23
- private enabledFor: PaginationResourceContext;
24
-
25
- // Blocked on https://github.com/rancher/rancher/issues/40773 / https://github.com/rancher/dashboard/issues/12734
26
- private onUpdate: (out: Result<T>) => void;
27
-
28
- public isEnabled: boolean;
29
-
30
- constructor({
31
- $store,
32
- enabledFor,
33
- onUpdate,
34
- }: {
35
- $store: VuexStore,
36
- onUpdate: (res: Result<T>) => void,
37
- enabledFor: PaginationResourceContext,
38
- }) {
39
- this.$store = $store;
40
- this.isEnabled = paginationUtils.isEnabled({ rootGetters: $store.getters }, enabledFor);
41
- this.enabledFor = enabledFor;
42
- this.onUpdate = onUpdate;
50
+ class PaginationWrapper<T extends object> {
51
+ private $store: VuexStore;
52
+ private enabledFor: PaginationResourceContext;
53
+ private onChange?: STEVE_WATCH_EVENT_LISTENER_CALLBACK;
54
+ private id: string;
55
+ private classify: boolean;
56
+ private reactive: boolean;
57
+
58
+ public isEnabled: boolean;
59
+ private steveWatchParams: STEVE_WATCH_EVENT_PARAMS_COMMON | undefined;
60
+
61
+ constructor(args: Args) {
62
+ const {
63
+ $store, id, enabledFor, onChange, formatResponse
64
+ } = args;
65
+
66
+ this.$store = $store;
67
+ this.id = id;
68
+ this.enabledFor = enabledFor;
69
+ this.onChange = onChange;
70
+ this.classify = formatResponse?.classify || false;
71
+ this.reactive = formatResponse?.reactive || false;
72
+
73
+ this.isEnabled = paginationUtils.isEnabled({ rootGetters: $store.getters }, enabledFor);
74
+ }
75
+
76
+ async request(args: {
77
+ pagination: PaginationArgs,
78
+ }): Promise<Result<T>> {
79
+ if (!this.isEnabled) {
80
+ throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ this.enabledFor.resource?.id }' in context '${ this.enabledFor.resource?.context }' not supported`);
81
+ }
82
+ const { pagination } = args;
83
+ const opt: ActionFindPageArgs = {
84
+ watch: false,
85
+ pagination,
86
+ transient: true,
87
+ };
88
+
89
+ // Fetch
90
+ const out: ActionFindPageTransientResult<T> = await this.$store.dispatch(`${ this.enabledFor.store }/findPage`, { opt, type: this.enabledFor.resource?.id });
91
+
92
+ // Watch
93
+ if (this.onChange && !this.steveWatchParams) {
94
+ this.steveWatchParams = {
95
+ event: STEVE_WATCH_EVENT.CHANGES,
96
+ id: this.id,
97
+ params: {
98
+ type: this.enabledFor.resource?.id as string,
99
+ mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
100
+ }
101
+ };
102
+
103
+ this.watch();
43
104
  }
44
105
 
45
- async request(args: {
46
- pagination: PaginationArgs,
47
- classify?: boolean,
48
- }): Promise<Result<T>> {
49
- if (!this.isEnabled) {
50
- throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ this.enabledFor.resource?.id }' in context '${ this.enabledFor.resource?.context }' not supported`);
51
- }
52
- const { pagination, classify: doClassify } = args;
53
- const opt: ActionFindPageArgs = {
54
- transient: true,
55
- pagination
106
+ // Convert Response
107
+ if (this.classify) {
108
+ out.data = await this.$store.dispatch(`${ this.enabledFor.store }/createMany`, out.data);
109
+ }
110
+
111
+ if (this.reactive) {
112
+ return {
113
+ ...out,
114
+ data: reactive(out.data)
56
115
  };
116
+ }
57
117
 
58
- const out: Result<T> = await this.$store.dispatch(`${ this.enabledFor.store }/findPage`, { opt, type: this.enabledFor.resource?.id });
118
+ return out;
119
+ }
59
120
 
60
- if (doClassify) {
61
- for (let i = 0; i < out.data.length; i++) {
62
- out.data[i] = await this.$store.dispatch(`${ this.enabledFor.store }/create`, out.data[i]);
63
- }
64
- }
121
+ private async watch() {
122
+ if (!this.steveWatchParams) {
123
+ console.error('Calling watch but no watch params created'); // eslint-disable-line no-console
65
124
 
66
- return out;
125
+ return;
67
126
  }
127
+ const watchParams: STEVE_WATCH_EVENT_PARAMS = {
128
+ ...this.steveWatchParams,
129
+ callback: this.onChange as STEVE_WATCH_EVENT_LISTENER_CALLBACK, // we must have it by now
130
+ };
131
+
132
+ await this.$store.dispatch(`${ this.enabledFor.store }/watchEvent`, watchParams);
133
+ }
134
+
135
+ private async unWatch() {
136
+ if (!this.steveWatchParams) {
137
+ console.error('Calling unWatch but no watch params created'); // eslint-disable-line no-console
138
+
139
+ return;
140
+ }
141
+
142
+ const unWatchParams: STEVE_UNWATCH_EVENT_PARAMS = { ...this.steveWatchParams };
143
+
144
+ await this.$store.dispatch(`${ this.enabledFor.store }/unwatchEvent`, unWatchParams);
145
+ }
146
+
147
+ async onDestroy() {
148
+ await this.unWatch();
149
+ }
68
150
  }
69
151
 
70
152
  export default PaginationWrapper;
@@ -0,0 +1,28 @@
1
+ import { PerfSettings } from '@shell/config/settings';
2
+
3
+ type PaginationSupersedesSettings = 'incrementalLoading' | 'manualRefresh'
4
+
5
+ class _Utils {
6
+ private setting: PaginationSupersedesSettings;
7
+ constructor(setting: PaginationSupersedesSettings) {
8
+ this.setting = setting;
9
+ }
10
+
11
+ /**
12
+ * This is a centralised point to ensure SSP takes precedence over the performance setting
13
+ */
14
+ isEnabled(paginationEnabled: boolean, perfSettings: PerfSettings): boolean {
15
+ return !paginationEnabled && perfSettings[this.setting].enabled;
16
+ }
17
+ }
18
+
19
+ export default {
20
+ /**
21
+ * Helper functions for the 'incremental loading indicator' performance settings
22
+ */
23
+ incrementalLoadingUtils: new _Utils('incrementalLoading'),
24
+ /**
25
+ * Helper functions for the 'manual refresh' performance settings
26
+ */
27
+ manualRefreshUtils: new _Utils('manualRefresh'),
28
+ };
@@ -0,0 +1,48 @@
1
+ import { getVersionData } from '@shell/config/version';
2
+ import { READ_WHATS_NEW } from '@shell/store/prefs';
3
+ import { NotificationLevel } from '@shell/types/notifications';
4
+
5
+ export async function addReleaseNotesNotification(dispatch: any, getters: any) {
6
+ const rancherVersion = getVersionData().Version.split('-')[0];
7
+ const prefix = 'release-notes-';
8
+ const id = `${ prefix }${ rancherVersion }`;
9
+ let found = false;
10
+ const all = getters['notifications/all'];
11
+ const lastReadVersion = getters['prefs/get'](READ_WHATS_NEW) || '';
12
+ const t = getters['i18n/t'];
13
+ const releaseNotesUrl = getters['releaseNotesUrl'];
14
+
15
+ // Delete notification(s) for old release notes
16
+ for (let i = 0; i < all.length; i++) {
17
+ const notification = all[i];
18
+
19
+ if (notification.id.startsWith(prefix)) {
20
+ if (notification.id === id) {
21
+ found = true;
22
+ } else {
23
+ await dispatch('notifications/delete', notification.id);
24
+ }
25
+ }
26
+ }
27
+
28
+ // Also use pref, so if we expired it, we don't add it back
29
+ if (!found && lastReadVersion !== rancherVersion) {
30
+ // Register notification
31
+ const notification = {
32
+ id,
33
+ level: NotificationLevel.Info,
34
+ title: t('landing.whatsNew.title', { version: rancherVersion }),
35
+ message: t('landing.whatsNew.message'),
36
+ preference: {
37
+ key: READ_WHATS_NEW,
38
+ value: rancherVersion
39
+ },
40
+ primaryAction: {
41
+ label: t('landing.whatsNew.link'),
42
+ target: releaseNotesUrl
43
+ }
44
+ };
45
+
46
+ await dispatch('notifications/add', notification);
47
+ }
48
+ }
@@ -0,0 +1,210 @@
1
+ import { COUNT } from '@shell/config/types';
2
+ import { KubeLabelSelector, KubeLabelSelectorExpression } from '@shell/types/kube/kube-api';
3
+ import { ActionFindPageArgs } from '@shell/types/store/dashboard-store.types';
4
+ import { FilterArgs, PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
5
+ import { isEmpty } from '@shell/utils/object';
6
+ import { convert, matching as rootMatching } from '@shell/utils/selector';
7
+
8
+ type MatchingResponse = {
9
+ matched: number,
10
+ matches: any[],
11
+ none: boolean,
12
+ sample: any,
13
+ total: number,
14
+ }
15
+
16
+ /**
17
+ * Find resources that match a labelSelector. This behaves differently if vai based pagination is on
18
+ * a) Pagination Enabled - fetch matching resources filtered on backend - findPage
19
+ * b) Pagination Disabled - fetch all resources and then filter locally - findAll --> root `matching` fn
20
+ *
21
+ * This is a much smarter version of root matching fn `matching` from shell/utils/selector.js (which just does local filtering)
22
+ *
23
+ * If fetching all of a resource should be avoided or we don't want to mess around with the cache the action `findLabelSelector` should be used
24
+ * - sometimes some legacy code expects all resources are fetched
25
+ * - sometimes we want to fetch a resource but not override the cache
26
+ * - already have a pods list cached, don't want to overwrite that when finding pods associated with a service
27
+ *
28
+ * Resources are returned in a common format which includes metadata
29
+ */
30
+ export async function matching({
31
+ labelSelector,
32
+ type,
33
+ inStore,
34
+ $store,
35
+ inScopeCount = undefined,
36
+ namespace = undefined,
37
+ transient = true,
38
+ }: {
39
+ /**
40
+ * Standard kube label selector object.
41
+ *
42
+ * If this is 'empty' (no matchLabels or matchExpressions) it will return all results
43
+ *
44
+ * If this is 'null' it will return no results
45
+ */
46
+ labelSelector: KubeLabelSelector,
47
+ /**
48
+ * Resource type
49
+ */
50
+ type: string,
51
+ /**
52
+ * Store in which resources will be cached
53
+ */
54
+ inStore: string,
55
+ /**
56
+ * Standard vuex store object
57
+ */
58
+ $store: any,
59
+ /**
60
+ * Number of resources that are applicable when filtering.
61
+ *
62
+ * Used to skip any potential http request if we know the result will be zero
63
+ *
64
+ * If this property is not supplied we'll try and discover it from the COUNTS resource.
65
+ */
66
+ inScopeCount?: number
67
+ /**
68
+ * Optional namespace or namespaces to apply selector to
69
+ *
70
+ * If this is undefined then namespaces will totally be ignored
71
+ *
72
+ * If this is provided all resources must be within them. If an empty array is provided then no resources will be matched
73
+ *
74
+ */
75
+ namespace?: string | string[],
76
+ /**
77
+ * Should the result bypass the store?
78
+ */
79
+ transient?: boolean,
80
+ }): Promise<MatchingResponse> {
81
+ const isNamespaced = $store.getters[`${ inStore }/schemaFor`](type)?.attributes.namespaced;
82
+ const safeNamespaces = Array.isArray(namespace) ? namespace : !!namespace ? [namespace] : [];
83
+ const filterByNamespaces = isNamespaced && !!namespace ; // Result set must come from a resource in a namespace
84
+
85
+ // Determine if there's actually anything to filter on
86
+ if (typeof inScopeCount === 'undefined') {
87
+ const counts = $store.getters[`${ inStore }/all`](COUNT)?.[0]?.counts || {};
88
+
89
+ if (filterByNamespaces) {
90
+ inScopeCount = 0;
91
+ safeNamespaces.forEach((n) => {
92
+ inScopeCount += counts?.[type]?.namespaces[n]?.count || 0;
93
+ });
94
+ } else {
95
+ inScopeCount = counts?.[type]?.summary?.count || 0;
96
+ }
97
+ }
98
+
99
+ // Exit early if there are any situations that always return nothing
100
+ const noCandidates = (inScopeCount || 0) === 0;
101
+ const filterByNamespaceButNoNamespace = isNamespaced && !!namespace && (!safeNamespaces || safeNamespaces.length === 0);
102
+ const explicityNullLabelSelector = labelSelector === null || (labelSelector?.matchLabels === null && !labelSelector.matchExpressions === null);
103
+
104
+ // If we have matchLabels or matchExpression entries they must have a key
105
+ const matchLabelKeys = Object.keys(labelSelector.matchLabels || {});
106
+ const invalidMatchLabelKeys = matchLabelKeys.length && matchLabelKeys.filter((k) => !k).length;
107
+ const invalidMatchExpressionKeys = labelSelector?.matchExpressions?.length && labelSelector.matchExpressions.filter((me) => !me.key).length;
108
+
109
+ if (noCandidates || filterByNamespaceButNoNamespace || explicityNullLabelSelector || invalidMatchLabelKeys || invalidMatchExpressionKeys) {
110
+ return generateMatchingResponse([], inScopeCount || 0);
111
+ }
112
+
113
+ if ($store.getters[`${ inStore }/paginationEnabled`]?.({ id: type })) {
114
+ if (isLabelSelectorEmpty(labelSelector) && (!!namespace && !safeNamespaces?.length)) {
115
+ // no namespaces - ALL resources are candidates
116
+ // no labels - return all candidates
117
+ // too many to fetch...
118
+ throw new Error('Either populated labelSelector or namespace/s must be supplied in order to call findPage');
119
+ }
120
+
121
+ const findPageArgs: ActionFindPageArgs = {
122
+ pagination: new FilterArgs({
123
+ labelSelector,
124
+ filters: PaginationParamFilter.createMultipleFields(
125
+ safeNamespaces.map(
126
+ (n) => new PaginationFilterField({
127
+ field: 'metadata.namespace', // API only compatible with steve atm...
128
+ value: n,
129
+ })
130
+ )
131
+ ),
132
+ }),
133
+ transient,
134
+ };
135
+
136
+ let match = await $store.dispatch(`${ inStore }/findPage`, { type, opt: findPageArgs });
137
+
138
+ if (transient) {
139
+ match = match.data;
140
+ }
141
+
142
+ return generateMatchingResponse(match, inScopeCount || 0);
143
+ } else {
144
+ // Start off with everything as a candidate
145
+ let candidates = await $store.dispatch(`${ inStore }/findAll`, { type });
146
+
147
+ inScopeCount = candidates.length;
148
+
149
+ // Filter out namespace specific stuff
150
+ if (isNamespaced && safeNamespaces?.length > 0) {
151
+ candidates = candidates.filter((e: any) => safeNamespaces.includes(e.metadata?.namespace));
152
+ inScopeCount = candidates.length;
153
+ }
154
+
155
+ // Apply labelSelector
156
+ if (labelSelector.matchLabels || labelSelector.matchExpressions) {
157
+ candidates = matches(candidates, labelSelector, 'metadata.labels');
158
+ }
159
+
160
+ return generateMatchingResponse(candidates, inScopeCount || 0);
161
+ }
162
+ }
163
+
164
+ const generateMatchingResponse = <T extends { [key: string]: any, nameDisplay: string}>(match: T[], inScopeCount: number): MatchingResponse => {
165
+ const matched = match.length || 0;
166
+ const sample = match[0]?.nameDisplay;
167
+
168
+ return {
169
+ matched,
170
+ matches: match,
171
+ none: matched === 0,
172
+ sample,
173
+ total: inScopeCount || 0,
174
+ };
175
+ };
176
+
177
+ /**
178
+ * This is similar to shell/utils/selector.js `matches`, but accepts a kube labelSelector
179
+ */
180
+ function matches<T = any>(candidates: T[], labelSelector: KubeLabelSelector, labelKey: string): T[] {
181
+ const convertedObject = convert(labelSelector.matchLabels, labelSelector.matchExpressions);
182
+
183
+ return rootMatching(candidates, convertedObject, labelKey);
184
+ }
185
+
186
+ export function isLabelSelectorEmpty(labelSelector?: KubeLabelSelector): boolean {
187
+ return !labelSelector?.matchExpressions?.length && isEmpty(labelSelector?.matchLabels);
188
+ }
189
+
190
+ export function labelSelectorToSelector(labelSelector?: KubeLabelSelector): string {
191
+ if (isLabelSelectorEmpty(labelSelector)) {
192
+ return '';
193
+ }
194
+
195
+ const res: string[] = [];
196
+
197
+ Object.entries(labelSelector?.matchLabels || {}).forEach(([key, value]) => {
198
+ res.push(`${ key }=${ value }`);
199
+ });
200
+
201
+ (labelSelector?.matchExpressions || []).forEach((value: KubeLabelSelectorExpression) => {
202
+ if (value.operator === 'In' && value.values?.length === 1) {
203
+ res.push(`${ value.key }=${ value.values[0] }`);
204
+ } else {
205
+ throw new Error(`Unsupported matchExpression found when converting to selector string. ${ value }`);
206
+ }
207
+ });
208
+
209
+ return res.join(',');
210
+ }