@rancher/shell 3.0.5-rc.5 → 3.0.5-rc.7

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 (361) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/images/key.svg +17 -0
  3. package/assets/styles/base/_spacing.scss +2 -2
  4. package/assets/styles/base/_variables.scss +17 -11
  5. package/assets/styles/global/_form.scss +1 -1
  6. package/assets/styles/global/_labeled-input.scss +1 -1
  7. package/assets/styles/themes/_dark.scss +5 -0
  8. package/assets/styles/themes/_light.scss +11 -2
  9. package/assets/styles/vendor/vue-select.scss +1 -1
  10. package/assets/translations/en-us.yaml +426 -64
  11. package/assets/translations/zh-hans.yaml +3 -4
  12. package/cloud-credential/gcp.vue +9 -1
  13. package/components/AppModal.vue +2 -0
  14. package/components/CodeMirror.vue +2 -2
  15. package/components/ConfigMapSettings/Settings.vue +377 -0
  16. package/components/ConfigMapSettings/index.vue +354 -0
  17. package/components/CruResource.vue +1 -2
  18. package/components/DetailText.vue +61 -11
  19. package/components/Drawer/Chrome.vue +115 -0
  20. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  21. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  22. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  23. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  24. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +106 -0
  25. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  26. package/components/Drawer/ResourceDetailDrawer/composables.ts +53 -0
  27. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  28. package/components/Drawer/ResourceDetailDrawer/index.vue +111 -0
  29. package/components/GrowlManager.vue +16 -15
  30. package/components/IconOrSvg.vue +5 -0
  31. package/components/KeyValueView.vue +1 -1
  32. package/components/Loading.vue +1 -1
  33. package/components/LocaleSelector.vue +9 -1
  34. package/components/PaginatedResourceTable.vue +46 -1
  35. package/components/ProgressBarMulti.vue +1 -0
  36. package/components/PromptModal.vue +6 -1
  37. package/components/PromptRestore.vue +22 -44
  38. package/components/RelatedResources.vue +4 -12
  39. package/components/Resource/Detail/Additional.vue +46 -0
  40. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
  41. package/components/Resource/Detail/Metadata/Annotations/index.vue +5 -0
  42. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  43. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +47 -256
  44. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +317 -0
  45. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +34 -5
  46. package/components/Resource/Detail/Metadata/KeyValue.vue +32 -22
  47. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -1
  48. package/components/Resource/Detail/Metadata/Labels/index.vue +4 -0
  49. package/components/Resource/Detail/Metadata/Rectangle.vue +3 -1
  50. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +1 -1
  51. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +1 -1
  52. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  53. package/components/Resource/Detail/Metadata/composables.ts +60 -11
  54. package/components/Resource/Detail/Metadata/index.vue +12 -5
  55. package/components/Resource/Detail/Page.vue +15 -0
  56. package/components/Resource/Detail/ResourceRow.vue +37 -18
  57. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  58. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  59. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  60. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  61. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  62. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  63. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  64. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  65. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  66. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  67. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  68. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  69. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  70. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  71. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  72. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  73. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  74. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  75. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  76. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  77. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  78. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  79. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  80. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  81. package/components/Resource/Detail/SpacedRow.vue +1 -1
  82. package/components/Resource/Detail/TitleBar/Title.vue +2 -1
  83. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +1 -1
  84. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +1 -1
  85. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  86. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
  87. package/components/Resource/Detail/TitleBar/composables.ts +45 -0
  88. package/components/Resource/Detail/TitleBar/index.vue +85 -13
  89. package/components/Resource/Detail/composables.ts +45 -0
  90. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  91. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  92. package/components/ResourceDetail/Masthead/index.vue +65 -0
  93. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  94. package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +1 -1
  95. package/components/ResourceDetail/__tests__/index.test.ts +26 -5
  96. package/components/ResourceDetail/index.vue +33 -17
  97. package/components/ResourceDetail/legacy.vue +18 -1
  98. package/components/ResourceList/Masthead.vue +6 -0
  99. package/components/ResourceList/index.vue +1 -0
  100. package/components/ResourceTable.vue +6 -1
  101. package/components/ResourceYaml.vue +15 -2
  102. package/components/RichTranslation.vue +106 -0
  103. package/components/SlideInPanelManager.vue +46 -11
  104. package/components/SortableTable/index.vue +1 -1
  105. package/components/SortableTable/selection.js +0 -1
  106. package/components/StateDot/index.vue +28 -0
  107. package/components/Tabbed/index.vue +17 -16
  108. package/components/Wizard.vue +4 -2
  109. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  110. package/components/__tests__/GrowlManager.test.ts +0 -25
  111. package/components/__tests__/PromptRestore.test.ts +1 -65
  112. package/components/__tests__/RichTranslation.test.ts +115 -0
  113. package/components/auth/login/ldap.vue +1 -1
  114. package/components/fleet/FleetApplications.vue +0 -7
  115. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  116. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  117. package/components/fleet/FleetClusters.vue +25 -6
  118. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  119. package/components/fleet/FleetHelmOps.vue +8 -0
  120. package/components/fleet/FleetRepos.vue +1 -6
  121. package/components/fleet/FleetResources.vue +4 -5
  122. package/components/fleet/FleetValuesFrom.vue +295 -0
  123. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  124. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  125. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +13 -13
  126. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  127. package/components/fleet/dashboard/ResourceCard.vue +1 -0
  128. package/components/fleet/dashboard/ResourceCardSummary.vue +1 -5
  129. package/components/fleet/dashboard/ResourceDetails.vue +8 -10
  130. package/components/fleet/dashboard/ResourcePanel.vue +17 -9
  131. package/components/form/ArrayList.vue +13 -2
  132. package/components/form/ChangePassword.vue +3 -1
  133. package/components/form/FileImageSelector.vue +1 -1
  134. package/components/form/Footer.vue +10 -4
  135. package/components/form/KeyValue.vue +81 -43
  136. package/components/form/LabeledSelect.vue +56 -16
  137. package/components/form/Labels.vue +90 -17
  138. package/components/form/MatchExpressions.vue +46 -5
  139. package/components/form/NameNsDescription.vue +2 -1
  140. package/components/form/Networking.vue +24 -19
  141. package/components/form/ResourceLabeledSelect.vue +4 -3
  142. package/components/form/ResourceSelector.vue +1 -0
  143. package/components/form/ResourceTabs/index.vue +5 -0
  144. package/components/form/SecretSelector.vue +9 -2
  145. package/components/form/Select.vue +57 -19
  146. package/components/form/SelectOrCreateAuthSecret.vue +6 -3
  147. package/components/form/SimpleSecretSelector.vue +9 -2
  148. package/components/form/Taints.vue +21 -2
  149. package/components/form/UnitInput.vue +8 -0
  150. package/components/form/ValueFromResource.vue +1 -1
  151. package/components/form/__tests__/LabeledSelect.test.ts +8 -4
  152. package/components/form/__tests__/Labels.test.ts +360 -0
  153. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  154. package/components/form/__tests__/Networking.test.ts +116 -0
  155. package/components/form/__tests__/Select.test.ts +5 -2
  156. package/components/formatter/FleetApplicationSource.vue +1 -1
  157. package/components/formatter/PodImages.vue +1 -1
  158. package/components/formatter/WorkloadHealthScale.vue +1 -1
  159. package/components/formatter/__tests__/LiveDate.test.ts +10 -2
  160. package/components/google/AccountAccess.vue +209 -0
  161. package/components/google/types/gcp.d.ts +136 -0
  162. package/components/google/types/index.d.ts +101 -0
  163. package/components/google/util/__mocks__/gcp.ts +465 -0
  164. package/components/google/util/formatter.ts +82 -0
  165. package/components/google/util/gcp.ts +134 -0
  166. package/components/google/util/index.d.ts +11 -0
  167. package/components/nav/Favorite.vue +1 -1
  168. package/components/nav/Group.vue +71 -45
  169. package/components/nav/Header.vue +5 -1
  170. package/components/nav/NamespaceFilter.vue +13 -1
  171. package/components/nav/NotificationCenter/Notification.vue +510 -0
  172. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  173. package/components/nav/NotificationCenter/index.vue +148 -0
  174. package/composables/drawer.ts +26 -0
  175. package/composables/resources.test.ts +63 -0
  176. package/composables/resources.ts +38 -0
  177. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  178. package/config/labels-annotations.js +8 -0
  179. package/config/pagination-table-headers.js +8 -1
  180. package/config/product/auth.js +16 -1
  181. package/config/product/{cis.js → compliance.js} +23 -26
  182. package/config/product/explorer.js +32 -3
  183. package/config/product/fleet.js +7 -0
  184. package/config/product/manager.js +0 -1
  185. package/config/product/settings.js +22 -11
  186. package/config/query-params.js +13 -0
  187. package/config/roles.ts +1 -1
  188. package/config/router/navigation-guards/authentication.js +51 -2
  189. package/config/router/routes.js +47 -31
  190. package/config/settings.ts +21 -3
  191. package/config/store.js +2 -0
  192. package/config/system-namespaces.js +1 -1
  193. package/config/table-headers.js +32 -3
  194. package/config/types.js +16 -7
  195. package/config/version.js +1 -1
  196. package/core/plugin.ts +32 -7
  197. package/core/types.ts +18 -1
  198. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  199. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  200. package/detail/management.cattle.io.oidcclient.vue +369 -0
  201. package/detail/node.vue +2 -2
  202. package/detail/pod.vue +2 -2
  203. package/detail/provisioning.cattle.io.cluster.vue +3 -47
  204. package/detail/service.vue +10 -1
  205. package/detail/workload/index.vue +8 -2
  206. package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
  207. package/dialog/GenericPrompt.vue +1 -1
  208. package/dialog/ImportDialog.vue +8 -8
  209. package/dialog/OidcClientSecretDialog.vue +117 -0
  210. package/dialog/RotateEncryptionKeyDialog.vue +10 -30
  211. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  212. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +5 -2
  213. package/edit/auth/ldap/__tests__/config.test.ts +14 -0
  214. package/edit/auth/ldap/config.vue +24 -0
  215. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  216. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  217. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  218. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  219. package/edit/configmap.vue +8 -2
  220. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  221. package/edit/fleet.cattle.io.gitrepo.vue +44 -222
  222. package/edit/fleet.cattle.io.helmop.vue +44 -269
  223. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  224. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  225. package/edit/logging-flow/index.vue +1 -0
  226. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  227. package/edit/management.cattle.io.fleetworkspace.vue +1 -0
  228. package/edit/management.cattle.io.oidcclient.vue +162 -0
  229. package/edit/management.cattle.io.project.vue +4 -1
  230. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  231. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  232. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  233. package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
  234. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  235. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  236. package/edit/monitoring.coreos.com.route.vue +1 -0
  237. package/edit/namespace.vue +1 -0
  238. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  239. package/edit/networking.k8s.io.ingress/Certificate.vue +12 -12
  240. package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +165 -0
  241. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  242. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
  243. package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
  244. package/edit/node.vue +1 -0
  245. package/edit/persistentvolume/index.vue +4 -1
  246. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -2
  247. package/edit/provisioning.cattle.io.cluster/rke2.vue +516 -426
  248. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +48 -39
  249. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  250. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -2
  251. package/edit/resources.cattle.io.restore.vue +1 -1
  252. package/edit/secret/basic.vue +1 -0
  253. package/edit/secret/index.vue +127 -15
  254. package/edit/service.vue +4 -1
  255. package/edit/serviceaccount.vue +4 -1
  256. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  257. package/edit/workload/index.vue +5 -0
  258. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  259. package/list/management.cattle.io.oidcclient.vue +108 -0
  260. package/list/node.vue +2 -0
  261. package/list/projectsecret.vue +345 -0
  262. package/list/secret.vue +109 -0
  263. package/machine-config/amazonec2.vue +3 -24
  264. package/machine-config/components/GCEImage.vue +374 -0
  265. package/machine-config/google.vue +617 -0
  266. package/mixins/__tests__/brand.spec.ts +170 -0
  267. package/mixins/brand.js +16 -17
  268. package/mixins/create-edit-view/impl.js +10 -1
  269. package/mixins/create-edit-view/index.js +5 -0
  270. package/mixins/resource-fetch-api-pagination.js +24 -8
  271. package/mixins/resource-fetch.js +3 -1
  272. package/mixins/vue-select-overrides.js +1 -0
  273. package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
  274. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  275. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  276. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  277. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  278. package/models/fleet-application.js +8 -79
  279. package/models/fleet.cattle.io.cluster.js +13 -2
  280. package/models/fleet.cattle.io.gitrepo.js +2 -2
  281. package/models/fleet.cattle.io.helmop.js +9 -39
  282. package/models/management.cattle.io.fleetworkspace.js +2 -1
  283. package/models/management.cattle.io.oidcclient.js +18 -0
  284. package/models/management.cattle.io.registration.js +3 -0
  285. package/models/provisioning.cattle.io.cluster.js +29 -33
  286. package/models/secret.js +157 -2
  287. package/models/service.js +4 -0
  288. package/models/workload.js +5 -0
  289. package/package.json +2 -2
  290. package/pages/about.vue +4 -58
  291. package/pages/auth/login.vue +1 -1
  292. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +0 -1
  293. package/pages/c/_cluster/apps/charts/index.vue +296 -81
  294. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  295. package/pages/c/_cluster/explorer/index.vue +3 -3
  296. package/pages/c/_cluster/explorer/projectsecret.vue +34 -0
  297. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  298. package/pages/c/_cluster/fleet/application/create.vue +3 -2
  299. package/pages/c/_cluster/fleet/index.vue +94 -57
  300. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  301. package/pages/c/_cluster/longhorn/index.vue +5 -2
  302. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  303. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  304. package/pages/explorer/resource/detail/configmap.vue +30 -7
  305. package/pages/explorer/resource/detail/projectsecret.vue +9 -0
  306. package/pages/explorer/resource/detail/secret.vue +63 -0
  307. package/pages/home.vue +9 -55
  308. package/pages/support/index.vue +4 -6
  309. package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
  310. package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
  311. package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
  312. package/plugins/dashboard-store/actions.js +19 -5
  313. package/plugins/dashboard-store/getters.js +4 -0
  314. package/plugins/dashboard-store/normalize.js +29 -17
  315. package/plugins/dashboard-store/resource-class.js +68 -19
  316. package/plugins/steve/steve-pagination-utils.ts +38 -19
  317. package/plugins/steve/subscribe.js +6 -1
  318. package/rancher-components/Banner/Banner.vue +13 -0
  319. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -4
  320. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  321. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  322. package/rancher-components/RcItemCard/RcItemCard.vue +8 -3
  323. package/store/auth.js +2 -0
  324. package/store/catalog.js +23 -1
  325. package/store/growl.js +97 -8
  326. package/store/index.js +6 -0
  327. package/store/notifications.ts +426 -0
  328. package/store/prefs.js +0 -1
  329. package/store/type-map.js +19 -16
  330. package/store/uiplugins.ts +15 -1
  331. package/types/fleet.d.ts +24 -0
  332. package/types/kube/kube-api.ts +12 -0
  333. package/types/notifications/index.ts +74 -0
  334. package/types/shell/index.d.ts +661 -589
  335. package/types/store/dashboard-store.types.ts +16 -0
  336. package/types/store/pagination.types.ts +16 -6
  337. package/utils/__tests__/create-yaml.test.ts +235 -0
  338. package/utils/__tests__/fleet.test.ts +148 -0
  339. package/utils/__tests__/object.test.ts +54 -1
  340. package/utils/__tests__/string.test.ts +273 -1
  341. package/utils/__tests__/time.test.ts +31 -0
  342. package/utils/auth.js +9 -2
  343. package/utils/create-yaml.js +103 -9
  344. package/utils/crypto/encryption.ts +103 -0
  345. package/utils/cspAdaptor.ts +51 -0
  346. package/utils/fleet.ts +54 -65
  347. package/utils/object.js +36 -0
  348. package/utils/pagination-utils.ts +19 -1
  349. package/utils/release-notes.ts +48 -0
  350. package/utils/selector-typed.ts +7 -2
  351. package/utils/string.js +24 -0
  352. package/utils/{time.js → time.ts} +25 -6
  353. package/utils/uiplugins.ts +22 -0
  354. package/utils/validators/formRules/index.ts +3 -0
  355. package/components/Resource/Detail/TitleBar/composable.ts +0 -31
  356. package/config/product/legacy.js +0 -62
  357. package/models/etcdbackup.js +0 -45
  358. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  359. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  360. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  361. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
@@ -0,0 +1,170 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { CATALOG, MANAGEMENT } from '@shell/config/types';
3
+ import Brand from '@shell/mixins/brand';
4
+
5
+ describe('brandMixin', () => {
6
+ const createWrapper = (vaiOn = false) => {
7
+ const Component = {
8
+ template: '<div></div>',
9
+ mixins: [Brand],
10
+ };
11
+
12
+ const data = {
13
+ apps: null, haveAppsAndSettings: null, canPaginate: false
14
+ };
15
+
16
+ const store = {
17
+ dispatch: (action, ...args) => {
18
+ switch (action) {
19
+ case 'management/findAll':
20
+ if (args[0] === MANAGEMENT.SETTING) {
21
+ return [];
22
+ }
23
+ if (args[0] === CATALOG.APP) {
24
+ return [];
25
+ }
26
+ break;
27
+ }
28
+ },
29
+ getters: {
30
+ 'auth/loggedIn': () => true,
31
+ 'auth/fromHeader': () => false,
32
+ 'management/byId': () => undefined,
33
+ 'management/canList': () => () => true,
34
+ 'management/schemaFor': (type: string) => {
35
+ switch (type) {
36
+ case MANAGEMENT.SETTING:
37
+ return { linkFor: () => undefined };
38
+ }
39
+ },
40
+ 'management/generation': () => undefined,
41
+ 'management/paginationEnabled': () => vaiOn,
42
+ 'management/all': (type: string) => {
43
+ switch (type) {
44
+ case MANAGEMENT.SETTING:
45
+ return [];
46
+ }
47
+ },
48
+ }
49
+ };
50
+
51
+ const wrapper = mount(
52
+ Component,
53
+ {
54
+ data: () => data,
55
+ global: { mocks: { $store: store } }
56
+ });
57
+ const spyManagementFindAll = jest.spyOn(store, 'dispatch');
58
+
59
+ return {
60
+ wrapper,
61
+ store,
62
+ spyManagementFindAll,
63
+ };
64
+ };
65
+
66
+ describe('should make correct requests', () => {
67
+ it('vai off', async() => {
68
+ const { wrapper, spyManagementFindAll } = createWrapper(false);
69
+
70
+ // NOTE - wrapper.vm.$options.fetch() doesn't work
71
+ await wrapper.vm.$options.fetch.apply(wrapper.vm);
72
+
73
+ // wrapper.vm.$nextTick();
74
+ expect(spyManagementFindAll).toHaveBeenNthCalledWith(1, 'management/findAll', {
75
+ type: MANAGEMENT.SETTING,
76
+ opt: {
77
+ load: 'multi', redirectUnauthorized: false, url: `/v1/${ MANAGEMENT.SETTING }s`
78
+ }
79
+ });
80
+ expect(spyManagementFindAll).toHaveBeenNthCalledWith(2, 'management/findAll', { type: CATALOG.APP });
81
+ });
82
+
83
+ it('vai on', async() => {
84
+ const { wrapper, spyManagementFindAll } = createWrapper(true);
85
+
86
+ // NOTE - wrapper.vm.$options.fetch() doesn't work
87
+ await wrapper.vm.$options.fetch.apply(wrapper.vm);
88
+
89
+ expect(spyManagementFindAll).toHaveBeenNthCalledWith(1, 'management/findAll', {
90
+ type: MANAGEMENT.SETTING,
91
+ opt: {
92
+ load: 'multi', url: `/v1/${ MANAGEMENT.SETTING }s`, redirectUnauthorized: false
93
+ }
94
+ });
95
+ expect(spyManagementFindAll).toHaveBeenNthCalledWith(2, 'management/findPage', {
96
+ type: CATALOG.APP,
97
+ opt: {
98
+ pagination: {
99
+ filters: [{
100
+ equals: true,
101
+ fields: [{
102
+ equals: true, exact: true, exists: false, field: 'metadata.name', value: 'rancher-csp-adapter'
103
+ }, {
104
+ equals: true, exact: true, exists: false, field: 'metadata.name', value: 'rancher-csp-billing-adapter'
105
+ }],
106
+ param: 'filter'
107
+ }],
108
+ labelSelector: undefined,
109
+ page: null,
110
+ pageSize: null,
111
+ projectsOrNamespaces: [],
112
+ sort: []
113
+ }
114
+ }
115
+ });
116
+ });
117
+ });
118
+
119
+ describe('cspAdapter', () => {
120
+ it('should have correct csp values (off)', async() => {
121
+ const { wrapper, store } = createWrapper();
122
+
123
+ const spyManagementFindAll = jest.spyOn(store, 'dispatch').mockImplementation((_, options) => {
124
+ const { type } = options as any;
125
+
126
+ if (type === MANAGEMENT.SETTING) {
127
+ return Promise.resolve([]);
128
+ }
129
+ if (type === CATALOG.APP) {
130
+ return Promise.resolve([]);
131
+ }
132
+
133
+ return Promise.reject(new Error('reason'));
134
+ });
135
+
136
+ // NOTE - wrapper.vm.$options.fetch() doesn't work
137
+ await wrapper.vm.$options.fetch.apply(wrapper.vm, []);
138
+
139
+ expect(spyManagementFindAll).toHaveBeenCalledTimes(2);
140
+
141
+ expect(wrapper.vm.canCalcCspAdapter).toBeTruthy();
142
+ expect(wrapper.vm.cspAdapter).toBeFalsy();
143
+ });
144
+
145
+ it.each(['rancher-csp-adapter', 'rancher-csp-billing-adapter'])('should have correct csp values (on - %p )', async(chartName) => {
146
+ const { wrapper, store } = createWrapper();
147
+
148
+ const spyManagementFindAll = jest.spyOn(store, 'dispatch').mockImplementation((_, options) => {
149
+ const { type } = options as any;
150
+
151
+ if (type === MANAGEMENT.SETTING) {
152
+ return Promise.resolve([]);
153
+ }
154
+ if (type === CATALOG.APP) {
155
+ return Promise.resolve([{ metadata: { name: chartName } }]);
156
+ }
157
+
158
+ return Promise.reject(new Error('reason'));
159
+ });
160
+
161
+ // NOTE - wrapper.vm.$options.fetch() doesn't work
162
+ await wrapper.vm.$options.fetch.apply(wrapper.vm, []);
163
+
164
+ expect(spyManagementFindAll).toHaveBeenCalledTimes(2);
165
+
166
+ expect(wrapper.vm.canCalcCspAdapter).toBeTruthy();
167
+ expect(wrapper.vm.cspAdapter).toBeTruthy();
168
+ });
169
+ });
170
+ });
package/mixins/brand.js CHANGED
@@ -1,39 +1,38 @@
1
1
  import { mapGetters } from 'vuex';
2
- import { CATALOG, MANAGEMENT } from '@shell/config/types';
2
+ import { MANAGEMENT } from '@shell/config/types';
3
3
  import { SETTING } from '@shell/config/settings';
4
4
  import { createCssVars } from '@shell/utils/color';
5
5
  import { setTitle } from '@shell/config/private-label';
6
6
  import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
7
-
8
- const cspAdaptorApp = ['rancher-csp-adapter', 'rancher-csp-billing-adapter'];
9
-
10
- export const hasCspAdapter = (apps) => {
11
- return apps?.find((a) => cspAdaptorApp.includes(a.metadata?.name));
12
- };
7
+ import { allHash } from '@shell/utils/promise';
8
+ import { fetchInitialSettings } from '@shell/utils/settings';
9
+ import CspAdapterUtils from '@shell/utils/cspAdaptor';
13
10
 
14
11
  export default {
15
12
  async fetch() {
16
- // For the login page, the schemas won't be loaded - we don't need the apps in this case
17
13
  try {
18
- if (this.$store.getters['management/canList'](CATALOG.APP)) {
19
- this.apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
20
- }
21
- } catch (e) {}
14
+ const res = await allHash({
15
+ // Ensure we read the settings even when we are not authenticated
16
+ globalSettings: fetchInitialSettings(this.$store),
17
+ apps: CspAdapterUtils.fetchCspAdaptorApp(this.$store),
18
+ });
22
19
 
23
- // Ensure we read the settings even when we are not authenticated
24
- try {
25
20
  // The favicon is implicitly dependent on the initial settings having already been fetched
26
21
  if (!haveSetFavIcon()) {
27
22
  setFavIcon(this.$store);
28
23
  }
29
- } catch (e) {}
24
+
25
+ this.apps = res.apps;
26
+ } catch (e) { }
30
27
 
31
28
  // Setting this up front will remove `computed` churn, and we only care that we've initialised them
32
29
  this.haveAppsAndSettings = !!this.apps && !!this.globalSettings;
33
30
  },
34
31
 
35
32
  data() {
36
- return { apps: null, haveAppsAndSettings: null };
33
+ return {
34
+ apps: null, haveAppsAndSettings: null, canPaginate: false
35
+ };
37
36
  },
38
37
 
39
38
  computed: {
@@ -87,7 +86,7 @@ export default {
87
86
  // Note! this used to be `findBy(this.app)` however for that case we lost reactivity on the collection
88
87
  // (computed fires before fetch, fetch happens and update apps, computed would not fire again - even with vue.set)
89
88
  // So use `.find` in method instead
90
- return hasCspAdapter(this.apps);
89
+ return CspAdapterUtils.hasCspAdapter({ $store: this.$store, apps: this.apps });
91
90
  },
92
91
 
93
92
  canCalcCspAdapter() {
@@ -117,7 +117,16 @@ export default {
117
117
  // If they are resolved, return a false-y value
118
118
  // Else they can't be resolved, return an array of errors to show to the user.
119
119
  async conflict() {
120
- return await handleConflict(this.initialValue.toJSON(), this.value, this.liveValue, this.$store.getters, this.$store, this.storeOverride || this.$store.getters['currentStore'](this.value.type));
120
+ return await handleConflict(
121
+ this.initialValue,
122
+ this.value,
123
+ this.liveValue,
124
+ {
125
+ dispatch: this.$store.dispatch,
126
+ getters: this.$store.getters
127
+ },
128
+ this.storeOverride || this.$store.getters['currentStore'](this.value.type)
129
+ );
121
130
  },
122
131
 
123
132
  async save(buttonDone, url, depth = 0) {
@@ -44,5 +44,10 @@ export default defineComponent({
44
44
  type: Boolean,
45
45
  default: false,
46
46
  },
47
+
48
+ useTabbedHash: {
49
+ type: Boolean,
50
+ default: undefined
51
+ }
47
52
  },
48
53
  });
@@ -7,6 +7,7 @@ import paginationUtils from '@shell/utils/pagination-utils';
7
7
  import debounce from 'lodash/debounce';
8
8
  import { PaginationParamFilter, PaginationFilterField, PaginationArgs } from '@shell/types/store/pagination.types';
9
9
  import stevePaginationUtils from '@shell/plugins/steve/steve-pagination-utils';
10
+ import { STEVE_WATCH_MODE } from '@shell/types/store/subscribe.types';
10
11
 
11
12
  /**
12
13
  * Companion mixin used with `resource-fetch` for `ResourceList` to determine if the user needs to filter the list by a single namespace
@@ -124,7 +125,7 @@ export default {
124
125
  context: this.context,
125
126
  };
126
127
 
127
- return this.$store.getters[`${ this.inStore }/paginationEnabled`]?.(args);
128
+ return this.$store.getters[`${ this.overrideInStore || this.inStore }/paginationEnabled`]?.(args);
128
129
  }
129
130
  },
130
131
 
@@ -199,7 +200,7 @@ export default {
199
200
  return;
200
201
  }
201
202
 
202
- return this.$store.getters[`${ this.inStore }/havePage`](this.resource);
203
+ return this.$store.getters[`${ this.overrideInStore || this.inStore }/havePage`](this.resource);
203
204
  },
204
205
 
205
206
  /**
@@ -279,12 +280,12 @@ export default {
279
280
  projectsOrNamespaces,
280
281
  filters
281
282
  } = stevePaginationUtils.createParamsFromNsFilter({
282
- allNamespaces: this.$store.getters[`${ this.currentProduct?.inStore }/all`](NAMESPACE),
283
- selection: neu,
284
- isAllNamespaces: this.isAllNamespaces,
285
- isLocalCluster: this.$store.getters['currentCluster'].isLocal,
286
- showDynamicRancherNamespaces: this.showDynamicRancherNamespaces,
287
- productHidesSystemNamespaces: this.productHidesSystemNamespaces,
283
+ allNamespaces: this.$store.getters[`${ this.currentProduct?.inStore }/all`](NAMESPACE),
284
+ selection: neu,
285
+ isAllNamespaces: this.isAllNamespaces,
286
+ isLocalCluster: this.$store.getters['currentCluster'].isLocal,
287
+ showReservedRancherNamespaces: this.showDynamicRancherNamespaces,
288
+ productHidesSystemNamespaces: this.productHidesSystemNamespaces,
288
289
  });
289
290
 
290
291
  this.requestFilters.filters = filters;
@@ -350,4 +351,19 @@ export default {
350
351
  });
351
352
  }
352
353
  },
354
+
355
+ unmounted() {
356
+ if (this.havePaginated) {
357
+ // of type @STEVE_WATCH_PARAMS
358
+ const watchArgs = {
359
+ type: this.resource,
360
+ mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
361
+ };
362
+
363
+ this.$store.dispatch(`${ this.overrideInStore || this.inStore }/forgetType`, this.resource, (watchParams) => {
364
+ return watchParams.type === watchArgs.type &&
365
+ watchParams.mode === watchArgs.type.mode;
366
+ });
367
+ }
368
+ }
353
369
  };
@@ -242,7 +242,9 @@ export default {
242
242
  },
243
243
 
244
244
  __getCountForResource(resourceName, namespace, storeType) {
245
- const resourceCounts = this.$store.getters[`${ storeType }/all`](COUNT)[0]?.counts[`${ resourceName }`]; // NB `rancher` store behaves differently, lacks counts but has resource
245
+ const currStore = storeType || this.$store.getters['currentStore']();
246
+
247
+ const resourceCounts = this.$store.getters[`${ currStore }/all`](COUNT)[0]?.counts[`${ resourceName }`]; // NB `rancher` store behaves differently, lacks counts but has resource
246
248
  const resourceCount = namespace && resourceCounts?.namespaces ? resourceCounts?.namespaces[namespace]?.count : resourceCounts?.summary?.count;
247
249
 
248
250
  return resourceCount || 0;
@@ -20,6 +20,7 @@ export default {
20
20
  e.preventDefault();
21
21
  e.stopPropagation();
22
22
 
23
+ this.isOpen = false;
23
24
  vm.open = false;
24
25
  vm.search = '';
25
26
 
@@ -125,7 +125,7 @@ export default class CapiMachineDeployment extends SteveModel {
125
125
  return;
126
126
  }
127
127
 
128
- const initialValue = this.cluster.toJSON();
128
+ const initialValue = this.cluster;
129
129
 
130
130
  this.inClusterSpec.quantity += delta;
131
131
 
@@ -145,7 +145,16 @@ export default class CapiMachineDeployment extends SteveModel {
145
145
  let errors = exceptionToErrorsArray(err);
146
146
 
147
147
  if ( err.status === 409 && depth < 2 ) {
148
- const conflicts = await handleConflict(initialValue, value, liveModel, this.$rootGetters, { dispatch: this.$dispatch }, 'management');
148
+ const conflicts = await handleConflict(
149
+ initialValue,
150
+ value,
151
+ liveModel,
152
+ {
153
+ dispatch: this.$dispatch,
154
+ getters: this.$rootGetters
155
+ },
156
+ 'management'
157
+ );
149
158
 
150
159
  if ( conflicts === false ) {
151
160
  // It was automatically figured out, save again
@@ -1,5 +1,5 @@
1
- import { NAME as PRODUCT_NAME } from '@shell/config/product/cis';
2
- import { CIS } from '@shell/config/types';
1
+ import { NAME as PRODUCT_NAME } from '@shell/config/product/compliance';
2
+ import { COMPLIANCE } from '@shell/config/types';
3
3
  import { findBy } from '@shell/utils/array';
4
4
  import { downloadFile, generateZip } from '@shell/utils/download';
5
5
  import { get, isEmpty } from '@shell/utils/object';
@@ -53,7 +53,7 @@ export default class ClusterScan extends SteveModel {
53
53
  action: 'downloadLatestReport',
54
54
  enabled: this.hasReport,
55
55
  icon: 'icon icon-fw icon-download',
56
- label: t('cis.downloadReport'),
56
+ label: t('compliance.downloadReport'),
57
57
  total: 1,
58
58
  };
59
59
 
@@ -61,7 +61,7 @@ export default class ClusterScan extends SteveModel {
61
61
  action: 'downloadAllReports',
62
62
  enabled: this.hasReport,
63
63
  icon: 'icon icon-fw icon-download',
64
- label: t('cis.downloadAllReports'),
64
+ label: t('compliance.downloadAllReports'),
65
65
  total: 1,
66
66
  };
67
67
 
@@ -69,7 +69,7 @@ export default class ClusterScan extends SteveModel {
69
69
  out.unshift({ divider: true });
70
70
  if (this.spec?.scheduledScanConfig?.cronSchedule) {
71
71
  out.unshift(downloadAllReports);
72
- downloadReport.label = t('cis.downloadLatestReport');
72
+ downloadReport.label = t('compliance.downloadLatestReport');
73
73
  }
74
74
  out.unshift(downloadReport);
75
75
  }
@@ -92,7 +92,7 @@ export default class ClusterScan extends SteveModel {
92
92
  get hasReports() {
93
93
  const { relationships = [] } = this.metadata;
94
94
 
95
- const reportRel = findBy(relationships, 'toType', CIS.REPORT);
95
+ const reportRel = findBy(relationships, 'toType', COMPLIANCE.REPORT);
96
96
 
97
97
  return !!reportRel;
98
98
  }
@@ -100,7 +100,7 @@ export default class ClusterScan extends SteveModel {
100
100
  async getReports() {
101
101
  const owned = await this.findOwned();
102
102
 
103
- const reports = owned.filter((obj) => obj.type === CIS.REPORT) || [];
103
+ const reports = owned.filter((obj) => obj.type === COMPLIANCE.REPORT) || [];
104
104
 
105
105
  return sortBy(reports, 'metadata.creationTimestamp', true);
106
106
  }
@@ -158,7 +158,7 @@ export default class ClusterScan extends SteveModel {
158
158
  return {
159
159
  name: 'c-cluster-product-resource-id',
160
160
  params: {
161
- resource: CIS.CLUSTER_SCAN_PROFILE,
161
+ resource: COMPLIANCE.CLUSTER_SCAN_PROFILE,
162
162
  product: PRODUCT_NAME,
163
163
  id: this.status?.lastRunScanProfileName
164
164
  }
@@ -3,7 +3,7 @@ import SteveModel from '@shell/plugins/steve/steve-class';
3
3
 
4
4
  export default class ClusterScanBenchmark extends SteveModel {
5
5
  warnDeletionMessage(toRemove = []) {
6
- return this.$rootGetters['i18n/t']('cis.deleteBenchmarkWarning', { count: toRemove.length });
6
+ return this.$rootGetters['i18n/t']('compliance.deleteBenchmarkWarning', { count: toRemove.length });
7
7
  }
8
8
 
9
9
  get isDefault() {
@@ -1,11 +1,11 @@
1
1
 
2
2
  import SteveModel from '@shell/plugins/steve/steve-class';
3
- import { NAME as PRODUCT_NAME } from '@shell/config/product/cis';
4
- import { CIS } from '@shell/config/types';
3
+ import { NAME as PRODUCT_NAME } from '@shell/config/product/compliance';
4
+ import { COMPLIANCE } from '@shell/config/types';
5
5
 
6
- export default class CISProfile extends SteveModel {
6
+ export default class ComplianceProfile extends SteveModel {
7
7
  warnDeletionMessage(toRemove = []) {
8
- return this.$rootGetters['i18n/t']('cis.deleteProfileWarning', { count: toRemove.length });
8
+ return this.$rootGetters['i18n/t']('compliance.deleteProfileWarning', { count: toRemove.length });
9
9
  }
10
10
 
11
11
  get numberTestsSkipped() {
@@ -19,7 +19,7 @@ export default class CISProfile extends SteveModel {
19
19
  return {
20
20
  name: 'c-cluster-product-resource-id',
21
21
  params: {
22
- resource: CIS.BENCHMARK,
22
+ resource: COMPLIANCE.BENCHMARK,
23
23
  product: PRODUCT_NAME,
24
24
  id: this.spec?.benchmarkVersion
25
25
  }
@@ -1,7 +1,7 @@
1
1
  import { compare } from '@shell/utils/sort';
2
2
  import SteveModel from '@shell/plugins/steve/steve-class';
3
3
 
4
- export default class CISReport extends SteveModel {
4
+ export default class ComplianceReport extends SteveModel {
5
5
  get aggregatedTests() {
6
6
  const json = this.parsedReport;
7
7
  const results = json?.results;
@@ -1,5 +1,4 @@
1
- import { convert, matching, convertSelectorObj } from '@shell/utils/selector';
2
- import jsyaml from 'js-yaml';
1
+ import { matching, convertSelectorObj } from '@shell/utils/selector';
3
2
  import isEmpty from 'lodash/isEmpty';
4
3
  import { escapeHtml } from '@shell/utils/string';
5
4
  import { FLEET, MANAGEMENT } from '@shell/config/types';
@@ -139,85 +138,11 @@ export default class FleetApplication extends SteveModel {
139
138
  }
140
139
 
141
140
  get targetInfo() {
142
- let mode = null;
143
- let cluster = null;
144
- let clusterGroup = null;
145
- let advanced = null;
146
-
147
- const targets = this.spec.targets || [];
148
-
149
- advanced = jsyaml.dump(targets);
150
-
151
- if (advanced === '[]\n') {
152
- advanced = `# - name:
153
- # clusterSelector:
154
- # matchLabels:
155
- # foo: bar
156
- # matchExpressions:
157
- # - key: foo
158
- # op: In
159
- # values: [bar, baz]
160
- # clusterGroup: foo
161
- # clusterGroupSelector:
162
- # matchLabels:
163
- # foo: bar
164
- # matchExpressions:
165
- # - key: foo
166
- # op: In
167
- # values: [bar, baz]
168
- `;
169
- }
170
-
171
- if (this.metadata.namespace === 'fleet-local') {
172
- mode = 'local';
173
- } else if (!targets.length) {
174
- mode = 'none';
175
- } else if (targets.length === 1) {
176
- const target = targets[0];
177
-
178
- if (Object.keys(target).length > 1) {
179
- // There are multiple properties in a single target, so use the 'advanced' mode
180
- // (otherwise any existing content is nuked for what we provide)
181
- mode = 'advanced';
182
- } else if (target.clusterGroup) {
183
- clusterGroup = target.clusterGroup;
184
-
185
- if (!mode) {
186
- mode = 'clusterGroup';
187
- }
188
- } else if (target.clusterName) {
189
- mode = 'cluster';
190
- cluster = target.clusterName;
191
- } else if (target.clusterSelector) {
192
- if (Object.keys(target.clusterSelector).length === 0) {
193
- mode = 'all';
194
- } else {
195
- const expressions = convert(target.clusterSelector.matchLabels, target.clusterSelector.matchExpressions);
196
-
197
- if (expressions.length === 1 &&
198
- expressions[0].key === FLEET_ANNOTATIONS.CLUSTER_NAME &&
199
- expressions[0].operator === 'In' &&
200
- expressions[0].values.length === 1
201
- ) {
202
- cluster = expressions[0].values[0];
203
- if (!mode) {
204
- mode = 'cluster';
205
- }
206
- }
207
- }
208
- }
209
- }
210
-
211
- if (!mode) {
212
- mode = 'advanced';
213
- }
141
+ const mode = FleetUtils.Application.getTargetMode(this.spec.targets || [], this.metadata.namespace);
214
142
 
215
143
  return {
216
144
  mode,
217
145
  modeDisplay: this.t(`fleet.gitRepo.targetDisplay."${ mode }"`),
218
- cluster,
219
- clusterGroup,
220
- advanced
221
146
  };
222
147
  }
223
148
 
@@ -361,17 +286,21 @@ export default class FleetApplication extends SteveModel {
361
286
  return this.status?.readyClusters || 0;
362
287
  }
363
288
 
289
+ get meta() {
290
+ return this.currentRoute()?.meta || {};
291
+ }
292
+
364
293
  get _detailLocation() {
365
294
  return {
366
295
  ...super._detailLocation,
367
- name: 'c-cluster-fleet-application-resource-namespace-id'
296
+ name: this.meta.detailLocation || super._detailLocation.name
368
297
  };
369
298
  }
370
299
 
371
300
  get doneOverride() {
372
301
  return {
373
302
  ...super.listLocation,
374
- name: 'c-cluster-fleet-application'
303
+ name: this.meta.doneOverride || super.listLocation.name
375
304
  };
376
305
  }
377
306
 
@@ -136,6 +136,17 @@ export default class FleetCluster extends SteveModel {
136
136
  };
137
137
  }
138
138
 
139
+ get helmOpsInfo() {
140
+ const ready = this.status?.readyHelmOps || 0;
141
+ const total = this.status?.desiredReadyHelmOps || 0;
142
+
143
+ return {
144
+ ready,
145
+ unready: total - ready,
146
+ total,
147
+ };
148
+ }
149
+
139
150
  get bundleInfo() {
140
151
  const bundlesData = {
141
152
  ready: 0,
@@ -212,8 +223,8 @@ export default class FleetCluster extends SteveModel {
212
223
  return parsedLabels;
213
224
  }
214
225
 
215
- async saveYaml(yaml) {
216
- await this._saveYaml(yaml);
226
+ async saveYaml(yaml, initialYaml) {
227
+ await this._saveYaml(yaml, initialYaml);
217
228
 
218
229
  const parsed = jsyaml.load(yaml);
219
230
 
@@ -118,10 +118,10 @@ export default class GitRepo extends FleetApplication {
118
118
 
119
119
  get resourceIcon() {
120
120
  if (this.github) {
121
- return FleetUtils.resourceIcons[FLEET.GIT_REPO];
121
+ return 'icon icon-github';
122
122
  }
123
123
 
124
- return '';
124
+ return FleetUtils.resourceIcons[FLEET.GIT_REPO];
125
125
  }
126
126
 
127
127
  get repoDisplay() {