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

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 (301) hide show
  1. package/assets/brand/classic/metadata.json +3 -0
  2. package/assets/styles/app.scss +1 -0
  3. package/assets/styles/base/_color.scss +19 -0
  4. package/assets/styles/base/_helpers.scss +10 -0
  5. package/assets/styles/base/_variables.scss +1 -1
  6. package/assets/styles/fonts/_icons.scss +1 -32
  7. package/assets/styles/global/_layout.scss +1 -1
  8. package/assets/styles/global/_tooltip.scss +7 -4
  9. package/assets/styles/themes/_dark.scss +272 -259
  10. package/assets/styles/themes/_light.scss +551 -516
  11. package/assets/styles/themes/_modern.scss +936 -0
  12. package/assets/translations/en-us.yaml +219 -38
  13. package/assets/translations/zh-hans.yaml +0 -1
  14. package/chart/__tests__/S3.test.ts +2 -1
  15. package/chart/monitoring/grafana/index.vue +8 -2
  16. package/cloud-credential/generic.vue +18 -10
  17. package/cloud-credential/harvester.vue +1 -9
  18. package/components/ActionMenuShell.vue +3 -1
  19. package/components/AdvancedSection.vue +8 -0
  20. package/components/ChartReadme.vue +17 -7
  21. package/components/Cron/CronExpressionEditor.vue +299 -0
  22. package/components/Cron/CronExpressionEditorModal.vue +247 -0
  23. package/components/Cron/CronTooltip.vue +87 -0
  24. package/components/Cron/types.ts +13 -0
  25. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +1 -26
  26. package/components/Drawer/ResourceDetailDrawer/composables.ts +0 -23
  27. package/components/Drawer/ResourceDetailDrawer/index.vue +17 -4
  28. package/components/ForceDirectedTreeChart/composable.ts +11 -0
  29. package/components/InstallHelmCharts.vue +656 -0
  30. package/components/LazyImage.vue +60 -4
  31. package/components/LocaleSelector.vue +7 -2
  32. package/components/Markdown.vue +4 -0
  33. package/components/PromptModal.vue +1 -1
  34. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +1 -0
  35. package/components/Resource/Detail/CopyToClipboard.vue +78 -0
  36. package/components/Resource/Detail/FetchLoader/__tests__/composables.test.ts +69 -0
  37. package/components/Resource/Detail/FetchLoader/composables.ts +27 -0
  38. package/components/Resource/Detail/Masthead/composable.ts +16 -0
  39. package/components/Resource/Detail/Masthead/index.vue +37 -0
  40. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
  41. package/components/Resource/Detail/Metadata/Annotations/index.vue +1 -1
  42. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +13 -61
  43. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +33 -6
  44. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +29 -43
  45. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +25 -5
  46. package/components/Resource/Detail/Metadata/KeyValue.vue +12 -23
  47. package/components/Resource/Detail/Metadata/KeyValueRow.vue +144 -0
  48. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -0
  49. package/components/Resource/Detail/Metadata/Labels/index.vue +1 -0
  50. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +30 -32
  51. package/components/Resource/Detail/Metadata/__tests__/KeyValueRow.test.ts +108 -0
  52. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +10 -20
  53. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +12 -5
  54. package/components/Resource/Detail/Metadata/composables.ts +9 -10
  55. package/components/Resource/Detail/Metadata/index.vue +18 -2
  56. package/components/Resource/Detail/Page.vue +35 -21
  57. package/components/Resource/Detail/Preview/Content.vue +63 -0
  58. package/components/Resource/Detail/Preview/Preview.vue +128 -0
  59. package/components/Resource/Detail/Preview/__tests__/Content.spec.ts +71 -0
  60. package/components/Resource/Detail/Preview/__tests__/Preview.spec.ts +121 -0
  61. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +141 -0
  62. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +136 -0
  63. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +245 -0
  64. package/components/Resource/Detail/ResourcePopover/index.vue +226 -0
  65. package/components/Resource/Detail/SpacedRow.vue +1 -0
  66. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +8 -14
  67. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
  68. package/components/Resource/Detail/TitleBar/composables.ts +3 -6
  69. package/components/Resource/Detail/TitleBar/index.vue +11 -29
  70. package/components/Resource/Detail/ViewOptions/composable.ts +9 -0
  71. package/components/Resource/Detail/ViewOptions/index.vue +41 -0
  72. package/components/Resource/Detail/__tests__/CopyToClipboard.spec.ts +82 -0
  73. package/components/ResourceDetail/Masthead/legacy.vue +0 -19
  74. package/components/ResourceDetail/index.vue +544 -74
  75. package/components/ResourceTable.vue +24 -0
  76. package/components/SlideInPanelManager.vue +10 -3
  77. package/components/SortableTable/index.vue +11 -5
  78. package/components/SortableTable/paging.js +3 -0
  79. package/components/Tabbed/Tab.vue +43 -1
  80. package/components/Tabbed/index.vue +32 -4
  81. package/components/__tests__/Cron/CronExpressionEditor.test.ts +151 -0
  82. package/components/__tests__/Cron/CronExpressionEditorModal.test.ts +81 -0
  83. package/components/__tests__/LazyImage.spec.ts +121 -0
  84. package/components/auth/login/saml.vue +86 -0
  85. package/components/fleet/FleetStatus.vue +4 -0
  86. package/components/form/ClusterAppearance.vue +5 -0
  87. package/components/form/LabeledSelect.vue +8 -8
  88. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  89. package/components/form/ProjectMemberEditor.vue +1 -1
  90. package/components/form/ResourceLabeledSelect.vue +19 -6
  91. package/components/form/ResourceTabs/composable.ts +54 -0
  92. package/components/form/ResourceTabs/index.vue +30 -7
  93. package/components/form/SecretSelector.vue +9 -0
  94. package/components/form/Select.vue +13 -10
  95. package/components/form/__tests__/LabeledSelect.test.ts +133 -0
  96. package/components/form/__tests__/Select.test.ts +134 -0
  97. package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
  98. package/components/formatter/FleetApplicationSource.vue +25 -17
  99. package/components/nav/Favorite.vue +4 -0
  100. package/components/nav/NotificationCenter/Notification.vue +1 -27
  101. package/components/nav/WindowManager/index.vue +3 -3
  102. package/composables/useExtensionManager.ts +17 -0
  103. package/config/home-links.js +12 -0
  104. package/config/labels-annotations.js +1 -3
  105. package/config/page-actions.js +0 -1
  106. package/config/product/explorer.js +3 -1
  107. package/config/product/fleet.js +2 -7
  108. package/config/product/manager.js +0 -5
  109. package/config/query-params.js +1 -0
  110. package/config/router/navigation-guards/clusters.js +2 -1
  111. package/config/router/navigation-guards/products.js +1 -1
  112. package/core/extension-manager-impl.js +518 -0
  113. package/core/plugins.js +35 -468
  114. package/core/types.ts +8 -2
  115. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +1 -0
  116. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +11 -0
  117. package/detail/__tests__/workload.test.ts +164 -0
  118. package/detail/catalog.cattle.io.app.vue +7 -4
  119. package/detail/configmap.vue +33 -75
  120. package/detail/fleet.cattle.io.bundle.vue +1 -5
  121. package/detail/fleet.cattle.io.cluster.vue +3 -2
  122. package/detail/fleet.cattle.io.gitrepo.vue +76 -49
  123. package/detail/fleet.cattle.io.helmop.vue +78 -49
  124. package/detail/projectsecret.vue +11 -0
  125. package/detail/provisioning.cattle.io.cluster.vue +350 -324
  126. package/detail/secret.vue +49 -308
  127. package/detail/workload/index.vue +38 -21
  128. package/dialog/AddonConfigConfirmationDialog.vue +1 -1
  129. package/dialog/GenericPrompt.vue +1 -1
  130. package/dialog/ImportDialog.vue +9 -2
  131. package/dialog/InstallExtensionDialog.vue +26 -15
  132. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -1
  133. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  134. package/edit/__tests__/resources.cattle.io.restore.test.ts +106 -0
  135. package/edit/cloudcredential.vue +31 -17
  136. package/edit/constraints.gatekeeper.sh.constraint/index.vue +10 -2
  137. package/edit/fleet.cattle.io.cluster.vue +19 -0
  138. package/edit/fleet.cattle.io.gitrepo.vue +28 -22
  139. package/edit/fleet.cattle.io.helmop.vue +78 -56
  140. package/edit/logging.banzaicloud.io.output/index.vue +1 -1
  141. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
  142. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +12 -11
  143. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +11 -1
  144. package/edit/networking.k8s.io.ingress/Certificate.vue +9 -11
  145. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +8 -3
  146. package/edit/networking.k8s.io.ingress/Rule.vue +2 -5
  147. package/edit/networking.k8s.io.ingress/RulePath.vue +17 -11
  148. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +11 -10
  149. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -3
  150. package/edit/networking.k8s.io.networkpolicy/index.vue +17 -17
  151. package/edit/provisioning.cattle.io.cluster/index.vue +14 -19
  152. package/edit/provisioning.cattle.io.cluster/rke2.vue +31 -15
  153. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +9 -7
  154. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +10 -12
  155. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +39 -38
  156. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +41 -19
  157. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +16 -3
  158. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +30 -31
  159. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +9 -10
  160. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -3
  161. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +16 -9
  162. package/edit/resources.cattle.io.restore.vue +5 -8
  163. package/edit/workload/index.vue +5 -14
  164. package/list/__tests__/workload.test.ts +1 -0
  165. package/list/provisioning.cattle.io.cluster.vue +1 -69
  166. package/list/workload.vue +8 -1
  167. package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
  168. package/machine-config/components/GCEImage.vue +6 -5
  169. package/machine-config/google.vue +20 -7
  170. package/machine-config/vmwarevsphere.vue +7 -17
  171. package/mixins/__tests__/chart.test.ts +139 -1
  172. package/mixins/chart.js +58 -20
  173. package/mixins/resource-fetch-api-pagination.js +3 -4
  174. package/models/__tests__/chart.test.ts +111 -80
  175. package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  176. package/models/__tests__/namespace.test.ts +69 -0
  177. package/models/__tests__/node.test.ts +7 -63
  178. package/models/apps.statefulset.js +8 -10
  179. package/models/catalog.cattle.io.app.js +1 -1
  180. package/models/catalog.cattle.io.operation.js +1 -1
  181. package/models/chart.js +41 -21
  182. package/models/cloudcredential.js +2 -163
  183. package/models/cluster/node.js +7 -7
  184. package/models/cluster.x-k8s.io.machine.js +3 -3
  185. package/models/compliance.cattle.io.clusterscan.js +2 -2
  186. package/models/configmap.js +4 -0
  187. package/models/constraints.gatekeeper.sh.constraint.js +1 -1
  188. package/models/fleet-application.js +16 -63
  189. package/models/fleet.cattle.io.bundle.js +1 -38
  190. package/models/fleet.cattle.io.gitrepo.js +19 -1
  191. package/models/fleet.cattle.io.helmop.js +30 -22
  192. package/models/management.cattle.io.project.js +12 -0
  193. package/models/management.cattle.io.setting.js +4 -0
  194. package/models/namespace.js +30 -0
  195. package/models/persistentvolumeclaim.js +1 -1
  196. package/models/pod.js +2 -2
  197. package/models/provisioning.cattle.io.cluster.js +16 -40
  198. package/models/rke.cattle.io.etcdsnapshot.js +1 -1
  199. package/models/secret.js +4 -0
  200. package/models/storage.k8s.io.storageclass.js +2 -2
  201. package/models/workload.js +6 -3
  202. package/package.json +19 -18
  203. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +26 -10
  204. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +4 -1
  205. package/pages/c/_cluster/apps/charts/__tests__/AppChartCardFooter.spec.js +41 -0
  206. package/pages/c/_cluster/apps/charts/chart.vue +440 -183
  207. package/pages/c/_cluster/apps/charts/index.vue +1 -0
  208. package/pages/c/_cluster/apps/charts/install.vue +7 -6
  209. package/pages/c/_cluster/explorer/projectsecret.vue +3 -13
  210. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +102 -12
  211. package/pages/c/_cluster/explorer/tools/index.vue +145 -254
  212. package/pages/c/_cluster/fleet/__tests__/index.test.ts +608 -314
  213. package/pages/c/_cluster/fleet/index.vue +103 -44
  214. package/pages/c/_cluster/manager/cloudCredential/index.vue +20 -60
  215. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +12 -2
  216. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +11 -4
  217. package/pages/c/_cluster/uiplugins/__tests__/index.spec.ts +318 -0
  218. package/pages/c/_cluster/uiplugins/index.vue +256 -387
  219. package/pages/home.vue +1 -9
  220. package/plugins/dashboard-store/actions.js +42 -22
  221. package/plugins/dashboard-store/resource-class.js +80 -0
  222. package/plugins/steve/__tests__/getters.test.ts +1 -1
  223. package/plugins/steve/__tests__/subscribe.spec.ts +259 -1
  224. package/plugins/steve/getters.js +8 -2
  225. package/plugins/steve/resourceWatcher.js +10 -3
  226. package/plugins/steve/subscribe.js +192 -19
  227. package/plugins/steve/worker/web-worker.advanced.js +2 -0
  228. package/public/index.html +2 -1
  229. package/rancher-components/Card/Card.vue +1 -19
  230. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  231. package/rancher-components/Form/Radio/RadioButton.vue +1 -1
  232. package/rancher-components/Form/Radio/RadioGroup.vue +1 -1
  233. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -11
  234. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.test.ts +53 -0
  235. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +65 -0
  236. package/rancher-components/Pill/RcCounterBadge/index.ts +1 -0
  237. package/rancher-components/Pill/RcCounterBadge/types.ts +7 -0
  238. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.test.ts +15 -0
  239. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +65 -0
  240. package/rancher-components/Pill/RcStatusBadge/index.ts +2 -0
  241. package/rancher-components/Pill/RcStatusBadge/types.ts +5 -0
  242. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.test.ts +33 -0
  243. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +75 -0
  244. package/rancher-components/Pill/RcStatusIndicator/index.ts +2 -0
  245. package/rancher-components/Pill/RcStatusIndicator/types.ts +7 -0
  246. package/rancher-components/Pill/RcTag/RcTag.test.ts +64 -0
  247. package/rancher-components/Pill/RcTag/RcTag.vue +94 -0
  248. package/rancher-components/Pill/RcTag/index.ts +1 -0
  249. package/rancher-components/Pill/RcTag/types.ts +9 -0
  250. package/rancher-components/Pill/types.ts +3 -0
  251. package/rancher-components/RcButton/RcButton.vue +1 -1
  252. package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
  253. package/rancher-components/RcDropdown/RcDropdown.vue +5 -0
  254. package/rancher-components/RcDropdown/RcDropdownItem.vue +7 -1
  255. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +2 -1
  256. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +2 -1
  257. package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
  258. package/rancher-components/RcDropdown/useDropdownItem.ts +30 -1
  259. package/rancher-components/RcItemCard/RcItemCard.test.ts +20 -0
  260. package/rancher-components/RcItemCard/RcItemCard.vue +41 -6
  261. package/rancher-components/RcItemCard/RcItemCardAction.vue +12 -0
  262. package/store/__tests__/catalog.test.ts +156 -1
  263. package/store/aws.js +19 -8
  264. package/store/catalog.js +10 -5
  265. package/store/type-map.js +3 -15
  266. package/types/extension-manager.ts +26 -0
  267. package/types/resources/settings.d.ts +1 -1
  268. package/types/shell/index.d.ts +149 -44
  269. package/types/uiplugins.ts +73 -0
  270. package/utils/__tests__/back-off.test.ts +354 -0
  271. package/utils/__tests__/kontainer.test.ts +19 -0
  272. package/utils/__tests__/product.test.ts +129 -0
  273. package/utils/__tests__/resource.test.ts +87 -0
  274. package/utils/__tests__/uiplugins.test.ts +84 -0
  275. package/utils/alertmanagerconfig.js +2 -2
  276. package/utils/auth.js +3 -76
  277. package/utils/back-off.ts +176 -0
  278. package/utils/dynamic-importer.js +8 -0
  279. package/utils/kontainer.ts +3 -5
  280. package/utils/product.ts +39 -0
  281. package/utils/resource.ts +35 -0
  282. package/utils/select.js +0 -24
  283. package/utils/style.ts +3 -0
  284. package/utils/uiplugins.ts +29 -2
  285. package/utils/validators/__tests__/setting.test.js +92 -0
  286. package/utils/validators/formRules/__tests__/index.test.ts +91 -7
  287. package/utils/validators/formRules/index.ts +84 -8
  288. package/utils/validators/setting.js +17 -0
  289. package/vue.config.js +1 -1
  290. package/cloud-credential/__tests__/harvester.test.ts +0 -18
  291. package/components/Resource/Detail/Metadata/Rectangle.vue +0 -34
  292. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +0 -24
  293. package/components/ResourceDetail/Masthead/__tests__/legacy.test.ts +0 -65
  294. package/components/ResourceDetail/__tests__/index.test.ts +0 -135
  295. package/components/ResourceDetail/legacy.vue +0 -562
  296. package/components/formatter/CloudCredExpired.vue +0 -69
  297. package/pages/explorer/resource/detail/configmap.vue +0 -42
  298. package/pages/explorer/resource/detail/projectsecret.vue +0 -9
  299. package/pages/explorer/resource/detail/secret.vue +0 -63
  300. package/utils/aws.js +0 -0
  301. /package/components/{ForceDirectedTreeChart.vue → ForceDirectedTreeChart/index.vue} +0 -0
@@ -1,10 +1,11 @@
1
1
  <script>
2
2
  import { clone, set } from '@shell/utils/object';
3
+ import semver from 'semver';
3
4
  import jsyaml from 'js-yaml';
4
5
  import { saferDump } from '@shell/utils/create-yaml';
5
6
  import { mapGetters } from 'vuex';
6
7
  import { base64Encode } from '@shell/utils/crypto';
7
- import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
8
+ import { _CREATE, _EDIT } from '@shell/config/query-params';
8
9
  import { checkSchemasForFindAllHash } from '@shell/utils/auth';
9
10
  import { AUTH_TYPE, CONFIG_MAP, NORMAN, SECRET } from '@shell/config/types';
10
11
  import { CATALOG, FLEET as FLEET_LABELS } from '@shell/config/labels-annotations';
@@ -27,9 +28,10 @@ import { SECRET_TYPES } from '@shell/config/secret';
27
28
  import UnitInput from '@shell/components/form/UnitInput';
28
29
  import FleetClusterTargets from '@shell/components/fleet/FleetClusterTargets/index.vue';
29
30
  import { toSeconds } from '@shell/utils/duration';
30
- import { DEFAULT_POLLING_INTERVAL, MINIMUM_POLLING_INTERVAL } from '@shell/models/fleet-application';
31
31
  import FleetValuesFrom from '@shell/components/fleet/FleetValuesFrom.vue';
32
32
 
33
+ const MINIMUM_POLLING_INTERVAL = 15;
34
+
33
35
  const VALUES_STATE = {
34
36
  YAML: 'YAML',
35
37
  DIFF: 'DIFF'
@@ -77,17 +79,6 @@ export default {
77
79
  },
78
80
 
79
81
  data() {
80
- let pollingInterval = toSeconds(this.value.spec.pollingInterval) || this.value.spec.pollingInterval;
81
-
82
- if (!pollingInterval) {
83
- if (this.realMode === _CREATE) {
84
- pollingInterval = DEFAULT_POLLING_INTERVAL;
85
- this.value.spec.pollingInterval = this.durationSeconds(pollingInterval);
86
- } else if (this.realMode === _EDIT || this.realMode === _VIEW) {
87
- pollingInterval = MINIMUM_POLLING_INTERVAL;
88
- }
89
- }
90
-
91
82
  const correctDriftEnabled = this.value.spec?.correctDrift?.enabled || false;
92
83
 
93
84
  const chartValues = saferDump(clone(this.value.spec.helm.values));
@@ -96,7 +87,7 @@ export default {
96
87
  VALUES_STATE,
97
88
  SOURCE_TYPE,
98
89
  allWorkspaces: [],
99
- pollingInterval,
90
+ pollingInterval: toSeconds(this.value.spec.pollingInterval) || this.value.spec.pollingInterval,
100
91
  sourceTypeInit: this.value.sourceType,
101
92
  sourceType: this.value.sourceType || SOURCE_TYPE.REPO,
102
93
  helmSpecInit: clone(this.value.spec.helm),
@@ -221,9 +212,25 @@ export default {
221
212
  return EDITOR_MODES.EDIT_CODE;
222
213
  },
223
214
 
224
- showPollingIntervalWarning() {
225
- return !this.isView && this.value.isPollingEnabled && this.pollingInterval < MINIMUM_POLLING_INTERVAL;
215
+ isNullOrStaticVersion() {
216
+ return !this.value.spec.helm.version || semver.valid(this.value.spec.helm.version) !== null;
217
+ },
218
+
219
+ isPollingEnabled() {
220
+ return !this.isNullOrStaticVersion && !!this.value.spec.pollingInterval;
221
+ },
222
+
223
+ showPollingIntervalMinValueWarning() {
224
+ return !this.isView && this.isPollingEnabled && this.pollingInterval < MINIMUM_POLLING_INTERVAL;
226
225
  },
226
+
227
+ enablePollingTooltip() {
228
+ if (this.isNullOrStaticVersion) {
229
+ return this.t('fleet.helmOp.polling.pollingInterval.versionTooltip', { version: this.value.spec.helm.version || '' }, true);
230
+ }
231
+
232
+ return null;
233
+ }
227
234
  },
228
235
 
229
236
  watch: {
@@ -255,22 +262,21 @@ export default {
255
262
  this.value.spec.targets = value;
256
263
  },
257
264
 
258
- enablePolling(value) {
265
+ togglePolling(value) {
259
266
  if (value) {
260
- delete this.value.spec.disablePolling;
267
+ this.pollingInterval = this.pollingInterval ?? MINIMUM_POLLING_INTERVAL;
268
+ this.value.spec.pollingInterval = this.value.spec.pollingInterval ?? this.durationSeconds(MINIMUM_POLLING_INTERVAL);
261
269
  } else {
262
- this.value.spec.disablePolling = true;
270
+ delete this.value.spec.pollingInterval;
263
271
  }
264
272
  },
265
273
 
266
274
  updatePollingInterval(value) {
267
- if (!value) {
268
- this.pollingInterval = DEFAULT_POLLING_INTERVAL;
269
- this.value.spec.pollingInterval = this.durationSeconds(DEFAULT_POLLING_INTERVAL);
270
- } else if (value === MINIMUM_POLLING_INTERVAL) {
271
- delete this.value.spec.pollingInterval;
272
- } else {
275
+ if (value) {
273
276
  this.value.spec.pollingInterval = this.durationSeconds(value);
277
+ } else {
278
+ this.pollingInterval = MINIMUM_POLLING_INTERVAL;
279
+ this.value.spec.pollingInterval = this.durationSeconds(MINIMUM_POLLING_INTERVAL);
274
280
  }
275
281
  },
276
282
 
@@ -398,22 +404,28 @@ export default {
398
404
  case SOURCE_TYPE.REPO:
399
405
  this.fvFormRuleSets = [{
400
406
  path: 'spec.helm.repo',
401
- rules: ['required', 'urlRepository'],
407
+ rules: ['urlRepository'],
402
408
  }, {
403
409
  path: 'spec.helm.chart',
404
410
  rules: ['required'],
411
+ }, {
412
+ path: 'spec.helm.version',
413
+ rules: ['semanticVersion'],
405
414
  }];
406
415
  break;
407
416
  case SOURCE_TYPE.OCI:
408
417
  this.fvFormRuleSets = [{
409
418
  path: 'spec.helm.repo',
410
- rules: ['required', 'ociRegistry'],
419
+ rules: ['ociRegistry'],
420
+ }, {
421
+ path: 'spec.helm.version',
422
+ rules: ['semanticVersion'],
411
423
  }];
412
424
  break;
413
425
  case SOURCE_TYPE.TARBALL:
414
426
  this.fvFormRuleSets = [{
415
427
  path: 'spec.helm.chart',
416
- rules: ['required', 'urlRepository'],
428
+ rules: ['urlRepository'],
417
429
  }];
418
430
  break;
419
431
  }
@@ -535,6 +547,7 @@ export default {
535
547
  :mode="mode"
536
548
  label-key="fleet.helmOp.source.version.label"
537
549
  :placeholder="t('fleet.helmOp.source.version.placeholder', null, true)"
550
+ :rules="fvGetAndReportPathRules('spec.helm.version')"
538
551
  />
539
552
  </div>
540
553
  </div>
@@ -558,6 +571,7 @@ export default {
558
571
  :mode="mode"
559
572
  label-key="fleet.helmOp.source.version.label"
560
573
  :placeholder="t('fleet.helmOp.source.version.placeholder', null, true)"
574
+ :rules="fvGetAndReportPathRules('spec.helm.version')"
561
575
  />
562
576
  </div>
563
577
  </div>
@@ -663,6 +677,7 @@ export default {
663
677
  v-if="!isView"
664
678
  color="info"
665
679
  label-key="fleet.helmOp.add.steps.advanced.info"
680
+ data-testid="helmOp-advanced-info"
666
681
  />
667
682
 
668
683
  <h2 v-t="'fleet.helmOp.auth.title'" />
@@ -713,38 +728,45 @@ export default {
713
728
  />
714
729
  </div>
715
730
 
716
- <h2 v-t="'fleet.helmOp.polling.label'" />
717
- <div class="row polling">
718
- <div class="col span-6">
719
- <Checkbox
720
- :value="value.isPollingEnabled"
721
- type="checkbox"
722
- label-key="fleet.helmOp.polling.enable"
723
- :mode="mode"
724
- @update:value="enablePolling"
725
- />
726
- </div>
727
- <template v-if="value.isPollingEnabled">
728
- <div class="col">
729
- <Banner
730
- v-if="showPollingIntervalWarning"
731
- color="warning"
732
- label-key="fleet.helmOp.polling.pollingInterval.minimumValuewarning"
733
- />
734
- </div>
731
+ <template v-if="sourceType === SOURCE_TYPE.REPO">
732
+ <h2 v-t="'fleet.helmOp.polling.label'" />
733
+ <div class="row polling">
735
734
  <div class="col span-6">
736
- <UnitInput
737
- v-model:value="pollingInterval"
738
- min="1"
739
- :suffix="t('suffix.seconds', { count: pollingInterval })"
740
- :label="t('fleet.helmOp.polling.pollingInterval.label')"
735
+ <Checkbox
736
+ :value="isPollingEnabled"
737
+ type="checkbox"
738
+ label-key="fleet.helmOp.polling.enable"
739
+ data-testid="helmOp-enablePolling-checkbox"
740
+ :tooltip="enablePollingTooltip"
741
741
  :mode="mode"
742
- tooltip-key="fleet.helmOp.polling.pollingInterval.tooltip"
743
- @blur.capture="updatePollingInterval(pollingInterval)"
742
+ :disabled="isNullOrStaticVersion"
743
+ @update:value="togglePolling"
744
744
  />
745
745
  </div>
746
- </template>
747
- </div>
746
+ <template v-if="isPollingEnabled">
747
+ <div class="col">
748
+ <Banner
749
+ v-if="showPollingIntervalMinValueWarning"
750
+ color="warning"
751
+ label-key="fleet.helmOp.polling.pollingInterval.minimumValueWarning"
752
+ data-testid="helmOp-pollingInterval-minimumValueWarning"
753
+ />
754
+ </div>
755
+ <div class="col span-6">
756
+ <UnitInput
757
+ v-model:value="pollingInterval"
758
+ min="1"
759
+ data-testid="helmOp-pollingInterval-input"
760
+ :suffix="t('suffix.seconds', { count: pollingInterval })"
761
+ :label="t('fleet.helmOp.polling.pollingInterval.label')"
762
+ :mode="mode"
763
+ tooltip-key="fleet.helmOp.polling.pollingInterval.tooltip"
764
+ @blur.capture="updatePollingInterval(pollingInterval)"
765
+ />
766
+ </div>
767
+ </template>
768
+ </div>
769
+ </template>
748
770
  </template>
749
771
  </CruResource>
750
772
  </template>
@@ -21,7 +21,7 @@ import YamlEditor, { EDITOR_MODES } from '@shell/components/YamlEditor';
21
21
  export default {
22
22
  components: {
23
23
  Banner, CruResource, Labels, LabeledSelect, NameNsDescription, Tab, Tabbed, YamlEditor, Loading
24
- }, //
24
+ },
25
25
 
26
26
  mixins: [CreateEditView],
27
27
 
@@ -36,11 +36,11 @@ export default {
36
36
  </div>
37
37
  <div class="row">
38
38
  <div class="col span-6">
39
- <LabeledInput
40
- v-model:value="value.endpoint.url"
41
- :mode="mode"
42
- :disabled="disabled"
43
- :label="t('logging.awsElasticsearch.url')"
39
+ <LabeledInput
40
+ v-model:value="value.endpoint.url"
41
+ :mode="mode"
42
+ :disabled="disabled"
43
+ :label="t('logging.awsElasticsearch.url')"
44
44
  />
45
45
  </div>
46
46
  </div>
@@ -51,7 +51,6 @@ export default {
51
51
  </div>
52
52
  </div>
53
53
  <div class="row mb-10">
54
- {{ value.namespace }}
55
54
  <div class="col span-6">
56
55
  <SecretSelector
57
56
  v-model:value="value.endpoint.access_key_id"
@@ -34,23 +34,24 @@ export default {
34
34
 
35
35
  async fetch() {
36
36
  const inStore = this.$store.getters['currentProduct'].inStore;
37
- const alertmanagerConfigId = this.value.id;
38
-
39
- const { receiverSchema, routeSchema } = await fetchAlertManagerConfigSpecs(this.$store);
37
+ const { receiverSchema } = await fetchAlertManagerConfigSpecs(this.$store);
40
38
 
41
39
  this.receiverSchema = receiverSchema;
42
- this.routeSchema = routeSchema;
43
40
 
44
- const alertmanagerConfigResource = await this.$store.dispatch(`${ inStore }/find`, { type: MONITORING.ALERTMANAGERCONFIG, id: alertmanagerConfigId });
41
+ // The edit page is (mis)used as the detail page. When it's in create world none of the below is valid (there's no existing resource)
42
+ if (!this.isCreate) {
43
+ const alertmanagerConfigResource = await this.$store.dispatch(`${ inStore }/find`, { type: MONITORING.ALERTMANAGERCONFIG, id: this.value.id });
44
+
45
+ this.alertmanagerConfigId = this.value.id;
46
+ this.alertmanagerConfigResource = alertmanagerConfigResource;
45
47
 
46
- this.alertmanagerConfigId = alertmanagerConfigId;
47
- this.alertmanagerConfigResource = alertmanagerConfigResource;
48
- this.alertmanagerConfigDetailRoute = alertmanagerConfigResource?._detailLocation;
48
+ this.alertmanagerConfigDetailRoute = alertmanagerConfigResource._detailLocation;
49
49
 
50
- const alertmanagerConfigActions = alertmanagerConfigResource.availableActions;
51
- const receiverActions = alertmanagerConfigResource.getReceiverActions(alertmanagerConfigActions);
50
+ const alertmanagerConfigActions = alertmanagerConfigResource.availableActions;
51
+ const receiverActions = alertmanagerConfigResource.getReceiverActions(alertmanagerConfigActions);
52
52
 
53
- this.receiverActions = receiverActions;
53
+ this.receiverActions = receiverActions;
54
+ }
54
55
  },
55
56
 
56
57
  data() {
@@ -128,6 +128,16 @@ export default {
128
128
  const expectedFields = Object.keys(receiverSchema.resourceFields);
129
129
  const suffix = {};
130
130
 
131
+ // Values contains multiple receivers of two types
132
+ // 1. Known (expected, from schema) shown in their own tabs with explicity forms
133
+ // 2. unknown (not expected, missing in schema) shown as a yaml blob
134
+
135
+ // - expectedFields and suffixYaml are only used if the receiver is of type `custom`
136
+ // - expectedFields are the known types
137
+ // - suffixYaml are the unknown types
138
+ // - usages,
139
+ // - for custom, we need to know only the unknown / yaml blog. so suffixYaml is created by extracting all known (expectedFields) from value
140
+ // - on edit of custom we then combine the two again and save to value
131
141
  Object.keys(this.value).forEach((key) => {
132
142
  if (!expectedFields.includes(key)) {
133
143
  suffix[key] = this.value[key];
@@ -195,7 +205,7 @@ export default {
195
205
  return {
196
206
  duplicateName: () => {
197
207
  const receiversArray = this.alertmanagerConfigResource.spec.receivers;
198
- const receiverNamesArray = receiversArray.map((R) => R.name);
208
+ const receiverNamesArray = receiversArray?.map((R) => R.name) || [];
199
209
  const receiversSet = new Set(receiverNamesArray);
200
210
 
201
211
  if (receiversArray.length !== receiversSet.size) {
@@ -25,17 +25,10 @@ export default {
25
25
  }
26
26
  },
27
27
  data() {
28
- const defaultCert = {
29
- label: this.t('ingress.certificates.defaultCertLabel'),
30
- value: DEFAULT_CERT_VALUE,
31
- };
32
- const { hosts = [''], secretName = defaultCert.value } = this.value;
33
-
34
28
  return {
35
- defaultCert,
36
- hosts,
37
- secretName,
38
- secretVal: this.value.secretName ?? DEFAULT_CERT_VALUE,
29
+ hosts: this.value?.hosts ?? [''],
30
+ secretName: this.value?.secretName === undefined ? DEFAULT_CERT_VALUE : this.value?.secretName,
31
+ secretVal: this.value?.secretName ?? DEFAULT_CERT_VALUE,
39
32
  };
40
33
  },
41
34
  watch: {
@@ -47,7 +40,12 @@ export default {
47
40
  },
48
41
  computed: {
49
42
  certsWithDefault() {
50
- return [this.defaultCert, ...this.certs.map((c) => ({ label: c, value: c }))];
43
+ const defaultCert = {
44
+ label: this.t('ingress.certificates.defaultCertLabel'),
45
+ value: DEFAULT_CERT_VALUE,
46
+ };
47
+
48
+ return [defaultCert, ...this.certs.map((c) => ({ label: c, value: c }))];
51
49
  },
52
50
  certificateStatus() {
53
51
  const isValueAnOption = !this.secretName || this.certsWithDefault.find((cert) => this.secretName === cert.value);
@@ -34,11 +34,16 @@ export default {
34
34
  }
35
35
  },
36
36
  data() {
37
+ return {
38
+ serviceName: '',
39
+ servicePort: '',
40
+ };
41
+ },
42
+ created() {
37
43
  const backend = get(this.value.spec, this.value.defaultBackendPath);
38
- const serviceName = get(backend, this.value.serviceNamePath) || '';
39
- const servicePort = get(backend, this.value.servicePortPath) || '';
40
44
 
41
- return { serviceName, servicePort };
45
+ this.serviceName = get(backend, this.value.serviceNamePath) || '';
46
+ this.servicePort = get(backend, this.value.servicePortPath) || '';
42
47
  },
43
48
  computed: {
44
49
  isView() {
@@ -32,12 +32,9 @@ export default {
32
32
  }
33
33
  },
34
34
  data() {
35
- const { host = '', http = {} } = this.value;
36
- const { paths = [{ id: random32(1) }] } = http;
37
-
38
35
  return {
39
- host,
40
- paths,
36
+ host: this.value?.host ?? '',
37
+ paths: this.value?.http?.paths ?? [{ id: random32(1) }],
41
38
  ruleMode: this.value.asDefault ? 'asDefault' : 'setHost',
42
39
  };
43
40
  },
@@ -34,24 +34,21 @@ export default {
34
34
  type: Object,
35
35
  }
36
36
  },
37
- data() {
37
+ setup() {
38
38
  const pathTypes = [
39
39
  'Prefix',
40
40
  'Exact',
41
41
  'ImplementationSpecific'
42
42
  ];
43
43
 
44
- set(this.value, 'backend', this.value.backend || {});
45
- set(this.value, 'path', this.value.path || '');
46
- set(this.value, 'pathType', this.value.pathType || pathTypes[0]);
47
- set(this.value.backend, this.ingress.serviceNamePath, get(this.value.backend, this.ingress.serviceNamePath) || '');
48
- set(this.value.backend, this.ingress.servicePortPath, get(this.value.backend, this.ingress.servicePortPath) || '');
49
-
50
- const serviceName = get(this.value.backend, this.ingress.serviceNamePath);
51
- const servicePort = get(this.value.backend, this.ingress.servicePortPath);
52
-
44
+ return { pathTypes };
45
+ },
46
+ data() {
53
47
  return {
54
- pathTypes, serviceName, servicePort, pathType: this.value.pathType, path: this.value.path
48
+ serviceName: undefined,
49
+ servicePort: undefined,
50
+ pathType: this.value.pathType,
51
+ path: this.value.path,
55
52
  };
56
53
  },
57
54
  computed: {
@@ -77,6 +74,15 @@ export default {
77
74
  created() {
78
75
  this.queueUpdate = debounce(this.update, 500);
79
76
  this.queueUpdatePathTypeAndPath = debounce(this.updatePathTypeAndPath, 500);
77
+
78
+ set(this.value, 'backend', this.value.backend || {});
79
+ set(this.value, 'path', this.value.path || '');
80
+ set(this.value, 'pathType', this.value.pathType || this.pathTypes[0]);
81
+ set(this.value.backend, this.ingress.serviceNamePath, get(this.value.backend, this.ingress.serviceNamePath) || '');
82
+ set(this.value.backend, this.ingress.servicePortPath, get(this.value.backend, this.ingress.servicePortPath) || '');
83
+
84
+ this.serviceName = get(this.value.backend, this.ingress.serviceNamePath);
85
+ this.servicePort = get(this.value.backend, this.ingress.servicePortPath);
80
86
  },
81
87
  methods: {
82
88
  update() {
@@ -47,16 +47,6 @@ export default {
47
47
  },
48
48
  },
49
49
  data() {
50
- if (!this.value[TARGET_OPTIONS.IP_BLOCK] &&
51
- !this.value[TARGET_OPTIONS.POD_SELECTOR] &&
52
- !this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR] &&
53
- !this.value[TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR]
54
- ) {
55
- this.$nextTick(() => {
56
- this.value[TARGET_OPTIONS.IP_BLOCK] = {};
57
- });
58
- }
59
-
60
50
  return {
61
51
  portOptions: ['TCP', 'UDP'],
62
52
  matchingPods: {
@@ -74,6 +64,17 @@ export default {
74
64
  debouncedUpdateMatches: debounce(this.updateMatches, 500)
75
65
  };
76
66
  },
67
+ created() {
68
+ if (!this.value[TARGET_OPTIONS.IP_BLOCK] &&
69
+ !this.value[TARGET_OPTIONS.POD_SELECTOR] &&
70
+ !this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR] &&
71
+ !this.value[TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR]
72
+ ) {
73
+ this.$nextTick(() => {
74
+ this.value[TARGET_OPTIONS.IP_BLOCK] = {};
75
+ });
76
+ }
77
+ },
77
78
  computed: {
78
79
  /**
79
80
  * of type matchExpression aka `KubeLabelSelectorExpression[]`
@@ -32,12 +32,10 @@ export default {
32
32
  default: undefined
33
33
  }
34
34
  },
35
- data() {
35
+ created() {
36
36
  if (!this.value.spec[this.type]) {
37
37
  this.value.spec[this.type] = [];
38
38
  }
39
-
40
- return {};
41
39
  },
42
40
  methods: {
43
41
  addPolicyRule() {
@@ -47,6 +47,23 @@ export default {
47
47
  },
48
48
 
49
49
  data() {
50
+ return {
51
+ POD,
52
+ matchingPods: {
53
+ matched: 0,
54
+ matches: [],
55
+ none: true,
56
+ sample: null,
57
+ total: 0,
58
+ },
59
+ podTableHeaders: this.$store.getters['type-map/headersFor'](
60
+ this.$store.getters['cluster/schemaFor'](POD)
61
+ ),
62
+ inStore: this.$store.getters['currentProduct'].inStore,
63
+ };
64
+ },
65
+
66
+ created() {
50
67
  if ( !this.value.spec ) {
51
68
  this.value['spec'] = {
52
69
  policyTypes: [],
@@ -56,23 +73,6 @@ export default {
56
73
  }
57
74
  };
58
75
  }
59
-
60
- const matchingPods = {
61
- matched: 0,
62
- matches: [],
63
- none: true,
64
- sample: null,
65
- total: 0,
66
- };
67
-
68
- return {
69
- POD,
70
- matchingPods,
71
- podTableHeaders: this.$store.getters['type-map/headersFor'](
72
- this.$store.getters['cluster/schemaFor'](POD)
73
- ),
74
- inStore: this.$store.getters['currentProduct'].inStore,
75
- };
76
76
  },
77
77
 
78
78
  computed: {
@@ -149,25 +149,20 @@ export default {
149
149
  });
150
150
 
151
151
  // Custom Providers from extensions - initialize each with the store and the i18n service
152
- // Wrap in try ... catch, to prevent errors in an extension breaking the page
153
- try {
154
- const extensionClasses = this.$plugin.listDynamic('provisioner').map((name) => this.$plugin.getDynamic('provisioner', name));
155
-
156
- // We can't pass in this.$store as this leads to a circular-reference that causes Vue to freeze,
157
- // so pass in specific services that the provisioner extension may need
158
- this.extensions = extensionClasses.map((c) => new c({
159
- dispatch: this.$store.dispatch,
160
- getters: this.$store.getters,
161
- axios: this.$store.$axios,
162
- $plugin: this.$store.app.$plugin,
163
- t: (...args) => this.t.apply(this, args),
164
- isCreate: this.isCreate,
165
- isEdit: this.isEdit,
166
- isView: this.isView,
167
- }));
168
- } catch (e) {
169
- console.error('Error loading provisioner(s) from extensions', e); // eslint-disable-line no-console
170
- }
152
+ // We can't pass in this.$store as this leads to a circular-reference that causes Vue to freeze,
153
+ // so pass in specific services that the provisioner extension may need
154
+ const context = {
155
+ dispatch: this.$store.dispatch,
156
+ getters: this.$store.getters,
157
+ axios: this.$store.$axios,
158
+ $extension: this.$store.app.$extension,
159
+ t: (...args) => this.t.apply(this, args),
160
+ isCreate: this.isCreate,
161
+ isEdit: this.isEdit,
162
+ isView: this.isView,
163
+ };
164
+
165
+ this.extensions = this.$extension.getProviders(context);
171
166
  },
172
167
 
173
168
  data() {