@rancher/shell 3.0.12-rc.3 → 3.0.12-rc.5

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 (315) hide show
  1. package/assets/styles/global/_button.scss +1 -1
  2. package/assets/styles/global/_layout.scss +4 -0
  3. package/assets/translations/en-us.yaml +183 -51
  4. package/assets/translations/zh-hans.yaml +1 -7
  5. package/chart/monitoring/ClusterSelector.vue +0 -21
  6. package/chart/monitoring/prometheus/index.vue +6 -3
  7. package/components/ActionDropdownShell.vue +5 -3
  8. package/components/ButtonGroup.vue +26 -1
  9. package/components/CruResource.vue +212 -16
  10. package/components/ExplorerMembers.vue +8 -4
  11. package/components/ExplorerProjectsNamespaces.vue +10 -6
  12. package/components/GrowlManager.vue +4 -0
  13. package/components/MgmtNodeList.vue +184 -0
  14. package/components/PromptRestore.vue +93 -32
  15. package/components/Questions/index.vue +1 -0
  16. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  17. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  18. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  19. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  20. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
  21. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  22. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  23. package/components/ResourceDetail/index.vue +1 -1
  24. package/components/ResourceList/Masthead.vue +7 -1
  25. package/components/ResourceList/index.vue +82 -1
  26. package/components/ResourceTable.vue +1 -0
  27. package/components/RichTranslation.vue +5 -2
  28. package/components/Setting.vue +1 -0
  29. package/components/SortableTable/index.vue +4 -3
  30. package/components/SubtleLink.vue +31 -6
  31. package/components/Tabbed/Tab.vue +29 -3
  32. package/components/Tabbed/index.vue +25 -3
  33. package/components/TableOfContents/TableOfContents.vue +109 -0
  34. package/components/TableOfContents/composables.ts +258 -0
  35. package/components/Window/ContainerShell.vue +21 -11
  36. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  37. package/components/Wizard.vue +23 -5
  38. package/components/__tests__/ButtonGroup.test.ts +56 -0
  39. package/components/__tests__/PromptRestore.test.ts +169 -19
  40. package/components/fleet/AppCoChartGrid.vue +401 -0
  41. package/components/fleet/AppCoEmptyState.vue +127 -0
  42. package/components/fleet/AppCoPageHeader.vue +119 -0
  43. package/components/fleet/AppCoVersionSelect.vue +70 -0
  44. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  45. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  46. package/components/fleet/FleetClusterTargets/index.vue +189 -146
  47. package/components/fleet/FleetIntro.vue +7 -3
  48. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  49. package/components/fleet/FleetSecretSelector.vue +5 -3
  50. package/components/fleet/FleetValuesFrom.vue +8 -2
  51. package/components/fleet/GitRepoAdvancedTab.vue +1 -0
  52. package/components/fleet/GitRepoMetadataTab.vue +5 -0
  53. package/components/fleet/GitRepoTargetTab.vue +0 -2
  54. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  55. package/components/fleet/HelmOpAppCoConfigTab.vue +597 -0
  56. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  57. package/components/fleet/HelmOpMetadataTab.vue +5 -0
  58. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  59. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  60. package/components/fleet/HelmOpTargetTab.vue +64 -60
  61. package/components/fleet/HelmOpValuesTab.vue +129 -105
  62. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  63. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  64. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  65. package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
  66. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  67. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  68. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  69. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  70. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  71. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  72. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  73. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  74. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  75. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  76. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  77. package/components/fleet/dashboard/Empty.vue +8 -4
  78. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  79. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  80. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  81. package/components/form/ArrayList.vue +61 -4
  82. package/components/form/FileSelector.vue +39 -1
  83. package/components/form/KeyValue.vue +23 -2
  84. package/components/form/LabeledSelect.vue +39 -1
  85. package/components/form/Labels.vue +22 -3
  86. package/components/form/NameNsDescription.vue +13 -5
  87. package/components/form/PrivateRegistry.constants.ts +7 -0
  88. package/components/form/PrivateRegistry.vue +253 -18
  89. package/components/form/ResourceTabs/index.vue +1 -0
  90. package/components/form/SelectOrCreateAuthSecret.vue +140 -17
  91. package/components/form/__tests__/FileSelector.test.ts +23 -0
  92. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  93. package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
  94. package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
  95. package/components/formatter/EtcdSnapshotName.vue +73 -0
  96. package/components/formatter/InternalExternalIP.vue +10 -4
  97. package/components/formatter/ServiceTargets.vue +26 -7
  98. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  99. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  100. package/components/nav/Header.vue +12 -1
  101. package/components/nav/TopLevelMenu.vue +7 -2
  102. package/components/nav/__tests__/Header.test.ts +15 -0
  103. package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
  104. package/components/templates/default.vue +16 -4
  105. package/components/templates/home.vue +9 -4
  106. package/components/templates/plain.vue +9 -4
  107. package/composables/useHelmOpResources.test.ts +56 -0
  108. package/composables/useHelmOpResources.ts +32 -0
  109. package/composables/useStateColor.test.ts +325 -0
  110. package/composables/useStateColor.ts +128 -0
  111. package/config/features.js +1 -0
  112. package/config/home-links.js +1 -1
  113. package/config/labels-annotations.js +3 -0
  114. package/config/product/explorer.js +17 -4
  115. package/config/product/manager.js +8 -0
  116. package/config/router/index.js +16 -0
  117. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  118. package/config/router/navigation-guards/authentication.js +10 -4
  119. package/config/router/routes.js +20 -6
  120. package/config/secret.ts +10 -0
  121. package/config/settings.ts +6 -4
  122. package/config/table-headers.js +3 -4
  123. package/config/types.js +16 -0
  124. package/core/plugin-products-base.ts +3 -3
  125. package/core/plugin-types.ts +83 -30
  126. package/core/plugin.ts +3 -0
  127. package/core/types-provisioning.ts +34 -1
  128. package/core/types.ts +15 -2
  129. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  130. package/detail/__tests__/workload.test.ts +3 -152
  131. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  132. package/detail/provisioning.cattle.io.cluster.vue +109 -7
  133. package/detail/workload/index.vue +12 -55
  134. package/dialog/RotateEncryptionKeyDialog.vue +33 -9
  135. package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
  136. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  137. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
  138. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +206 -0
  139. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  140. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  141. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  142. package/edit/auth/__tests__/azuread.test.ts +34 -9
  143. package/edit/auth/__tests__/github.test.ts +234 -0
  144. package/edit/auth/__tests__/oidc.test.ts +26 -6
  145. package/edit/auth/__tests__/saml.test.ts +196 -0
  146. package/edit/auth/azuread.vue +128 -95
  147. package/edit/auth/github.vue +72 -13
  148. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  149. package/edit/auth/ldap/config.vue +8 -0
  150. package/edit/auth/ldap/index.vue +75 -1
  151. package/edit/auth/oidc.vue +119 -73
  152. package/edit/auth/saml.vue +76 -12
  153. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  154. package/edit/compliance.cattle.io.clusterscanprofile.vue +39 -41
  155. package/edit/fleet.cattle.io.gitrepo.vue +70 -16
  156. package/edit/fleet.cattle.io.helmop.vue +542 -141
  157. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  158. package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
  159. package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
  160. package/edit/management.cattle.io.user.vue +5 -2
  161. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
  162. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
  163. package/edit/provisioning.cattle.io.cluster/rke2.vue +89 -11
  164. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  165. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
  166. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
  167. package/list/group.principal.vue +5 -4
  168. package/list/harvesterhci.io.management.cluster.vue +8 -9
  169. package/list/management.cattle.io.user.vue +12 -9
  170. package/list/provisioning.cattle.io.cluster.vue +16 -10
  171. package/mixins/__tests__/auth-config.test.ts +90 -0
  172. package/mixins/__tests__/chart.test.ts +94 -0
  173. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  174. package/mixins/auth-config.js +7 -0
  175. package/mixins/chart.js +11 -2
  176. package/mixins/child-hook.js +12 -6
  177. package/mixins/create-edit-view/impl.js +5 -3
  178. package/mixins/resource-fetch-api-pagination.js +21 -1
  179. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  180. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  181. package/models/__tests__/fleet-application.test.ts +175 -0
  182. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  183. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  184. package/models/__tests__/management.cattle.io.node.ts +22 -0
  185. package/models/__tests__/namespace.test.ts +36 -0
  186. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +205 -0
  187. package/models/__tests__/secret.test.ts +68 -1
  188. package/models/__tests__/workload.test.ts +401 -26
  189. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  190. package/models/compliance.cattle.io.clusterscan.js +39 -4
  191. package/models/fleet-application.js +4 -0
  192. package/models/fleet.cattle.io.helmop.js +20 -1
  193. package/models/management.cattle.io.cluster.js +39 -5
  194. package/models/management.cattle.io.node.js +44 -3
  195. package/models/namespace.js +1 -1
  196. package/models/pod.js +46 -3
  197. package/models/provisioning.cattle.io.cluster.js +64 -14
  198. package/models/rke.cattle.io.etcdsnapshot.js +17 -9
  199. package/models/secret.js +19 -0
  200. package/models/workload.js +120 -20
  201. package/models/workload.service.js +5 -0
  202. package/package.json +14 -13
  203. package/pages/about.vue +5 -6
  204. package/pages/auth/login.vue +0 -35
  205. package/pages/auth/setup.vue +11 -0
  206. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  207. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  208. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  209. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +485 -107
  210. package/pages/c/_cluster/apps/charts/chart.vue +2 -1
  211. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  212. package/pages/c/_cluster/apps/charts/install.vue +236 -144
  213. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  214. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  215. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  216. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  217. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  218. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  219. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  220. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  221. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  222. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  223. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  224. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  225. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  226. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  227. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  228. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  229. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  230. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  231. package/pages/c/_cluster/fleet/index.vue +2 -2
  232. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
  233. package/pages/c/_cluster/uiplugins/index.vue +15 -0
  234. package/pages/fail-whale.vue +16 -11
  235. package/pages/home.vue +16 -46
  236. package/pkg/require-asset.lib.js +25 -0
  237. package/pkg/vue.config.js +7 -0
  238. package/plugins/clean-html.d.ts +9 -0
  239. package/plugins/dashboard-store/__tests__/resource-class.test.ts +177 -0
  240. package/plugins/dashboard-store/getters.js +0 -1
  241. package/plugins/dashboard-store/resource-class.js +114 -19
  242. package/plugins/steve/__tests__/actions.test.ts +212 -0
  243. package/plugins/steve/actions.js +96 -0
  244. package/plugins/steve/steve-pagination-utils.ts +1 -1
  245. package/rancher-components/Accordion/Accordion.vue +53 -9
  246. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  247. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  248. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  249. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
  250. package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
  251. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  252. package/rancher-components/RcButton/RcButton.test.ts +103 -0
  253. package/rancher-components/RcButton/RcButton.vue +94 -15
  254. package/rancher-components/RcButton/index.ts +1 -1
  255. package/rancher-components/RcButton/types.ts +3 -0
  256. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
  257. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  258. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  259. package/rancher-components/RcSection/RcSection.vue +28 -3
  260. package/scripts/extension/helm/package/Dockerfile +1 -1
  261. package/scripts/test-plugins-build.sh +2 -1
  262. package/store/__tests__/features.test.ts +131 -0
  263. package/store/__tests__/growl.test.ts +374 -0
  264. package/store/__tests__/modal.test.ts +131 -0
  265. package/store/__tests__/notifications.test.ts +434 -0
  266. package/store/__tests__/slideInPanel.test.ts +88 -0
  267. package/store/__tests__/type-map.utils.test.ts +433 -0
  268. package/store/catalog.js +57 -0
  269. package/store/features.js +4 -0
  270. package/store/plugins.js +7 -4
  271. package/types/components/buttonGroup.ts +5 -0
  272. package/types/shell/index.d.ts +166 -70
  273. package/utils/__tests__/auth.test.ts +273 -0
  274. package/utils/__tests__/computed.test.ts +193 -0
  275. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  276. package/utils/__tests__/dom.test.ts +81 -0
  277. package/utils/__tests__/duration.test.ts +37 -1
  278. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  279. package/utils/__tests__/fleet-appco.test.ts +312 -0
  280. package/utils/__tests__/monitoring.test.ts +130 -0
  281. package/utils/__tests__/object.test.ts +22 -0
  282. package/utils/__tests__/operation-cr.test.ts +34 -0
  283. package/utils/__tests__/platform.test.ts +91 -0
  284. package/utils/__tests__/position.test.ts +237 -0
  285. package/utils/__tests__/provider.test.ts +51 -1
  286. package/utils/__tests__/queue.test.ts +232 -0
  287. package/utils/__tests__/release-notes.test.ts +221 -0
  288. package/utils/__tests__/router.test.js +254 -1
  289. package/utils/__tests__/select.test.ts +208 -0
  290. package/utils/__tests__/time.test.ts +265 -1
  291. package/utils/__tests__/title.test.ts +47 -0
  292. package/utils/__tests__/width.test.ts +53 -0
  293. package/utils/__tests__/window.test.ts +158 -0
  294. package/utils/__tests__/xccdf.test.ts +126 -6
  295. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  296. package/utils/crypto/__tests__/index.test.ts +144 -0
  297. package/utils/duration.ts +104 -0
  298. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  299. package/utils/dynamic-content/info.ts +2 -1
  300. package/utils/error.js +13 -0
  301. package/utils/fleet-appco.ts +323 -0
  302. package/utils/object.js +22 -2
  303. package/utils/operation-cr.js +19 -0
  304. package/utils/provider.ts +12 -0
  305. package/utils/require-asset.ts +7 -0
  306. package/utils/validators/__tests__/container-images.test.ts +104 -0
  307. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  308. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  309. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  310. package/utils/validators/__tests__/private-registry.test.ts +27 -15
  311. package/utils/validators/private-registry.ts +15 -4
  312. package/utils/xccdf.ts +39 -42
  313. package/vue.config.js +1 -1
  314. package/pages/support/index.vue +0 -264
  315. package/utils/duration.js +0 -43
@@ -5,9 +5,12 @@ import jsyaml from 'js-yaml';
5
5
  import { saferDump } from '@shell/utils/create-yaml';
6
6
  import { mapGetters } from 'vuex';
7
7
  import { base64Encode } from '@shell/utils/crypto';
8
- import { _CREATE, _EDIT } from '@shell/config/query-params';
8
+ import { _CREATE, _EDIT, SUB_TYPE } from '@shell/config/query-params';
9
9
  import { checkSchemasForFindAllHash } from '@shell/utils/auth';
10
- import { AUTH_TYPE, CONFIG_MAP, NORMAN, SECRET } from '@shell/config/types';
10
+ import {
11
+ AUTH_TYPE, CONFIG_MAP, FLEET, AUTH_GENERATE_NAME, NORMAN, SECRET
12
+ } from '@shell/config/types';
13
+ import { FLEET_APPCO_AUTH_GENERATE_NAME, IMAGE_PULL_SECRET_SUFFIX, SUSE_APP_COLLECTION_REPO_URL, deriveRepoName } from '@shell/utils/fleet-appco';
11
14
  import { CATALOG, FLEET as FLEET_LABELS } from '@shell/config/labels-annotations';
12
15
  import { SOURCE_TYPE } from '@shell/config/product/fleet';
13
16
  import CreateEditView from '@shell/mixins/create-edit-view';
@@ -27,6 +30,7 @@ import HelmOpChartTab from '@shell/components/fleet/HelmOpChartTab.vue';
27
30
  import HelmOpValuesTab from '@shell/components/fleet/HelmOpValuesTab.vue';
28
31
  import HelmOpTargetTab from '@shell/components/fleet/HelmOpTargetTab.vue';
29
32
  import HelmOpAdvancedTab from '@shell/components/fleet/HelmOpAdvancedTab.vue';
33
+ import HelmOpAppCoConfigTab from '@shell/components/fleet/HelmOpAppCoConfigTab.vue';
30
34
 
31
35
  const MINIMUM_POLLING_INTERVAL = 15;
32
36
 
@@ -35,6 +39,22 @@ const VALUES_STATE = {
35
39
  DIFF: 'DIFF'
36
40
  };
37
41
 
42
+ function checkIsSuseAppCollection(route, value) {
43
+ // CREATE: route query param set by the subtype selector
44
+ // EDIT: annotation set on the resource during create, or URL fallback for older resources
45
+ return route.query[SUB_TYPE] === FLEET.SUSE_APP_COLLECTION ||
46
+ value.isSuseAppCollectionFromUI;
47
+ }
48
+
49
+ function getInitialSourceType(route, value, modelSourceType) {
50
+ if (checkIsSuseAppCollection(route, value)) {
51
+ return SOURCE_TYPE.OCI;
52
+ }
53
+
54
+ // REPO is the default value
55
+ return modelSourceType || SOURCE_TYPE.REPO;
56
+ }
57
+
38
58
  export default {
39
59
  name: 'CruHelmOp',
40
60
 
@@ -53,6 +73,7 @@ export default {
53
73
  HelmOpValuesTab,
54
74
  HelmOpTargetTab,
55
75
  HelmOpAdvancedTab,
76
+ HelmOpAppCoConfigTab,
56
77
  },
57
78
 
58
79
  mixins: [CreateEditView, FormValidation],
@@ -61,12 +82,12 @@ export default {
61
82
  // Fetch Secrets and ConfigMaps to mask the loading phase in FleetValuesFrom.vue
62
83
  checkSchemasForFindAllHash({
63
84
  allSecrets: {
64
- inStoreType: 'management',
85
+ inStoreType: CATALOG._MANAGEMENT,
65
86
  type: SECRET
66
87
  },
67
88
 
68
89
  allConfigMaps: {
69
- inStoreType: 'management',
90
+ inStoreType: CATALOG._MANAGEMENT,
70
91
  type: CONFIG_MAP
71
92
  }
72
93
  }, this.$store);
@@ -81,10 +102,10 @@ export default {
81
102
  return {
82
103
  VALUES_STATE,
83
104
  SOURCE_TYPE,
84
- allWorkspaces: [],
105
+ currentUser: null,
85
106
  pollingInterval: toSeconds(this.value.spec.pollingInterval) || this.value.spec.pollingInterval,
86
107
  sourceTypeInit: this.value.sourceType,
87
- sourceType: this.value.sourceType || SOURCE_TYPE.REPO,
108
+ sourceType: getInitialSourceType(this.$route, this.value, this.value.sourceType),
88
109
  helmSpecInit: clone(this.value.spec.helm),
89
110
  yamlForm: VALUES_STATE.YAML,
90
111
  chartValues,
@@ -95,6 +116,11 @@ export default {
95
116
  isRealModeEdit: this.realMode === _EDIT,
96
117
  targetsCreated: '',
97
118
  fvFormRuleSets: [],
119
+
120
+ // Raw chart index entries from the ClusterRepo, keyed by chart name
121
+ appCoChartEntries: {},
122
+ // True while fetching the chart index from the ClusterRepo
123
+ appCoChartsLoading: false,
98
124
  };
99
125
  },
100
126
 
@@ -110,12 +136,59 @@ export default {
110
136
  mounted() {
111
137
  this.value.applyDefaults();
112
138
  this.updateValidationRules(this.sourceType);
139
+
140
+ if (this.isSuseAppCollection) {
141
+ const repo = this.value.spec?.helm?.repo || '';
142
+
143
+ if (!repo) {
144
+ set(this.value, 'spec.helm.repo', SUSE_APP_COLLECTION_REPO_URL);
145
+ } else if (repo.startsWith(SUSE_APP_COLLECTION_REPO_URL) && repo.length > SUSE_APP_COLLECTION_REPO_URL.length) {
146
+ const chart = repo.slice(SUSE_APP_COLLECTION_REPO_URL.length).replace(/^\//, '');
147
+
148
+ set(this.value, 'spec.helm.repo', SUSE_APP_COLLECTION_REPO_URL);
149
+ set(this.value, 'spec.helm.chart', chart);
150
+ }
151
+
152
+ if (this.realMode === _CREATE) {
153
+ const queryChart = this.$route.query.chart;
154
+ const querySecret = this.$route.query.secret;
155
+ const queryVersion = this.$route.query.version;
156
+
157
+ if (queryChart) {
158
+ set(this.value, 'spec.helm.chart', queryChart);
159
+ }
160
+
161
+ if (queryVersion) {
162
+ set(this.value, 'spec.helm.version', queryVersion);
163
+ }
164
+
165
+ if (querySecret) {
166
+ const ns = this.value.metadata.namespace;
167
+
168
+ this.updateAuth(`${ ns }/${ querySecret }`, 'helmSecretName');
169
+ this.addAppCoImagePullSecretToSpec(`${ querySecret }${ IMAGE_PULL_SECRET_SUFFIX }`);
170
+
171
+ this.fetchAppCoCharts(deriveRepoName(querySecret));
172
+ }
173
+ } else {
174
+ const rawSecret = this.value.spec?.helmSecretName || '';
175
+ const secretName = rawSecret.includes('/') ? rawSecret.split('/')[1] : rawSecret;
176
+
177
+ if (secretName) {
178
+ this.fetchAppCoCharts(deriveRepoName(secretName));
179
+ }
180
+ }
181
+ }
113
182
  },
114
183
 
115
184
  computed: {
116
185
  ...mapGetters(['workspace']),
117
186
 
118
187
  steps() {
188
+ if (this.isSuseAppCollection) {
189
+ return [];
190
+ }
191
+
119
192
  return [
120
193
  {
121
194
  name: 'basics',
@@ -123,7 +196,7 @@ export default {
123
196
  label: this.t('fleet.helmOp.add.steps.metadata.label'),
124
197
  subtext: this.t('fleet.helmOp.add.steps.metadata.subtext'),
125
198
  descriptionKey: 'fleet.helmOp.add.steps.metadata.description',
126
- ready: this.isView || !!this.value.metadata.name,
199
+ ready: this.isView || (!!this.value.metadata.name && this.stepPathErrors('basics').length === 0),
127
200
  weight: 1
128
201
  },
129
202
  {
@@ -165,6 +238,10 @@ export default {
165
238
  ];
166
239
  },
167
240
 
241
+ isSuseAppCollection() {
242
+ return checkIsSuseAppCollection(this.$route, this.value);
243
+ },
244
+
168
245
  sourceTypeOptions() {
169
246
  return Object.values(SOURCE_TYPE).map((value) => ({
170
247
  value,
@@ -234,6 +311,71 @@ export default {
234
311
  downstreamConfigMapsList() {
235
312
  return (this.value.spec.downstreamResources || []).filter((r) => r.kind === 'ConfigMap').map((r) => r.name);
236
313
  },
314
+
315
+ appCoConfigProps() {
316
+ return {
317
+ value: this.value,
318
+ mode: this.mode,
319
+ realMode: this.realMode,
320
+ appCoChartEntries: this.appCoChartEntries,
321
+ appCoChartsLoading: this.appCoChartsLoading,
322
+ chartValues: this.chartValues,
323
+ chartValuesInit: this.chartValuesInit,
324
+ yamlForm: this.yamlForm,
325
+ yamlFormOptions: this.yamlFormOptions,
326
+ yamlDiffModeOptions: this.yamlDiffModeOptions,
327
+ isYamlDiff: this.isYamlDiff,
328
+ editorMode: this.editorMode,
329
+ diffMode: this.diffMode,
330
+ isRealModeEdit: this.isRealModeEdit,
331
+ targetsCreated: this.targetsCreated,
332
+ correctDriftEnabled: this.correctDriftEnabled,
333
+ downstreamSecretsList: this.downstreamSecretsList,
334
+ downstreamConfigMapsList: this.downstreamConfigMapsList,
335
+ registerBeforeHook: this.registerBeforeHook,
336
+ };
337
+ },
338
+
339
+ appCoConfigListeners() {
340
+ return {
341
+ 'update:value': this.emitInput,
342
+ 'update:yaml-form': this.updateYamlForm,
343
+ 'update:chart-values': this.updateChartValues,
344
+ 'update:diff-mode': (e) => {
345
+ this.diffMode = e;
346
+ },
347
+ 'update:targets': this.updateTargets,
348
+ 'targets-created': (e) => {
349
+ this.targetsCreated = e;
350
+ },
351
+ 'update:auth': (e) => this.updateAuth(e.value, e.key),
352
+ 'update:cached-auth': (e) => this.updateCachedAuthVal(e.value, e.key),
353
+ 'update:correct-drift': (e) => {
354
+ this.correctDriftEnabled = e;
355
+ },
356
+ 'update:downstream-resources': (e) => this.updateDownstreamResources(e.kind, e.list),
357
+ };
358
+ },
359
+
360
+ appCoViewTabs() {
361
+ return [
362
+ {
363
+ name: 'chartConfig',
364
+ label: this.t('fleet.helmOp.appCoView.chartConfig'),
365
+ weight: 3
366
+ },
367
+ {
368
+ name: 'targetDetails',
369
+ label: this.t('fleet.helmOp.appCoView.targetDetails'),
370
+ weight: 2
371
+ },
372
+ {
373
+ name: 'advanced',
374
+ label: this.t('fleet.helmOp.appCoView.advanced'),
375
+ weight: 1
376
+ },
377
+ ];
378
+ },
237
379
  },
238
380
 
239
381
  watch: {
@@ -245,7 +387,75 @@ export default {
245
387
  },
246
388
 
247
389
  methods: {
390
+ emitInput(e) {
391
+ this.$emit('input', e);
392
+ },
393
+
394
+ async handleSave(btnCb) {
395
+ if (!this.isSuseAppCollection) {
396
+ return this.save(btnCb);
397
+ }
398
+
399
+ const origRepo = this.value.spec?.helm?.repo;
400
+ const origChart = this.value.spec?.helm?.chart;
401
+
402
+ if (this.sourceType === SOURCE_TYPE.OCI && origChart) {
403
+ const repo = (origRepo || '').replace(/\/$/, '');
404
+
405
+ set(this.value, 'spec.helm.repo', `${ repo }/${ origChart }`);
406
+ delete this.value.spec.helm.chart;
407
+ }
408
+
409
+ await this.save((success) => {
410
+ if (!success && origChart) {
411
+ set(this.value, 'spec.helm.repo', origRepo);
412
+ set(this.value, 'spec.helm.chart', origChart);
413
+ }
414
+ btnCb(success);
415
+ });
416
+ },
417
+
418
+ refreshAppCoAdvancedYaml() {
419
+ this.$refs.appCoAdvancedRef?.refreshYamlEditor?.();
420
+ },
421
+
422
+ onCancel() {
423
+ if (this.isSuseAppCollection && this.realMode === _CREATE) {
424
+ const querySecret = this.$route.query.secret;
425
+ const queryChart = this.$route.query.chart;
426
+ const repoName = deriveRepoName(querySecret || '');
427
+
428
+ this.$router.push({
429
+ name: 'c-cluster-fleet-application-appco-chart',
430
+ params: { cluster: this.$route.params.cluster },
431
+ query: {
432
+ 'repo-type': 'cluster',
433
+ repo: repoName,
434
+ chart: queryChart,
435
+ version: this.$route.query.version,
436
+ secret: querySecret,
437
+ },
438
+ });
439
+
440
+ return;
441
+ }
442
+
443
+ this.done();
444
+ },
445
+
446
+ stepPathErrors(stepName) {
447
+ // Helper is used to check which validations is for each step
448
+ const paths = this.fvFormRuleSets
449
+ .filter((rule) => rule.step === stepName)
450
+ .map((rule) => rule.path);
451
+
452
+ return this.fvGetPathErrors(paths);
453
+ },
454
+
248
455
  onSourceTypeSelect(type) {
456
+ if (this.isSuseAppCollection) {
457
+ return;
458
+ }
249
459
  this.sourceType = type;
250
460
  delete this.value.spec.helm.repo;
251
461
  delete this.value.spec.helm.chart;
@@ -302,8 +512,6 @@ export default {
302
512
  } else {
303
513
  delete spec[key];
304
514
  }
305
-
306
- this.updateCachedAuthVal(val, key);
307
515
  },
308
516
 
309
517
  async doCreateSecrets() {
@@ -311,7 +519,7 @@ export default {
311
519
  await this.doCreate('clientSecretName', this.tempCachedValues.clientSecretName);
312
520
  }
313
521
 
314
- if (this.tempCachedValues.helmSecretName) {
522
+ if (!this.isSuseAppCollection && this.tempCachedValues.helmSecretName) {
315
523
  await this.doCreate('helmSecretName', this.tempCachedValues.helmSecretName);
316
524
  }
317
525
  },
@@ -343,7 +551,7 @@ export default {
343
551
  type: SECRET,
344
552
  metadata: {
345
553
  namespace: this.value.metadata.namespace,
346
- generateName: 'auth-',
554
+ generateName: AUTH_GENERATE_NAME,
347
555
  labels: { [FLEET_LABELS.MANAGED]: 'true' }
348
556
  }
349
557
  });
@@ -386,6 +594,36 @@ export default {
386
594
  return secret;
387
595
  },
388
596
 
597
+ /**
598
+ * Adds the image-pull-secret to downstreamResources (Secret kind) and
599
+ * to spec.helm.values.global.imagePullSecrets.
600
+ */
601
+ addAppCoImagePullSecretToSpec(imagePullSecretName) {
602
+ // Replace downstream resources: remove stale fleet-appco-auth-* image-pull-secrets, add the current one
603
+ const existingSecrets = (this.value.spec.downstreamResources || []).filter((r) => r.kind === 'Secret');
604
+ const nonAppcoSecrets = existingSecrets.filter((r) => !r.name.startsWith(FLEET_APPCO_AUTH_GENERATE_NAME));
605
+
606
+ this.updateDownstreamResources('Secret', [
607
+ ...nonAppcoSecrets.map((r) => r.name),
608
+ imagePullSecretName,
609
+ ]);
610
+
611
+ // Replace spec.helm.values.global.imagePullSecrets: remove stale fleet-appco-auth-* entries, add the current one
612
+ const currentValues = this.value.spec.helm.values || {};
613
+
614
+ const newValues = {
615
+ ...currentValues,
616
+ global: {
617
+ ...(currentValues.global || {}),
618
+ imagePullSecrets: [imagePullSecretName],
619
+ },
620
+ };
621
+
622
+ set(this.value, 'spec.helm.values', newValues);
623
+ this.chartValuesInit = saferDump(clone(newValues));
624
+ this.chartValues = saferDump(clone(newValues));
625
+ },
626
+
389
627
  updateYamlForm() {
390
628
  if (this.$refs.yaml) {
391
629
  this.$refs.yaml.updateValue(this.chartValues);
@@ -393,6 +631,8 @@ export default {
393
631
  },
394
632
 
395
633
  updateChartValues(value) {
634
+ this.chartValues = value;
635
+
396
636
  try {
397
637
  const chartValues = jsyaml.load(value);
398
638
 
@@ -406,6 +646,20 @@ export default {
406
646
 
407
647
  if (this.mode === _CREATE) {
408
648
  this.value.metadata.labels[FLEET_LABELS.CREATED_BY_USER_ID] = this.currentUser.id;
649
+
650
+ if (this.isSuseAppCollection) {
651
+ if (!this.value.metadata.annotations) {
652
+ this.value.metadata.annotations = {};
653
+ }
654
+
655
+ this.value.metadata.annotations[CATALOG.SUSE_APP_COLLECTION] = 'true';
656
+ }
657
+ }
658
+
659
+ const helmSecret = this.value.spec?.helmSecretName || '';
660
+
661
+ if (helmSecret.includes('/')) {
662
+ this.value.spec.helmSecretName = helmSecret.split('/').pop();
409
663
  }
410
664
  },
411
665
 
@@ -414,30 +668,49 @@ export default {
414
668
  },
415
669
 
416
670
  updateValidationRules(sourceType) {
671
+ const nameRule = {
672
+ step: 'basics',
673
+ path: 'metadata.name',
674
+ rules: ['subDomain'],
675
+ translationKey: 'nameNsDescription.name.label'
676
+ };
677
+
417
678
  switch (sourceType) {
418
679
  case SOURCE_TYPE.REPO:
419
- this.fvFormRuleSets = [{
680
+ this.fvFormRuleSets = [nameRule, {
681
+ step: 'chart',
420
682
  path: 'spec.helm.repo',
421
683
  rules: ['urlRepository'],
422
684
  }, {
685
+ step: 'chart',
423
686
  path: 'spec.helm.chart',
424
687
  rules: ['required'],
425
688
  }, {
689
+ step: 'chart',
426
690
  path: 'spec.helm.version',
427
691
  rules: ['semanticVersion'],
428
692
  }];
429
693
  break;
430
694
  case SOURCE_TYPE.OCI:
431
- this.fvFormRuleSets = [{
695
+ this.fvFormRuleSets = [nameRule, {
696
+ step: 'chart',
432
697
  path: 'spec.helm.repo',
433
698
  rules: ['ociRegistry'],
434
- }, {
699
+ },
700
+ ...(this.isSuseAppCollection ? [{
701
+ step: 'chart',
702
+ path: 'spec.helm.chart',
703
+ rules: ['required'],
704
+ }] : []),
705
+ {
706
+ step: 'chart',
435
707
  path: 'spec.helm.version',
436
- rules: ['semanticVersion'],
708
+ rules: this.isSuseAppCollection ? ['required', 'semanticVersion'] : ['semanticVersion'],
437
709
  }];
438
710
  break;
439
711
  case SOURCE_TYPE.TARBALL:
440
- this.fvFormRuleSets = [{
712
+ this.fvFormRuleSets = [nameRule, {
713
+ step: 'chart',
441
714
  path: 'spec.helm.chart',
442
715
  rules: ['urlRepository'],
443
716
  }];
@@ -445,6 +718,34 @@ export default {
445
718
  }
446
719
  },
447
720
 
721
+ async fetchAppCoCharts(repoName) {
722
+ if (!repoName) {
723
+ return;
724
+ }
725
+
726
+ this.appCoChartsLoading = true;
727
+
728
+ try {
729
+ await this.$store.dispatch('catalog/loadRepo', { repoName });
730
+
731
+ const chartName = this.value.spec.helm.chart;
732
+ const catalogChart = chartName ? this.$store.getters['catalog/chart']({
733
+ repoType: 'cluster',
734
+ repoName,
735
+ chartName,
736
+ includeHidden: true,
737
+ }) : null;
738
+
739
+ if (catalogChart?.versions?.length) {
740
+ this.appCoChartEntries = { [chartName]: catalogChart.versions };
741
+ }
742
+ } catch (e) {
743
+ console.error('Failed to fetch AppCo chart list:', e); // eslint-disable-line no-console
744
+ } finally {
745
+ this.appCoChartsLoading = false;
746
+ }
747
+ },
748
+
448
749
  updateDownstreamResources(kind, list) {
449
750
  switch (kind) {
450
751
  case 'Secret':
@@ -461,6 +762,26 @@ export default {
461
762
  break;
462
763
  }
463
764
  },
765
+
766
+ async beforeNext(activeStep) {
767
+ if (activeStep.name !== 'basics' || !this.isCreate) {
768
+ return;
769
+ }
770
+
771
+ await this.value.dryRunCreate({
772
+ type: this.value.type,
773
+ metadata: {
774
+ name: this.value.metadata.name,
775
+ namespace: this.value.metadata.namespace,
776
+ },
777
+ spec: {
778
+ helm: {
779
+ chart: 'placeholder',
780
+ repo: 'https://example.com',
781
+ },
782
+ }
783
+ });
784
+ },
464
785
  },
465
786
  };
466
787
  </script>
@@ -470,29 +791,41 @@ export default {
470
791
 
471
792
  <CruResource
472
793
  v-else
794
+ ref="cruResource"
473
795
  :done-route="doneRouteList"
474
796
  :mode="mode"
475
797
  :resource="value"
476
798
  :subtypes="[]"
477
- :validation-passed="true"
799
+ :validation-passed="fvFormIsValid"
478
800
  :errors="errors"
479
801
  :steps="!isView ? steps : undefined"
480
802
  :finish-mode="'finish'"
803
+ :cancel-event="true"
804
+ :before-next="beforeNext"
481
805
  class="wizard"
482
- @cancel="done"
806
+ data-testid="helmop-cru-resource"
807
+ @cancel="onCancel"
483
808
  @error="e=>errors = e"
484
- @finish="save"
809
+ @finish="handleSave"
485
810
  >
486
- <template #basics>
811
+ <template
812
+ v-if="!isSuseAppCollection"
813
+ #basics
814
+ >
487
815
  <HelmOpMetadataTab
488
816
  :value="value"
489
817
  :mode="mode"
490
818
  :is-view="isView"
819
+ data-testid="helmop-metadata-tab"
820
+ :name-rules="fvGetAndReportPathRules('metadata.name')"
491
821
  @update:value="$emit('input', $event)"
492
822
  />
493
823
  </template>
494
824
 
495
- <template #chart>
825
+ <template
826
+ v-if="!isSuseAppCollection"
827
+ #chart
828
+ >
496
829
  <HelmOpChartTab
497
830
  :value="value"
498
831
  :mode="mode"
@@ -500,16 +833,19 @@ export default {
500
833
  :source-type="sourceType"
501
834
  :source-type-options="sourceTypeOptions"
502
835
  :fv-get-and-report-path-rules="fvGetAndReportPathRules"
836
+ data-testid="helmop-chart-tab"
503
837
  @update:source-type="onSourceTypeSelect"
504
838
  />
505
839
  </template>
506
840
 
507
- <template #values>
841
+ <template
842
+ v-if="!isSuseAppCollection"
843
+ #values
844
+ >
508
845
  <HelmOpValuesTab
509
846
  :value="value"
510
847
  :mode="mode"
511
848
  :real-mode="realMode"
512
- :is-view="isView"
513
849
  :chart-values="chartValues"
514
850
  :chart-values-init="chartValuesInit"
515
851
  :yaml-form="yamlForm"
@@ -519,30 +855,38 @@ export default {
519
855
  :editor-mode="editorMode"
520
856
  :diff-mode="diffMode"
521
857
  :is-real-mode-edit="isRealModeEdit"
858
+ data-testid="helmop-values-tab"
522
859
  @update:yaml-form="updateYamlForm"
523
860
  @update:chart-values="updateChartValues"
524
861
  @update:diff-mode="diffMode = $event"
525
862
  />
526
863
  </template>
527
864
 
528
- <template #target>
865
+ <template
866
+ v-if="!isSuseAppCollection"
867
+ #target
868
+ >
529
869
  <HelmOpTargetTab
530
870
  :value="value"
531
871
  :mode="mode"
532
872
  :real-mode="realMode"
533
- :is-view="isView"
534
873
  :targets-created="targetsCreated"
874
+ data-testid="helmop-target-tab"
535
875
  @update:targets="updateTargets"
536
876
  @targets-created="targetsCreated=$event"
537
877
  />
538
878
  </template>
539
879
 
540
- <template #advanced>
880
+ <template
881
+ v-if="!isSuseAppCollection"
882
+ #advanced
883
+ >
541
884
  <HelmOpAdvancedTab
542
885
  :value="value"
543
886
  :mode="mode"
544
887
  :is-view="isView"
545
888
  :source-type="sourceType"
889
+ :is-suse-app-collection="isSuseAppCollection"
546
890
  :temp-cached-values="tempCachedValues"
547
891
  :correct-drift-enabled="correctDriftEnabled"
548
892
  :polling-interval="pollingInterval"
@@ -553,6 +897,7 @@ export default {
553
897
  :downstream-secrets-list="downstreamSecretsList"
554
898
  :downstream-config-maps-list="downstreamConfigMapsList"
555
899
  :register-before-hook="registerBeforeHook"
900
+ data-testid="helmop-advanced-tab"
556
901
  @update:auth="updateAuth($event.value, $event.key)"
557
902
  @update:cached-auth="updateCachedAuthVal($event.value, $event.key)"
558
903
  @update:correct-drift="correctDriftEnabled = $event"
@@ -564,143 +909,199 @@ export default {
564
909
  </template>
565
910
 
566
911
  <template
567
- v-if="isView && steps.length === 5"
912
+ v-if="isView || isSuseAppCollection"
568
913
  #single
569
914
  >
570
- <NameNsDescription
571
- :value="value"
572
- :namespaced="false"
573
- :mode="mode"
574
- @update:value="$emit('input', $event)"
575
- />
576
-
915
+ <!-- Non-AppCo view -->
916
+ <div v-if="!isSuseAppCollection">
917
+ <NameNsDescription
918
+ :value="value"
919
+ :namespaced="false"
920
+ :mode="mode"
921
+ data-testid="helmop-view-name-ns-description"
922
+ @update:value="$emit('input', $event)"
923
+ />
924
+
925
+ <Tabbed
926
+ v-if="isView"
927
+ :side-tabs="true"
928
+ :use-hash="true"
929
+ >
930
+ <Tab
931
+ v-if="steps[1]"
932
+ :name="steps[1].name"
933
+ :label="steps[1].label"
934
+ :weight="4"
935
+ >
936
+ <HelmOpChartTab
937
+ :value="value"
938
+ :mode="mode"
939
+ :is-view="isView"
940
+ :source-type="sourceType"
941
+ :source-type-options="sourceTypeOptions"
942
+ :fv-get-and-report-path-rules="fvGetAndReportPathRules"
943
+ data-testid="helmop-view-chart-tab"
944
+ @update:source-type="onSourceTypeSelect"
945
+ />
946
+ </Tab>
947
+ <Tab
948
+ v-if="steps[2]"
949
+ :name="steps[2].name"
950
+ :label="steps[2].label"
951
+ :weight="3"
952
+ >
953
+ <HelmOpValuesTab
954
+ :value="value"
955
+ :mode="mode"
956
+ :real-mode="realMode"
957
+ :is-view="isView"
958
+ :chart-values="chartValues"
959
+ :chart-values-init="chartValuesInit"
960
+ :yaml-form="yamlForm"
961
+ :yaml-form-options="yamlFormOptions"
962
+ :yaml-diff-mode-options="yamlDiffModeOptions"
963
+ :is-yaml-diff="isYamlDiff"
964
+ :editor-mode="editorMode"
965
+ :diff-mode="diffMode"
966
+ :is-real-mode-edit="isRealModeEdit"
967
+ data-testid="helmop-view-values-tab"
968
+ @update:yaml-form="updateYamlForm"
969
+ @update:chart-values="updateChartValues"
970
+ @update:diff-mode="diffMode = $event"
971
+ />
972
+ </Tab>
973
+ <Tab
974
+ v-if="steps[3]"
975
+ :name="steps[3].name"
976
+ :label="steps[3].label"
977
+ :weight="2"
978
+ >
979
+ <HelmOpTargetTab
980
+ :value="value"
981
+ :mode="mode"
982
+ :real-mode="realMode"
983
+ :targets-created="targetsCreated"
984
+ data-testid="helmop-view-target-tab"
985
+ @update:targets="updateTargets"
986
+ @targets-created="targetsCreated=$event"
987
+ />
988
+ </Tab>
989
+ <Tab
990
+ v-if="steps[4]"
991
+ :name="steps[4].name"
992
+ :label="steps[4].label"
993
+ :weight="1"
994
+ >
995
+ <HelmOpAdvancedTab
996
+ :value="value"
997
+ :mode="mode"
998
+ :is-view="isView"
999
+ :source-type="sourceType"
1000
+ :is-suse-app-collection="isSuseAppCollection"
1001
+ :temp-cached-values="tempCachedValues"
1002
+ :correct-drift-enabled="correctDriftEnabled"
1003
+ :polling-interval="pollingInterval"
1004
+ :is-polling-enabled="isPollingEnabled"
1005
+ :show-polling-interval-min-value-warning="showPollingIntervalMinValueWarning"
1006
+ :enable-polling-tooltip="enablePollingTooltip"
1007
+ :is-null-or-static-version="isNullOrStaticVersion"
1008
+ :downstream-secrets-list="downstreamSecretsList"
1009
+ :downstream-config-maps-list="downstreamConfigMapsList"
1010
+ :register-before-hook="registerBeforeHook"
1011
+ data-testid="helmop-view-advanced-tab"
1012
+ @update:auth="updateAuth($event.value, $event.key)"
1013
+ @update:cached-auth="updateCachedAuthVal($event.value, $event.key)"
1014
+ @update:correct-drift="correctDriftEnabled = $event"
1015
+ @update:downstream-resources="updateDownstreamResources($event.kind, $event.list)"
1016
+ @toggle-polling="togglePolling"
1017
+ @update:polling-interval="updatePollingInterval"
1018
+ @update:validate-polling-interval="validatePollingInterval"
1019
+ />
1020
+ </Tab>
1021
+ <Tab
1022
+ name="labels"
1023
+ label-key="generic.labelsAndAnnotations"
1024
+ :weight="5"
1025
+ >
1026
+ <HelmOpMetadataTab
1027
+ :value="value"
1028
+ :mode="mode"
1029
+ :is-view="isView"
1030
+ data-testid="helmop-view-metadata-tab"
1031
+ @update:value="$emit('input', $event)"
1032
+ />
1033
+ </Tab>
1034
+ </Tabbed>
1035
+ </div>
1036
+
1037
+ <!-- AppCo view -->
577
1038
  <Tabbed
578
- v-if="isView"
1039
+ v-else-if="isSuseAppCollection && isView"
579
1040
  :side-tabs="true"
580
1041
  :use-hash="true"
1042
+ data-testid="helmop-appco-view-tabbed"
581
1043
  >
582
1044
  <Tab
583
- v-if="steps[1]"
584
- :name="steps[1].name"
585
- :label="steps[1].label"
586
- :weight="4"
587
- >
588
- <HelmOpChartTab
589
- :value="value"
590
- :mode="mode"
591
- :is-view="isView"
592
- :source-type="sourceType"
593
- :source-type-options="sourceTypeOptions"
594
- :fv-get-and-report-path-rules="fvGetAndReportPathRules"
595
- @update:source-type="onSourceTypeSelect"
596
- />
597
- </Tab>
598
- <Tab
599
- v-if="steps[2]"
600
- :name="steps[2].name"
601
- :label="steps[2].label"
602
- :weight="3"
603
- >
604
- <HelmOpValuesTab
605
- :value="value"
606
- :mode="mode"
607
- :real-mode="realMode"
608
- :is-view="isView"
609
- :chart-values="chartValues"
610
- :chart-values-init="chartValuesInit"
611
- :yaml-form="yamlForm"
612
- :yaml-form-options="yamlFormOptions"
613
- :yaml-diff-mode-options="yamlDiffModeOptions"
614
- :is-yaml-diff="isYamlDiff"
615
- :editor-mode="editorMode"
616
- :diff-mode="diffMode"
617
- :is-real-mode-edit="isRealModeEdit"
618
- @update:yaml-form="updateYamlForm"
619
- @update:chart-values="updateChartValues"
620
- @update:diff-mode="diffMode = $event"
621
- />
622
- </Tab>
623
- <Tab
624
- v-if="steps[3]"
625
- :name="steps[3].name"
626
- :label="steps[3].label"
627
- :weight="2"
1045
+ :name="appCoViewTabs[0].name"
1046
+ :label="appCoViewTabs[0].label"
1047
+ :weight="appCoViewTabs[0].weight"
1048
+ :show-header="false"
628
1049
  >
629
- <HelmOpTargetTab
630
- :value="value"
631
- :mode="mode"
632
- :real-mode="realMode"
633
- :is-view="isView"
634
- :targets-created="targetsCreated"
635
- @update:targets="updateTargets"
636
- @targets-created="targetsCreated=$event"
1050
+ <HelmOpAppCoConfigTab
1051
+ v-bind="appCoConfigProps"
1052
+ :hide-target="true"
1053
+ :hide-advanced="true"
1054
+ :hide-chart-config="false"
1055
+ data-testid="helmop-appco-view-chart-config"
1056
+ v-on="appCoConfigListeners"
637
1057
  />
638
1058
  </Tab>
1059
+
639
1060
  <Tab
640
- v-if="steps[4]"
641
- :name="steps[4].name"
642
- :label="steps[4].label"
643
- :weight="1"
1061
+ :name="appCoViewTabs[1].name"
1062
+ :label="appCoViewTabs[1].label"
1063
+ :weight="appCoViewTabs[1].weight"
1064
+ :show-header="false"
644
1065
  >
645
- <HelmOpAdvancedTab
646
- :value="value"
647
- :mode="mode"
648
- :is-view="isView"
649
- :source-type="sourceType"
650
- :temp-cached-values="tempCachedValues"
651
- :correct-drift-enabled="correctDriftEnabled"
652
- :polling-interval="pollingInterval"
653
- :is-polling-enabled="isPollingEnabled"
654
- :show-polling-interval-min-value-warning="showPollingIntervalMinValueWarning"
655
- :enable-polling-tooltip="enablePollingTooltip"
656
- :is-null-or-static-version="isNullOrStaticVersion"
657
- :downstream-secrets-list="downstreamSecretsList"
658
- :downstream-config-maps-list="downstreamConfigMapsList"
659
- :register-before-hook="registerBeforeHook"
660
- @update:auth="updateAuth($event.value, $event.key)"
661
- @update:cached-auth="updateCachedAuthVal($event.value, $event.key)"
662
- @update:correct-drift="correctDriftEnabled = $event"
663
- @update:downstream-resources="updateDownstreamResources($event.kind, $event.list)"
664
- @toggle-polling="togglePolling"
665
- @update:polling-interval="updatePollingInterval"
666
- @update:validate-polling-interval="validatePollingInterval"
1066
+ <HelmOpAppCoConfigTab
1067
+ v-bind="appCoConfigProps"
1068
+ :hide-chart-config="true"
1069
+ :hide-advanced="true"
1070
+ data-testid="helmop-appco-view-target-details"
1071
+ v-on="appCoConfigListeners"
667
1072
  />
668
1073
  </Tab>
1074
+
669
1075
  <Tab
670
- name="labels"
671
- label-key="generic.labelsAndAnnotations"
672
- :weight="5"
1076
+ :name="appCoViewTabs[2].name"
1077
+ :label="appCoViewTabs[2].label"
1078
+ :weight="appCoViewTabs[2].weight"
1079
+ @active="refreshAppCoAdvancedYaml"
673
1080
  >
674
- <HelmOpMetadataTab
675
- :value="value"
676
- :mode="mode"
677
- :is-view="isView"
678
- @update:value="$emit('input', $event)"
1081
+ <HelmOpAppCoConfigTab
1082
+ ref="appCoAdvancedRef"
1083
+ v-bind="appCoConfigProps"
1084
+ :hide-chart-config="true"
1085
+ :hide-target="true"
1086
+ data-testid="helmop-appco-view-advanced"
1087
+ v-on="appCoConfigListeners"
679
1088
  />
680
1089
  </Tab>
681
1090
  </Tabbed>
1091
+ <div
1092
+ v-else-if="isSuseAppCollection && (isEdit || isCreate)"
1093
+ data-testid="helmop-appco-edit"
1094
+ >
1095
+ <HelmOpAppCoConfigTab
1096
+ v-bind="appCoConfigProps"
1097
+ :name-rules="fvGetAndReportPathRules('metadata.name')"
1098
+ data-testid="helmop-appco-edit-config-tab"
1099
+ v-on="appCoConfigListeners"
1100
+ />
1101
+ </div>
682
1102
  </template>
683
1103
  </CruResource>
684
1104
  </template>
685
1105
 
686
1106
  <style lang="scss" scoped>
687
- .yaml-form-controls {
688
- display: flex;
689
- margin-bottom: 15px;
690
- }
691
- :deep() .yaml-editor {
692
- .root {
693
- height: auto !important;
694
- }
695
- }
696
- .resource-handling {
697
- display: flex;
698
- flex-direction: column;
699
- gap: 5px;
700
- }
701
- .polling {
702
- display: flex;
703
- flex-direction: column;
704
- gap: 5px;
705
- }
706
1107
  </style>