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
@@ -0,0 +1,1224 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import flushPromises from 'flush-promises';
3
+ import FleetClusterTargets from '@shell/components/fleet/FleetClusterTargets/index.vue';
4
+ import { _CREATE, _EDIT } from '@shell/config/query-params';
5
+ import { Selector } from '@shell/types/fleet';
6
+
7
+ describe('component: FleetClusterTargets', () => {
8
+ describe('mode: edit', () => {
9
+ const mode = _EDIT;
10
+
11
+ describe('decode spec.targets and set form data', () => {
12
+ it('should build form source data from target with clusterName and clusterSelector', () => {
13
+ const target1 = {
14
+ clusterName: 'fleet-5-france',
15
+ clusterSelector: { matchLabels: { foo: 'true' } }
16
+ };
17
+ const wrapper = mount(FleetClusterTargets, {
18
+ props: {
19
+ targets: [target1],
20
+ namespace: 'fleet-default',
21
+ mode
22
+ },
23
+ });
24
+
25
+ const targetMode = wrapper.vm.targetMode;
26
+ const selectedClusters = wrapper.vm.selectedClusters;
27
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
28
+
29
+ expect(targetMode).toBe('clusters');
30
+ expect(selectedClusters).toStrictEqual([target1.clusterName]);
31
+ expect(clusterSelectors[0].matchLabels).toStrictEqual(target1.clusterSelector.matchLabels);
32
+ expect(clusterSelectors[0].matchExpressions).toBeUndefined();
33
+ });
34
+
35
+ it('should set targetMode to "all" and correctly filter clusterSelector for harvester rule', () => {
36
+ const target1 = {
37
+ clusterSelector: {
38
+ matchExpressions: [{
39
+ key: 'provider.cattle.io',
40
+ operator: 'NotIn',
41
+ values: ['harvester']
42
+ }]
43
+ }
44
+ };
45
+ const wrapper = mount(FleetClusterTargets, {
46
+ props: {
47
+ targets: [target1],
48
+ namespace: 'fleet-default',
49
+ mode,
50
+ },
51
+ });
52
+
53
+ const targetMode = wrapper.vm.targetMode;
54
+ const selectedClusters = wrapper.vm.selectedClusters;
55
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
56
+
57
+ expect(targetMode).toBe('all');
58
+ expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
59
+ expect(selectedClusters).toStrictEqual([]);
60
+ });
61
+
62
+ it('should set targetMode to "clusters" and populate selectedClusters and clusterSelectors', () => {
63
+ const target1 = { clusterName: 'fleet-5-france' };
64
+
65
+ const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
66
+
67
+ const wrapper = mount(FleetClusterTargets, {
68
+ props: {
69
+ targets: [target1, target2],
70
+ namespace: 'fleet-default',
71
+ mode
72
+ },
73
+ });
74
+
75
+ const targetMode = wrapper.vm.targetMode;
76
+ const selectedClusters = wrapper.vm.selectedClusters;
77
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
78
+
79
+ expect(targetMode).toBe('clusters');
80
+ expect(selectedClusters).toStrictEqual(['fleet-5-france']);
81
+ expect(clusterSelectors).toStrictEqual([{
82
+ key: 0,
83
+ matchLabels: { foo: 'true' },
84
+ matchExpressions: undefined
85
+ }]);
86
+ });
87
+
88
+ it('should set targetMode to "clusters" and populate clusterSelectors with multiple entries', () => {
89
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
90
+ const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
91
+
92
+ const wrapper = mount(FleetClusterTargets, {
93
+ props: {
94
+ targets: [target1, target2],
95
+ namespace: 'fleet-default',
96
+ mode
97
+ },
98
+ });
99
+
100
+ const targetMode = wrapper.vm.targetMode;
101
+ const selectedClusters = wrapper.vm.selectedClusters;
102
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
103
+
104
+ expect(targetMode).toBe('clusters');
105
+ expect(selectedClusters).toStrictEqual([]);
106
+ expect(clusterSelectors).toStrictEqual([{
107
+ key: 0,
108
+ matchLabels: { foo: 'true' },
109
+ matchExpressions: undefined
110
+ }, {
111
+ key: 1,
112
+ matchLabels: { hci: 'true' },
113
+ matchExpressions: undefined
114
+ }]);
115
+ });
116
+
117
+ it('should set targetMode to "advanced" and return early if clusterGroupSelector is present', () => {
118
+ const target1 = { clusterGroupSelector: {} };
119
+
120
+ const wrapper = mount(FleetClusterTargets, {
121
+ props: {
122
+ targets: [target1],
123
+ namespace: 'fleet-default',
124
+ mode
125
+ },
126
+ });
127
+
128
+ const targetMode = wrapper.vm.targetMode;
129
+ const selectedClusters = wrapper.vm.selectedClusters;
130
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
131
+
132
+ expect(targetMode).toBe('advanced');
133
+ // Expect no further processing for selectedClusters or clusterSelectors due to early return
134
+ expect(selectedClusters).toStrictEqual([]);
135
+ expect(clusterSelectors).toStrictEqual([]);
136
+ });
137
+
138
+ it('should set targetMode to "advanced" and return early if clusterGroup is present', () => {
139
+ const target1 = {
140
+ clusterGroup: 'cg1',
141
+ clusterGroupSelector: {
142
+ matchExpressions: [{
143
+ key: 'string',
144
+ operator: 'string',
145
+ values: ['string']
146
+ }],
147
+ matchLabels: { foo: 'bar' }
148
+ },
149
+ clusterName: 'pippo',
150
+ clusterSelector: {
151
+ matchExpressions: [{
152
+ key: 'string',
153
+ operator: 'string',
154
+ values: ['vvv']
155
+ }],
156
+ matchLabels: { foo: 'bar' }
157
+ },
158
+ name: 'tt1',
159
+ };
160
+
161
+ const wrapper = mount(FleetClusterTargets, {
162
+ props: {
163
+ targets: [target1],
164
+ namespace: 'fleet-default',
165
+ mode
166
+ },
167
+ });
168
+
169
+ const targetMode = wrapper.vm.targetMode;
170
+ const selectedClusters = wrapper.vm.selectedClusters;
171
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
172
+
173
+ expect(targetMode).toBe('advanced');
174
+ // Expect no further processing for selectedClusters or clusterSelectors due to early return
175
+ expect(selectedClusters).toStrictEqual([]);
176
+ expect(clusterSelectors).toStrictEqual([]);
177
+ });
178
+
179
+ it('should return early and not modify state if targets is empty', () => {
180
+ const wrapper = mount(FleetClusterTargets, {
181
+ props: {
182
+ targets: [],
183
+ namespace: 'fleet-default',
184
+ mode
185
+ },
186
+ });
187
+
188
+ const targetMode = wrapper.vm.targetMode;
189
+ const selectedClusters = wrapper.vm.selectedClusters;
190
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
191
+
192
+ expect(targetMode).toBe('none');
193
+ expect(selectedClusters).toStrictEqual([]);
194
+ expect(clusterSelectors).toStrictEqual([]);
195
+ });
196
+
197
+ it('should return targetMode local if namespace is fleet-local', () => {
198
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
199
+ const wrapper = mount(FleetClusterTargets, {
200
+ props: {
201
+ targets: [target1],
202
+ namespace: 'fleet-local',
203
+ mode
204
+ },
205
+ });
206
+
207
+ const targetMode = wrapper.vm.targetMode;
208
+
209
+ expect(targetMode).toBe('local');
210
+ });
211
+
212
+ it('should handle targets with multiple clusterName', () => {
213
+ const target1 = { clusterName: 'prod-cluster' };
214
+ const target2 = { clusterName: 'test-cluster' };
215
+ const wrapper = mount(FleetClusterTargets, {
216
+ props: {
217
+ targets: [target1, target2],
218
+ namespace: 'fleet-default',
219
+ mode
220
+ },
221
+ });
222
+
223
+ const targetMode = wrapper.vm.targetMode;
224
+ const selectedClusters = wrapper.vm.selectedClusters;
225
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
226
+
227
+ expect(targetMode).toBe('clusters');
228
+ expect(selectedClusters).toStrictEqual(['prod-cluster', 'test-cluster']);
229
+ expect(clusterSelectors).toStrictEqual([]);
230
+ });
231
+
232
+ it('should filter out harvester rule and leave others', () => {
233
+ const target1 = {
234
+ clusterSelector: {
235
+ matchExpressions: [{
236
+ key: 'provider.cattle.io',
237
+ operator: 'NotIn',
238
+ values: ['harvester']
239
+ }, {
240
+ key: 'foo',
241
+ operator: 'In',
242
+ values: ['bar']
243
+ }]
244
+ }
245
+ };
246
+
247
+ const wrapper = mount(FleetClusterTargets, {
248
+ props: {
249
+ targets: [target1],
250
+ namespace: 'fleet-default',
251
+ mode
252
+ },
253
+ });
254
+
255
+ const targetMode = wrapper.vm.targetMode;
256
+ const selectedClusters = wrapper.vm.selectedClusters;
257
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
258
+
259
+ expect(targetMode).toBe('clusters');
260
+ expect(selectedClusters).toStrictEqual([]);
261
+ expect(clusterSelectors).toStrictEqual([{
262
+ key: 0,
263
+ matchLabels: undefined,
264
+ matchExpressions: [{
265
+ key: 'foo',
266
+ operator: 'In',
267
+ values: ['bar']
268
+ }]
269
+ }]);
270
+ });
271
+
272
+ it('should correctly process targets when targetMode is "all" and no clusterName or clusterSelector is present', () => {
273
+ const target1 = { name: 'simple-target' };
274
+
275
+ const wrapper = mount(FleetClusterTargets, {
276
+ props: {
277
+ targets: [target1],
278
+ namespace: 'fleet-default',
279
+ mode,
280
+ },
281
+ });
282
+
283
+ const targetMode = wrapper.vm.targetMode;
284
+ const selectedClusters = wrapper.vm.selectedClusters;
285
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
286
+
287
+ expect(targetMode).toBe('all');
288
+ expect(selectedClusters).toStrictEqual([]);
289
+ expect(clusterSelectors).toStrictEqual([]);
290
+ });
291
+
292
+ it('should correctly process targets when targetMode is "all", name is defined and harvester rule is present', () => {
293
+ const target1 = {
294
+ clusterSelector: {
295
+ matchExpressions: [{
296
+ key: 'provider.cattle.io',
297
+ operator: 'NotIn',
298
+ values: ['harvester']
299
+ }]
300
+ },
301
+ name: 'simple-target'
302
+ };
303
+
304
+ const wrapper = mount(FleetClusterTargets, {
305
+ props: {
306
+ targets: [target1],
307
+ namespace: 'fleet-default',
308
+ mode,
309
+ },
310
+ });
311
+
312
+ const targetMode = wrapper.vm.targetMode;
313
+ const selectedClusters = wrapper.vm.selectedClusters;
314
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
315
+
316
+ expect(targetMode).toBe('all');
317
+ expect(selectedClusters).toStrictEqual([]);
318
+ expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
319
+ });
320
+ });
321
+
322
+ describe('decode form data and emit to spec.targets', () => {
323
+ it('should emit target with clusterName and clusterSelector', async() => {
324
+ const target1 = {
325
+ clusterName: 'fleet-5-france',
326
+ clusterSelector: { matchLabels: { foo: 'true' } }
327
+ };
328
+ const wrapper = mount(FleetClusterTargets, {
329
+ props: {
330
+ targets: [target1],
331
+ namespace: 'fleet-default',
332
+ mode,
333
+ },
334
+ });
335
+
336
+ wrapper.vm.update();
337
+
338
+ await flushPromises();
339
+
340
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
341
+ });
342
+
343
+ it('should emit harvester exclude rule', async() => {
344
+ const target1 = {
345
+ clusterSelector: {
346
+ matchExpressions: [{
347
+ key: 'provider.cattle.io',
348
+ operator: 'NotIn',
349
+ values: ['harvester']
350
+ }]
351
+ }
352
+ };
353
+ const wrapper = mount(FleetClusterTargets, {
354
+ props: {
355
+ targets: [target1],
356
+ namespace: 'fleet-default',
357
+ mode,
358
+ },
359
+ });
360
+
361
+ wrapper.vm.update();
362
+ await flushPromises();
363
+
364
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
365
+ clusterSelector: {
366
+ matchExpressions: [{
367
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
368
+ }]
369
+ }
370
+ }]);
371
+ });
372
+
373
+ it('should emit multiple targets with clusterName and clusterSelector', async() => {
374
+ const target1 = { clusterName: 'fleet-5-france' };
375
+
376
+ const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
377
+
378
+ const wrapper = mount(FleetClusterTargets, {
379
+ props: {
380
+ targets: [target1, target2],
381
+ namespace: 'fleet-default',
382
+ mode,
383
+ },
384
+ });
385
+
386
+ wrapper.vm.update();
387
+ await flushPromises();
388
+
389
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
390
+ });
391
+
392
+ it('should emit multiple targets containing both clusterSelector fields', async() => {
393
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
394
+ const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
395
+
396
+ const wrapper = mount(FleetClusterTargets, {
397
+ props: {
398
+ targets: [target1, target2],
399
+ namespace: 'fleet-default',
400
+ mode,
401
+ },
402
+ });
403
+
404
+ wrapper.vm.update();
405
+ await flushPromises();
406
+
407
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }, { clusterSelector: { matchLabels: { hci: 'true' } } }]);
408
+ });
409
+
410
+ it('should emit advanced cases untouched', async() => {
411
+ const target1 = { clusterGroupSelector: {} };
412
+
413
+ const wrapper = mount(FleetClusterTargets, {
414
+ props: {
415
+ targets: [target1],
416
+ namespace: 'fleet-default',
417
+ mode,
418
+ },
419
+ });
420
+
421
+ wrapper.vm.update();
422
+ await flushPromises();
423
+
424
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterGroupSelector: {} }]);
425
+ });
426
+
427
+ it('should emit full target definition', async() => {
428
+ const target1 = {
429
+ clusterGroup: 'cg1',
430
+ clusterGroupSelector: {
431
+ matchExpressions: [{
432
+ key: 'string',
433
+ operator: 'string',
434
+ values: ['string']
435
+ }],
436
+ matchLabels: { foo: 'bar' }
437
+ },
438
+ clusterName: 'pippo',
439
+ clusterSelector: {
440
+ matchExpressions: [{
441
+ key: 'string',
442
+ operator: 'string',
443
+ values: ['vvv']
444
+ }],
445
+ matchLabels: { foo: 'bar' }
446
+ },
447
+ name: 'tt1',
448
+ };
449
+
450
+ const wrapper = mount(FleetClusterTargets, {
451
+ props: {
452
+ targets: [target1],
453
+ namespace: 'fleet-default',
454
+ mode,
455
+ },
456
+ });
457
+
458
+ wrapper.vm.update();
459
+ await flushPromises();
460
+
461
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
462
+ clusterGroup: 'cg1',
463
+ clusterGroupSelector: {
464
+ matchExpressions: [{
465
+ key: 'string', operator: 'string', values: ['string']
466
+ }],
467
+ matchLabels: { foo: 'bar' }
468
+ },
469
+ clusterName: 'pippo',
470
+ clusterSelector: {
471
+ matchExpressions: [{
472
+ key: 'string', operator: 'string', values: ['vvv']
473
+ }],
474
+ matchLabels: { foo: 'bar' }
475
+ },
476
+ name: 'tt1'
477
+ }]);
478
+ });
479
+
480
+ it('should emit harvester rule from empty targets source', async() => {
481
+ const wrapper = mount(FleetClusterTargets, {
482
+ props: {
483
+ targets: [], // targetMode === 'none'
484
+ namespace: 'fleet-default',
485
+ mode,
486
+ },
487
+ });
488
+
489
+ wrapper.vm.update();
490
+ await flushPromises();
491
+
492
+ expect(wrapper.emitted('update:value')?.[0][0]).toBeUndefined();
493
+ });
494
+
495
+ it('should emit untouched targets from source when operating in fleet-local workspace', async() => {
496
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
497
+
498
+ const wrapper = mount(FleetClusterTargets, {
499
+ props: {
500
+ targets: [target1],
501
+ namespace: 'fleet-local',
502
+ mode,
503
+ },
504
+ });
505
+
506
+ wrapper.vm.update();
507
+ await flushPromises();
508
+
509
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }]);
510
+ });
511
+
512
+ it('should emit custom targets filtering out harvester rule', async() => {
513
+ const target1 = {
514
+ clusterSelector: {
515
+ matchExpressions: [{
516
+ key: 'provider.cattle.io',
517
+ operator: 'NotIn',
518
+ values: ['harvester']
519
+ }, {
520
+ key: 'foo',
521
+ operator: 'In',
522
+ values: ['bar']
523
+ }]
524
+ }
525
+ };
526
+
527
+ const wrapper = mount(FleetClusterTargets, {
528
+ props: {
529
+ targets: [target1],
530
+ namespace: 'fleet-default',
531
+ mode,
532
+ },
533
+ });
534
+
535
+ wrapper.vm.update();
536
+ await flushPromises();
537
+
538
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
539
+ clusterSelector: {
540
+ matchExpressions: [{
541
+ key: 'foo', operator: 'In', values: ['bar']
542
+ }]
543
+ }
544
+ }]);
545
+ });
546
+
547
+ it('should emit targets excluding target names and adding harvester rule', async() => {
548
+ const target1 = { name: 'simple-target' };
549
+
550
+ const wrapper = mount(FleetClusterTargets, {
551
+ props: {
552
+ targets: [target1],
553
+ namespace: 'fleet-default',
554
+ mode,
555
+ },
556
+ });
557
+
558
+ wrapper.vm.update();
559
+ await flushPromises();
560
+
561
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
562
+ clusterSelector: {
563
+ matchExpressions: [{
564
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
565
+ }]
566
+ }
567
+ }]);
568
+ });
569
+
570
+ it('should emit targets excluding target names and harvester rule if present in source targets', async() => {
571
+ const target1 = {
572
+ clusterSelector: {
573
+ matchExpressions: [{
574
+ key: 'provider.cattle.io',
575
+ operator: 'NotIn',
576
+ values: ['harvester']
577
+ }]
578
+ },
579
+ name: 'simple-target'
580
+ };
581
+
582
+ const wrapper = mount(FleetClusterTargets, {
583
+ props: {
584
+ targets: [target1],
585
+ namespace: 'fleet-default',
586
+ mode,
587
+ },
588
+ });
589
+
590
+ wrapper.vm.update();
591
+ await flushPromises();
592
+
593
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
594
+ clusterSelector: {
595
+ matchExpressions: [{
596
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
597
+ }]
598
+ }
599
+ }]);
600
+ });
601
+ });
602
+ });
603
+
604
+ describe('mode: create', () => {
605
+ const mode = _CREATE;
606
+
607
+ describe('decode spec.targets and set form data', () => {
608
+ it('should build form source data from target with clusterName and clusterSelector', () => {
609
+ const target1 = {
610
+ clusterName: 'fleet-5-france',
611
+ clusterSelector: { matchLabels: { foo: 'true' } }
612
+ };
613
+ const wrapper = mount(FleetClusterTargets, {
614
+ props: {
615
+ targets: [target1],
616
+ namespace: 'fleet-default',
617
+ mode,
618
+ created: 'clusters'
619
+ },
620
+ });
621
+
622
+ const targetMode = wrapper.vm.targetMode;
623
+ const selectedClusters = wrapper.vm.selectedClusters;
624
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
625
+
626
+ expect(targetMode).toBe('clusters');
627
+ expect(selectedClusters).toStrictEqual([target1.clusterName]);
628
+ expect(clusterSelectors[0].matchLabels).toStrictEqual(target1.clusterSelector.matchLabels);
629
+ expect(clusterSelectors[0].matchExpressions).toBeUndefined();
630
+ });
631
+
632
+ it('should set targetMode to "all" and correctly filter clusterSelector for harvester rule', () => {
633
+ const target1 = {
634
+ clusterSelector: {
635
+ matchExpressions: [{
636
+ key: 'provider.cattle.io',
637
+ operator: 'NotIn',
638
+ values: ['harvester']
639
+ }]
640
+ }
641
+ };
642
+ const wrapper = mount(FleetClusterTargets, {
643
+ props: {
644
+ targets: [target1],
645
+ namespace: 'fleet-default',
646
+ mode,
647
+ },
648
+ });
649
+
650
+ const targetMode = wrapper.vm.targetMode;
651
+ const selectedClusters = wrapper.vm.selectedClusters;
652
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
653
+
654
+ expect(targetMode).toBe('all');
655
+ expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
656
+ expect(selectedClusters).toStrictEqual([]);
657
+ });
658
+
659
+ it('should set targetMode to "clusters" and populate selectedClusters and clusterSelectors', () => {
660
+ const target1 = { clusterName: 'fleet-5-france' };
661
+
662
+ const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
663
+
664
+ const wrapper = mount(FleetClusterTargets, {
665
+ props: {
666
+ targets: [target1, target2],
667
+ namespace: 'fleet-default',
668
+ mode,
669
+ created: 'clusters'
670
+ },
671
+ });
672
+
673
+ const targetMode = wrapper.vm.targetMode;
674
+ const selectedClusters = wrapper.vm.selectedClusters;
675
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
676
+
677
+ expect(targetMode).toBe('clusters');
678
+ expect(selectedClusters).toStrictEqual(['fleet-5-france']);
679
+ expect(clusterSelectors).toStrictEqual([{
680
+ key: 0,
681
+ matchLabels: { foo: 'true' },
682
+ matchExpressions: undefined
683
+ }]);
684
+ });
685
+
686
+ it('should set targetMode to "clusters" and populate clusterSelectors with multiple entries', () => {
687
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
688
+ const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
689
+
690
+ const wrapper = mount(FleetClusterTargets, {
691
+ props: {
692
+ targets: [target1, target2],
693
+ namespace: 'fleet-default',
694
+ mode,
695
+ created: 'clusters'
696
+ },
697
+ });
698
+
699
+ const targetMode = wrapper.vm.targetMode;
700
+ const selectedClusters = wrapper.vm.selectedClusters;
701
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
702
+
703
+ expect(targetMode).toBe('clusters');
704
+ expect(selectedClusters).toStrictEqual([]);
705
+ expect(clusterSelectors).toStrictEqual([{
706
+ key: 0,
707
+ matchLabels: { foo: 'true' },
708
+ matchExpressions: undefined
709
+ }, {
710
+ key: 1,
711
+ matchLabels: { hci: 'true' },
712
+ matchExpressions: undefined
713
+ }]);
714
+ });
715
+
716
+ it('should set targetMode to "advanced" and return early if clusterGroupSelector is present', () => {
717
+ const target1 = { clusterGroupSelector: {} };
718
+
719
+ const wrapper = mount(FleetClusterTargets, {
720
+ props: {
721
+ targets: [target1],
722
+ namespace: 'fleet-default',
723
+ mode,
724
+ created: 'advanced'
725
+ },
726
+ });
727
+
728
+ const targetMode = wrapper.vm.targetMode;
729
+ const selectedClusters = wrapper.vm.selectedClusters;
730
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
731
+
732
+ expect(targetMode).toBe('advanced');
733
+ // Expect no further processing for selectedClusters or clusterSelectors due to early return
734
+ expect(selectedClusters).toStrictEqual([]);
735
+ expect(clusterSelectors).toStrictEqual([]);
736
+ });
737
+
738
+ it('should set targetMode to "advanced" and return early if clusterGroup is present', () => {
739
+ const target1 = {
740
+ clusterGroup: 'cg1',
741
+ clusterGroupSelector: {
742
+ matchExpressions: [{
743
+ key: 'string',
744
+ operator: 'string',
745
+ values: ['string']
746
+ }],
747
+ matchLabels: { foo: 'bar' }
748
+ },
749
+ clusterName: 'pippo',
750
+ clusterSelector: {
751
+ matchExpressions: [{
752
+ key: 'string',
753
+ operator: 'string',
754
+ values: ['vvv']
755
+ }],
756
+ matchLabels: { foo: 'bar' }
757
+ },
758
+ name: 'tt1',
759
+ };
760
+
761
+ const wrapper = mount(FleetClusterTargets, {
762
+ props: {
763
+ targets: [target1],
764
+ namespace: 'fleet-default',
765
+ mode,
766
+ created: 'advanced'
767
+ },
768
+ });
769
+
770
+ const targetMode = wrapper.vm.targetMode;
771
+ const selectedClusters = wrapper.vm.selectedClusters;
772
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
773
+
774
+ expect(targetMode).toBe('advanced');
775
+ // Expect no further processing for selectedClusters or clusterSelectors due to early return
776
+ expect(selectedClusters).toStrictEqual([]);
777
+ expect(clusterSelectors).toStrictEqual([]);
778
+ });
779
+
780
+ it('should return early and not modify state if targets is empty', () => {
781
+ const wrapper = mount(FleetClusterTargets, {
782
+ props: {
783
+ targets: [],
784
+ namespace: 'fleet-default',
785
+ mode,
786
+ created: 'none'
787
+ },
788
+ });
789
+
790
+ const targetMode = wrapper.vm.targetMode;
791
+ const selectedClusters = wrapper.vm.selectedClusters;
792
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
793
+
794
+ expect(targetMode).toBe('none');
795
+ expect(selectedClusters).toStrictEqual([]);
796
+ expect(clusterSelectors).toStrictEqual([]);
797
+ });
798
+
799
+ it('should return targetMode local if namespace is fleet-local', () => {
800
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
801
+ const wrapper = mount(FleetClusterTargets, {
802
+ props: {
803
+ targets: [target1],
804
+ namespace: 'fleet-local',
805
+ mode,
806
+ created: 'local'
807
+ },
808
+ });
809
+
810
+ const targetMode = wrapper.vm.targetMode;
811
+
812
+ expect(targetMode).toBe('local');
813
+ });
814
+
815
+ it('should handle targets with multiple clusterName', () => {
816
+ const target1 = { clusterName: 'prod-cluster' };
817
+ const target2 = { clusterName: 'test-cluster' };
818
+ const wrapper = mount(FleetClusterTargets, {
819
+ props: {
820
+ targets: [target1, target2],
821
+ namespace: 'fleet-default',
822
+ mode,
823
+ created: 'clusters'
824
+ },
825
+ });
826
+
827
+ const targetMode = wrapper.vm.targetMode;
828
+ const selectedClusters = wrapper.vm.selectedClusters;
829
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
830
+
831
+ expect(targetMode).toBe('clusters');
832
+ expect(selectedClusters).toStrictEqual(['prod-cluster', 'test-cluster']);
833
+ expect(clusterSelectors).toStrictEqual([]);
834
+ });
835
+
836
+ it('should filter out harvester rule and leave others', () => {
837
+ const target1 = {
838
+ clusterSelector: {
839
+ matchExpressions: [{
840
+ key: 'provider.cattle.io',
841
+ operator: 'NotIn',
842
+ values: ['harvester']
843
+ }, {
844
+ key: 'foo',
845
+ operator: 'In',
846
+ values: ['bar']
847
+ }]
848
+ }
849
+ };
850
+
851
+ const wrapper = mount(FleetClusterTargets, {
852
+ props: {
853
+ targets: [target1],
854
+ namespace: 'fleet-default',
855
+ mode,
856
+ created: 'clusters'
857
+ },
858
+ });
859
+
860
+ const targetMode = wrapper.vm.targetMode;
861
+ const selectedClusters = wrapper.vm.selectedClusters;
862
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
863
+
864
+ expect(targetMode).toBe('clusters');
865
+ expect(selectedClusters).toStrictEqual([]);
866
+ expect(clusterSelectors).toStrictEqual([{
867
+ key: 0,
868
+ matchLabels: undefined,
869
+ matchExpressions: [{
870
+ key: 'foo',
871
+ operator: 'In',
872
+ values: ['bar']
873
+ }]
874
+ }]);
875
+ });
876
+
877
+ it('should correctly process targets when targetMode is "all" and no clusterName or clusterSelector is present', () => {
878
+ const target1 = { name: 'simple-target' };
879
+
880
+ const wrapper = mount(FleetClusterTargets, {
881
+ props: {
882
+ targets: [target1],
883
+ namespace: 'fleet-default',
884
+ mode,
885
+ },
886
+ });
887
+
888
+ const targetMode = wrapper.vm.targetMode;
889
+ const selectedClusters = wrapper.vm.selectedClusters;
890
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
891
+
892
+ expect(targetMode).toBe('all');
893
+ expect(selectedClusters).toStrictEqual([]);
894
+ expect(clusterSelectors).toStrictEqual([]);
895
+ });
896
+
897
+ it('should correctly process targets when targetMode is "all", name is defined and harvester rule is present', () => {
898
+ const target1 = {
899
+ clusterSelector: {
900
+ matchExpressions: [{
901
+ key: 'provider.cattle.io',
902
+ operator: 'NotIn',
903
+ values: ['harvester']
904
+ }]
905
+ },
906
+ name: 'simple-target'
907
+ };
908
+
909
+ const wrapper = mount(FleetClusterTargets, {
910
+ props: {
911
+ targets: [target1],
912
+ namespace: 'fleet-default',
913
+ mode,
914
+ },
915
+ });
916
+
917
+ const targetMode = wrapper.vm.targetMode;
918
+ const selectedClusters = wrapper.vm.selectedClusters;
919
+ const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
920
+
921
+ expect(targetMode).toBe('all');
922
+ expect(selectedClusters).toStrictEqual([]);
923
+ expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
924
+ });
925
+ });
926
+
927
+ describe('decode form data and emit to spec.targets', () => {
928
+ it('should emit target with clusterName and clusterSelector', async() => {
929
+ const target1 = {
930
+ clusterName: 'fleet-5-france',
931
+ clusterSelector: { matchLabels: { foo: 'true' } }
932
+ };
933
+ const wrapper = mount(FleetClusterTargets, {
934
+ props: {
935
+ targets: [target1],
936
+ namespace: 'fleet-default',
937
+ mode,
938
+ },
939
+ });
940
+
941
+ wrapper.setData({ targetMode: 'clusters' });
942
+
943
+ wrapper.vm.update();
944
+
945
+ await flushPromises();
946
+
947
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
948
+ });
949
+
950
+ it('should emit harvester exclude rule', async() => {
951
+ const target1 = {
952
+ clusterSelector: {
953
+ matchExpressions: [{
954
+ key: 'provider.cattle.io',
955
+ operator: 'NotIn',
956
+ values: ['harvester']
957
+ }]
958
+ }
959
+ };
960
+ const wrapper = mount(FleetClusterTargets, {
961
+ props: {
962
+ targets: [target1],
963
+ namespace: 'fleet-default',
964
+ mode,
965
+ },
966
+ });
967
+
968
+ wrapper.vm.update();
969
+ await flushPromises();
970
+
971
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
972
+ clusterSelector: {
973
+ matchExpressions: [{
974
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
975
+ }]
976
+ }
977
+ }]);
978
+ });
979
+
980
+ it('should emit multiple targets with clusterName and clusterSelector', async() => {
981
+ const target1 = { clusterName: 'fleet-5-france' };
982
+
983
+ const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
984
+
985
+ const wrapper = mount(FleetClusterTargets, {
986
+ props: {
987
+ targets: [target1, target2],
988
+ namespace: 'fleet-default',
989
+ mode,
990
+ },
991
+ });
992
+
993
+ wrapper.setData({ targetMode: 'clusters' });
994
+
995
+ wrapper.vm.update();
996
+ await flushPromises();
997
+
998
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
999
+ });
1000
+
1001
+ it('should emit multiple targets containing both clusterSelector fields', async() => {
1002
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
1003
+ const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
1004
+
1005
+ const wrapper = mount(FleetClusterTargets, {
1006
+ props: {
1007
+ targets: [target1, target2],
1008
+ namespace: 'fleet-default',
1009
+ mode,
1010
+ },
1011
+ });
1012
+
1013
+ wrapper.setData({ targetMode: 'clusters' });
1014
+
1015
+ wrapper.vm.update();
1016
+ await flushPromises();
1017
+
1018
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }, { clusterSelector: { matchLabels: { hci: 'true' } } }]);
1019
+ });
1020
+
1021
+ it('should emit advanced cases untouched', async() => {
1022
+ const target1 = { clusterGroupSelector: {} };
1023
+
1024
+ const wrapper = mount(FleetClusterTargets, {
1025
+ props: {
1026
+ targets: [target1],
1027
+ namespace: 'fleet-default',
1028
+ mode,
1029
+ },
1030
+ });
1031
+
1032
+ wrapper.setData({ targetMode: 'advanced' });
1033
+
1034
+ wrapper.vm.update();
1035
+ await flushPromises();
1036
+
1037
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterGroupSelector: {} }]);
1038
+ });
1039
+
1040
+ it('should emit full target definition', async() => {
1041
+ const target1 = {
1042
+ clusterGroup: 'cg1',
1043
+ clusterGroupSelector: {
1044
+ matchExpressions: [{
1045
+ key: 'string',
1046
+ operator: 'string',
1047
+ values: ['string']
1048
+ }],
1049
+ matchLabels: { foo: 'bar' }
1050
+ },
1051
+ clusterName: 'pippo',
1052
+ clusterSelector: {
1053
+ matchExpressions: [{
1054
+ key: 'string',
1055
+ operator: 'string',
1056
+ values: ['vvv']
1057
+ }],
1058
+ matchLabels: { foo: 'bar' }
1059
+ },
1060
+ name: 'tt1',
1061
+ };
1062
+
1063
+ const wrapper = mount(FleetClusterTargets, {
1064
+ props: {
1065
+ targets: [target1],
1066
+ namespace: 'fleet-default',
1067
+ mode,
1068
+ },
1069
+ });
1070
+
1071
+ wrapper.setData({ targetMode: 'advanced' });
1072
+
1073
+ wrapper.vm.update();
1074
+ await flushPromises();
1075
+
1076
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{
1077
+ clusterGroup: 'cg1',
1078
+ clusterGroupSelector: {
1079
+ matchExpressions: [{
1080
+ key: 'string', operator: 'string', values: ['string']
1081
+ }],
1082
+ matchLabels: { foo: 'bar' }
1083
+ },
1084
+ clusterName: 'pippo',
1085
+ clusterSelector: {
1086
+ matchExpressions: [{
1087
+ key: 'string', operator: 'string', values: ['vvv']
1088
+ }],
1089
+ matchLabels: { foo: 'bar' }
1090
+ },
1091
+ name: 'tt1'
1092
+ }]);
1093
+ });
1094
+
1095
+ it('should emit harvester rule from empty targets source', async() => {
1096
+ const wrapper = mount(FleetClusterTargets, {
1097
+ props: {
1098
+ targets: [], // targetMode === 'none'
1099
+ namespace: 'fleet-default',
1100
+ mode,
1101
+ },
1102
+ });
1103
+
1104
+ wrapper.setData({ targetMode: 'none' });
1105
+
1106
+ wrapper.vm.update();
1107
+ await flushPromises();
1108
+
1109
+ expect(wrapper.emitted('update:value')?.[1][0]).toBeUndefined();
1110
+ });
1111
+
1112
+ it('should emit untouched targets from source when operating in fleet-local workspace', async() => {
1113
+ const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
1114
+
1115
+ const wrapper = mount(FleetClusterTargets, {
1116
+ props: {
1117
+ targets: [target1],
1118
+ namespace: 'fleet-local',
1119
+ mode,
1120
+ },
1121
+ });
1122
+
1123
+ wrapper.setData({ targetMode: 'clusters' });
1124
+
1125
+ wrapper.vm.update();
1126
+ await flushPromises();
1127
+
1128
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }]);
1129
+ });
1130
+
1131
+ it('should emit custom targets filtering out harvester rule', async() => {
1132
+ const target1 = {
1133
+ clusterSelector: {
1134
+ matchExpressions: [{
1135
+ key: 'provider.cattle.io',
1136
+ operator: 'NotIn',
1137
+ values: ['harvester']
1138
+ }, {
1139
+ key: 'foo',
1140
+ operator: 'In',
1141
+ values: ['bar']
1142
+ }]
1143
+ }
1144
+ };
1145
+
1146
+ const wrapper = mount(FleetClusterTargets, {
1147
+ props: {
1148
+ targets: [target1],
1149
+ namespace: 'fleet-default',
1150
+ mode,
1151
+ },
1152
+ });
1153
+
1154
+ wrapper.setData({ targetMode: 'clusters' });
1155
+
1156
+ wrapper.vm.update();
1157
+ await flushPromises();
1158
+
1159
+ expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{
1160
+ clusterSelector: {
1161
+ matchExpressions: [{
1162
+ key: 'foo', operator: 'In', values: ['bar']
1163
+ }]
1164
+ }
1165
+ }]);
1166
+ });
1167
+
1168
+ it('should emit targets excluding target names and adding harvester rule', async() => {
1169
+ const target1 = { name: 'simple-target' };
1170
+
1171
+ const wrapper = mount(FleetClusterTargets, {
1172
+ props: {
1173
+ targets: [target1],
1174
+ namespace: 'fleet-default',
1175
+ mode,
1176
+ },
1177
+ });
1178
+
1179
+ wrapper.vm.update();
1180
+ await flushPromises();
1181
+
1182
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
1183
+ clusterSelector: {
1184
+ matchExpressions: [{
1185
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
1186
+ }]
1187
+ }
1188
+ }]);
1189
+ });
1190
+
1191
+ it('should emit targets excluding target names and harvester rule if present in source targets', async() => {
1192
+ const target1 = {
1193
+ clusterSelector: {
1194
+ matchExpressions: [{
1195
+ key: 'provider.cattle.io',
1196
+ operator: 'NotIn',
1197
+ values: ['harvester']
1198
+ }]
1199
+ },
1200
+ name: 'simple-target'
1201
+ };
1202
+
1203
+ const wrapper = mount(FleetClusterTargets, {
1204
+ props: {
1205
+ targets: [target1],
1206
+ namespace: 'fleet-default',
1207
+ mode,
1208
+ },
1209
+ });
1210
+
1211
+ wrapper.vm.update();
1212
+ await flushPromises();
1213
+
1214
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
1215
+ clusterSelector: {
1216
+ matchExpressions: [{
1217
+ key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
1218
+ }]
1219
+ }
1220
+ }]);
1221
+ });
1222
+ });
1223
+ });
1224
+ });