@rancher/shell 3.0.0-rc.3 → 3.0.0-rc.4

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 (288) hide show
  1. package/assets/styles/base/_variables.scss +12 -4
  2. package/assets/styles/global/_layout.scss +1 -1
  3. package/assets/translations/en-us.yaml +61 -26
  4. package/assets/translations/zh-hans.yaml +6 -5
  5. package/chart/istio.vue +2 -0
  6. package/chart/monitoring/ClusterSelector.vue +2 -0
  7. package/chart/monitoring/StorageClassSelector.vue +4 -1
  8. package/chart/monitoring/index.vue +2 -0
  9. package/chart/rancher-backup/S3.vue +2 -0
  10. package/chart/rancher-backup/index.vue +2 -0
  11. package/cloud-credential/aws.vue +2 -0
  12. package/cloud-credential/azure.vue +2 -0
  13. package/cloud-credential/digitalocean.vue +2 -0
  14. package/cloud-credential/gcp.vue +2 -0
  15. package/cloud-credential/generic.vue +2 -0
  16. package/cloud-credential/harvester.vue +2 -0
  17. package/cloud-credential/linode.vue +2 -0
  18. package/cloud-credential/pnap.vue +2 -0
  19. package/cloud-credential/s3.vue +2 -0
  20. package/cloud-credential/vmwarevsphere.vue +2 -0
  21. package/components/ActionMenu.vue +4 -1
  22. package/components/AppModal.vue +4 -1
  23. package/components/ButtonDropdown.vue +3 -0
  24. package/components/ButtonGroup.vue +2 -0
  25. package/components/ButtonMultiAction.vue +41 -0
  26. package/components/Carousel.vue +3 -0
  27. package/components/CodeMirror.vue +6 -4
  28. package/components/Collapse.vue +4 -1
  29. package/components/CollapsibleCard.vue +4 -1
  30. package/components/ContainerResourceLimit.vue +2 -0
  31. package/components/CopyCode.vue +8 -4
  32. package/components/CopyToClipboardText.vue +2 -0
  33. package/components/CruResource.vue +2 -0
  34. package/components/CruResourceFooter.vue +2 -0
  35. package/components/Dialog.vue +2 -0
  36. package/components/DisableAuthProviderModal.vue +4 -1
  37. package/components/EmberPage.vue +2 -0
  38. package/components/ExplorerProjectsNamespaces.vue +11 -8
  39. package/components/GlobalRoleBindings.vue +2 -0
  40. package/components/Import.vue +2 -0
  41. package/components/InputOrDisplay.vue +23 -18
  42. package/components/Loading.vue +4 -1
  43. package/components/Markdown.vue +2 -0
  44. package/components/ModalWithCard.vue +2 -0
  45. package/components/MoveModal.vue +2 -0
  46. package/components/PodSecurityAdmission.vue +2 -0
  47. package/components/Questions/Array.vue +2 -0
  48. package/components/Questions/Boolean.vue +2 -0
  49. package/components/Questions/CloudCredential.vue +2 -0
  50. package/components/Questions/Enum.vue +2 -0
  51. package/components/Questions/Float.vue +2 -0
  52. package/components/Questions/Int.vue +2 -0
  53. package/components/Questions/QuestionMap.vue +4 -1
  54. package/components/Questions/Radio.vue +2 -0
  55. package/components/Questions/Reference.vue +2 -0
  56. package/components/Questions/String.vue +2 -0
  57. package/components/Questions/Yaml.vue +2 -0
  58. package/components/Questions/index.vue +2 -0
  59. package/components/ResourceCancelModal.vue +2 -0
  60. package/components/ResourceDetail/Masthead.vue +4 -3
  61. package/components/ResourceDetail/index.vue +17 -15
  62. package/components/ResourceTable.vue +2 -0
  63. package/components/ResourceYaml.vue +2 -0
  64. package/components/SelectIconGrid.vue +2 -0
  65. package/components/SimpleBox.vue +2 -0
  66. package/components/SortableTable/THead.vue +2 -0
  67. package/components/SortableTable/index.vue +15 -19
  68. package/components/StatusTable.vue +2 -0
  69. package/components/Tabbed/Tab.vue +2 -0
  70. package/components/Tabbed/index.vue +2 -0
  71. package/components/Wizard.vue +2 -0
  72. package/components/YamlEditor.vue +2 -0
  73. package/components/__tests__/ButtonMultiAction.test.ts +31 -0
  74. package/components/auth/RoleDetailEdit.vue +2 -0
  75. package/components/auth/SelectPrincipal.vue +2 -0
  76. package/components/auth/login/ldap.vue +2 -0
  77. package/components/form/ArrayList.vue +16 -1
  78. package/components/form/ArrayListSelect.vue +2 -0
  79. package/components/form/ChangePassword.vue +2 -0
  80. package/components/form/ColorInput.vue +2 -0
  81. package/components/form/Command.vue +2 -0
  82. package/components/form/FileImageSelector.vue +2 -0
  83. package/components/form/FileSelector.vue +2 -0
  84. package/components/form/Footer.vue +2 -0
  85. package/components/form/GitPicker.vue +1 -0
  86. package/components/form/HealthCheck.vue +5 -3
  87. package/components/form/HookOption.vue +22 -18
  88. package/components/form/InputWithSelect.vue +3 -1
  89. package/components/form/KeyValue.vue +2 -0
  90. package/components/form/LabeledSelect.vue +13 -3
  91. package/components/form/LifecycleHooks.vue +2 -0
  92. package/components/form/MatchExpressions.vue +2 -0
  93. package/components/form/Members/ClusterPermissionsEditor.vue +2 -0
  94. package/components/form/Members/MembershipEditor.vue +2 -0
  95. package/components/form/NameNsDescription.vue +4 -1
  96. package/components/form/Networking.vue +2 -0
  97. package/components/form/NodeAffinity.vue +4 -1
  98. package/components/form/Password.vue +2 -0
  99. package/components/form/PlusMinus.vue +2 -0
  100. package/components/form/PodAffinity.vue +4 -1
  101. package/components/form/Ports.vue +2 -0
  102. package/components/form/Probe.vue +8 -4
  103. package/components/form/ResourceQuota/NamespaceRow.vue +2 -0
  104. package/components/form/ResourceQuota/Project.vue +2 -0
  105. package/components/form/ResourceQuota/ProjectRow.vue +2 -0
  106. package/components/form/RuleSelector.vue +2 -0
  107. package/components/form/SecretSelector.vue +1 -0
  108. package/components/form/Security.vue +5 -2
  109. package/components/form/Select.vue +2 -1
  110. package/components/form/SelectOrCreateAuthSecret.vue +2 -0
  111. package/components/form/ServiceNameSelect.vue +2 -0
  112. package/components/form/ServicePorts.vue +2 -0
  113. package/components/form/ShellInput.vue +2 -0
  114. package/components/form/SimpleSecretSelector.vue +2 -0
  115. package/components/form/Taints.vue +2 -0
  116. package/components/form/Tolerations.vue +2 -0
  117. package/components/form/ValueFromResource.vue +2 -0
  118. package/components/form/WorkloadPorts.vue +5 -3
  119. package/components/form/__tests__/HookOption.test.ts +28 -0
  120. package/components/form/__tests__/LabeledSelect.test.ts +42 -0
  121. package/components/form/__tests__/Probe.test.ts +12 -0
  122. package/components/nav/Header.vue +17 -141
  123. package/components/nav/HeaderPageActionMenu.vue +173 -0
  124. package/components/nav/Jump.vue +2 -0
  125. package/components/nav/NamespaceFilter.vue +5 -1
  126. package/components/nav/Type.vue +28 -2
  127. package/components/nav/WindowManager/ContainerShell.vue +6 -12
  128. package/components/nav/WindowManager/index.vue +2 -0
  129. package/components/nav/__tests__/Type.test.ts +68 -24
  130. package/composables/useClickOutside.ts +81 -0
  131. package/config/product/cis.js +4 -3
  132. package/config/product/manager.js +1 -0
  133. package/config/router/routes.js +1 -1
  134. package/config/table-headers.js +0 -10
  135. package/config/uiplugins.js +186 -143
  136. package/config/version.js +10 -0
  137. package/detail/autoscaling.horizontalpodautoscaler/index.vue +2 -0
  138. package/detail/configmap.vue +2 -0
  139. package/detail/fleet.cattle.io.cluster.vue +2 -0
  140. package/detail/fleet.cattle.io.clustergroup.vue +2 -0
  141. package/detail/fleet.cattle.io.gitrepo.vue +2 -0
  142. package/detail/harvesterhci.io.management.cluster.vue +2 -0
  143. package/detail/management.cattle.io.roletemplate.vue +4 -4
  144. package/detail/management.cattle.io.user.vue +2 -0
  145. package/detail/namespace.vue +2 -0
  146. package/detail/networking.k8s.io.ingress.vue +1 -0
  147. package/detail/node.vue +2 -0
  148. package/detail/provisioning.cattle.io.cluster.vue +2 -0
  149. package/detail/secret.vue +2 -0
  150. package/detail/service.vue +2 -0
  151. package/detail/workload/index.vue +1 -1
  152. package/dialog/AddClusterMemberDialog.vue +2 -0
  153. package/dialog/AddCustomBadgeDialog.vue +3 -1
  154. package/dialog/AddProjectMemberDialog.vue +2 -0
  155. package/dialog/AddonConfigConfirmationDialog.vue +2 -0
  156. package/dialog/DeactivateDriverDialog.vue +2 -0
  157. package/dialog/DiagnosticTimingsDialog.vue +2 -0
  158. package/dialog/DrainNode.vue +2 -0
  159. package/dialog/ForceMachineRemoveDialog.vue +2 -0
  160. package/dialog/GenericPrompt.vue +2 -0
  161. package/dialog/RollbackWorkloadDialog.vue +2 -0
  162. package/dialog/RotateCertificatesDialog.vue +2 -0
  163. package/dialog/RotateEncryptionKeyDialog.vue +2 -0
  164. package/dialog/SaveAsRKETemplateDialog.vue +2 -0
  165. package/dialog/ScaleMachineDownDialog.vue +2 -0
  166. package/dialog/ScalePoolDownDialog.vue +2 -0
  167. package/dialog/SloDialog.vue +2 -0
  168. package/edit/auth/ldap/config.vue +2 -0
  169. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +3 -3
  170. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -2
  171. package/edit/catalog.cattle.io.clusterrepo.vue +2 -0
  172. package/edit/cis.cattle.io.clusterscan.vue +38 -18
  173. package/edit/cloudcredential.vue +2 -0
  174. package/edit/constraints.gatekeeper.sh.constraint/MatchKinds.vue +2 -0
  175. package/edit/constraints.gatekeeper.sh.constraint/NamespaceList.vue +2 -0
  176. package/edit/constraints.gatekeeper.sh.constraint/Scope.vue +2 -0
  177. package/edit/constraints.gatekeeper.sh.constraint/index.vue +2 -0
  178. package/edit/fleet.cattle.io.cluster.vue +2 -0
  179. package/edit/fleet.cattle.io.clustergroup.vue +4 -1
  180. package/edit/fleet.cattle.io.gitrepo.vue +2 -0
  181. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +2 -0
  182. package/edit/logging-flow/Match.vue +2 -0
  183. package/edit/logging-flow/index.vue +10 -8
  184. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +1 -1
  185. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +1 -1
  186. package/edit/logging.banzaicloud.io.output/providers/redis.vue +3 -3
  187. package/edit/management.cattle.io.fleetworkspace.vue +4 -1
  188. package/edit/management.cattle.io.project.vue +2 -0
  189. package/edit/management.cattle.io.roletemplate.vue +1 -1
  190. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -0
  191. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -0
  192. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -0
  193. package/edit/namespace.vue +1 -0
  194. package/edit/networking.k8s.io.ingress/Certificate.vue +2 -0
  195. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -1
  196. package/edit/networking.k8s.io.ingress/Rule.vue +1 -0
  197. package/edit/networking.k8s.io.ingress/RulePath.vue +20 -23
  198. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  199. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +1 -1
  200. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  201. package/edit/node.vue +2 -0
  202. package/edit/persistentvolumeclaim.vue +1 -0
  203. package/edit/policy.poddisruptionbudget.vue +3 -1
  204. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +2 -0
  205. package/edit/provisioning.cattle.io.cluster/Labels.vue +2 -0
  206. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +2 -0
  207. package/edit/provisioning.cattle.io.cluster/import.vue +2 -0
  208. package/edit/provisioning.cattle.io.cluster/index.vue +2 -2
  209. package/edit/provisioning.cattle.io.cluster/rke2.vue +38 -13
  210. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +49 -0
  211. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +32 -65
  212. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +2 -0
  213. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +2 -0
  214. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +2 -0
  215. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +2 -0
  216. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -0
  217. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +2 -0
  218. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -0
  219. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -0
  220. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +2 -0
  221. package/edit/resources.cattle.io.backup.vue +2 -2
  222. package/edit/secret/index.vue +2 -0
  223. package/edit/service.vue +2 -1
  224. package/edit/ui.cattle.io.navlink.vue +1 -0
  225. package/edit/workload/Job.vue +3 -2
  226. package/edit/workload/Upgrading.vue +1 -0
  227. package/edit/workload/index.vue +18 -7
  228. package/edit/workload/storage/ContainerMountPaths.vue +37 -97
  229. package/edit/workload/storage/awsElasticBlockStore.vue +1 -1
  230. package/edit/workload/storage/azureDisk.vue +1 -1
  231. package/edit/workload/storage/csi/driver.longhorn.io.vue +2 -0
  232. package/edit/workload/storage/ephemeralVolume/index.vue +2 -0
  233. package/edit/workload/storage/gcePersistentDisk.vue +1 -1
  234. package/edit/workload/storage/index.vue +38 -22
  235. package/edit/workload/storage/persistentVolumeClaim/index.vue +2 -0
  236. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +1 -0
  237. package/edit/workload/storage/vsphereVolume.vue +1 -1
  238. package/initialize/install-components.js +0 -12
  239. package/initialize/install-plugins.js +4 -5
  240. package/machine-config/azure.vue +2 -0
  241. package/machine-config/generic.vue +2 -0
  242. package/machine-config/vmwarevsphere.vue +2 -0
  243. package/mixins/resource-manager.js +1 -1
  244. package/models/cis.cattle.io.clusterscan.js +17 -16
  245. package/models/cis.cattle.io.clusterscanprofile.js +17 -0
  246. package/models/management.cattle.io.user.js +3 -3
  247. package/models/provisioning.cattle.io.cluster.js +2 -1
  248. package/models/steve-schema.ts +1 -1
  249. package/models/workload.js +2 -1
  250. package/package.json +4 -6
  251. package/pages/c/_cluster/apps/charts/chart.vue +3 -1
  252. package/pages/c/_cluster/apps/charts/install.vue +5 -56
  253. package/pages/c/_cluster/fleet/index.vue +0 -1
  254. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +1 -0
  255. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +2 -0
  256. package/pages/c/_cluster/settings/performance.vue +2 -2
  257. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +11 -16
  258. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -0
  259. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +2 -0
  260. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +2 -0
  261. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +6 -3
  262. package/pages/c/_cluster/uiplugins/InstallDialog.vue +2 -0
  263. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -17
  264. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  265. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +3 -6
  266. package/pages/c/_cluster/uiplugins/index.vue +93 -92
  267. package/pkg/vue.config.js +2 -0
  268. package/plugins/plugin.js +27 -19
  269. package/plugins/version.js +3 -13
  270. package/promptRemove/pod.vue +2 -0
  271. package/rancher-components/Form/LabeledInput/LabeledInput.vue +14 -8
  272. package/rancher-components/Form/Radio/RadioButton.vue +0 -1
  273. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +17 -9
  274. package/rancher-components/StringList/StringList.vue +6 -15
  275. package/scripts/extension/bundle +1 -1
  276. package/scripts/extension/publish +174 -99
  277. package/store/catalog.js +0 -26
  278. package/store/growl.js +8 -5
  279. package/utils/cluster.js +9 -0
  280. package/utils/versions.ts +39 -0
  281. package/vue.config.js +5 -0
  282. package/components/form/PodSecurity.vue +0 -168
  283. package/components/formatter/Weight.vue +0 -147
  284. package/components/nuxt/nuxt-build-indicator.vue +0 -170
  285. package/components/nuxt/nuxt-child.js +0 -52
  286. package/components/nuxt/nuxt-error.vue +0 -128
  287. package/components/nuxt/nuxt-link.client.js +0 -17
  288. package/components/nuxt/nuxt-loading.vue +0 -165
@@ -6,6 +6,7 @@ import { RadioGroup } from '@components/Form/Radio';
6
6
  import { mapGetters } from 'vuex';
7
7
 
8
8
  export default {
9
+ emits: ['update:value'],
9
10
  components: {
10
11
  UnitInput, LabeledInput, RadioGroup
11
12
  },
@@ -213,7 +214,7 @@ export default {
213
214
  class="col span-6"
214
215
  >
215
216
  <LabeledInput
216
- v-model.number="successfulJobsHistoryLimit"
217
+ v-model:value.number="successfulJobsHistoryLimit"
217
218
  :mode="mode"
218
219
  label-key="workload.job.successfulJobsHistoryLimit.label"
219
220
  tooltip-key="workload.job.successfulJobsHistoryLimit.tip"
@@ -225,7 +226,7 @@ export default {
225
226
  class="col span-6"
226
227
  >
227
228
  <LabeledInput
228
- v-model.number="failedJobsHistoryLimit"
229
+ v-model:value.number="failedJobsHistoryLimit"
229
230
  :mode="mode"
230
231
  label-key="workload.job.failedJobsHistoryLimit.label"
231
232
  tooltip-key="workload.job.failedJobsHistoryLimit.tip"
@@ -8,6 +8,7 @@ import { mapGetters } from 'vuex';
8
8
  import InputWithSelect from '@shell/components/form/InputWithSelect';
9
9
 
10
10
  export default {
11
+ emits: ['update:value'],
11
12
  components: {
12
13
  RadioGroup, UnitInput, InputWithSelect
13
14
  },
@@ -6,6 +6,7 @@ import { mapGetters } from 'vuex';
6
6
 
7
7
  export default {
8
8
  name: 'Workload',
9
+ emits: ['input'],
9
10
  mixins: [CreateEditView, FormValidation, WorkLoadMixin], // The order here is important since WorkLoadMixin contains some FormValidation configuration
10
11
  props: {
11
12
  value: {
@@ -133,7 +134,7 @@ export default {
133
134
  class="col span-3"
134
135
  >
135
136
  <LabeledInput
136
- v-model.number="spec.replicas"
137
+ v-model:value.number="spec.replicas"
137
138
  type="number"
138
139
  min="0"
139
140
  required
@@ -162,6 +163,7 @@ export default {
162
163
  :show-tabs-add-remove="true"
163
164
  :default-tab="defaultTab"
164
165
  :flat="true"
166
+ data-testid="workload-horizontal-tabs"
165
167
  @changed="changed"
166
168
  >
167
169
  <Tab
@@ -175,6 +177,7 @@ export default {
175
177
  <Tabbed
176
178
  :side-tabs="true"
177
179
  :weight="99"
180
+ :data-testid="`workload-container-tabs-${i}`"
178
181
  >
179
182
  <Tab
180
183
  :label="t('workload.container.titles.general')"
@@ -346,13 +349,13 @@ export default {
346
349
  :weight="tabWeightMap['storage']"
347
350
  >
348
351
  <ContainerMountPaths
349
- v-model:value="podTemplateSpec"
352
+ v-model:container="allContainers[i]"
353
+ :value="podTemplateSpec"
350
354
  :namespace="value.metadata.namespace"
351
355
  :register-before-hook="registerBeforeHook"
352
356
  :mode="mode"
353
357
  :secrets="namespacedSecrets"
354
358
  :config-maps="namespacedConfigMaps"
355
- :container="allContainers[i]"
356
359
  :save-pvc-hook-name="savePvcHookName"
357
360
  @removePvcForm="clearPvcFormState"
358
361
  />
@@ -365,7 +368,10 @@ export default {
365
368
  :name="nameDisplayFor(type)"
366
369
  :weight="99"
367
370
  >
368
- <Tabbed :side-tabs="true">
371
+ <Tabbed
372
+ data-testid="workload-general-tabs"
373
+ :side-tabs="true"
374
+ >
369
375
  <Tab
370
376
  name="labels"
371
377
  label-key="generic.labelsAndAnnotations"
@@ -403,13 +409,18 @@ export default {
403
409
  :name="'pod'"
404
410
  :weight="98"
405
411
  >
406
- <Tabbed :side-tabs="true">
412
+ <Tabbed
413
+ data-testid="workload-pod-tabs"
414
+ :side-tabs="true"
415
+ >
407
416
  <Tab
408
417
  :label="t('workload.storage.title')"
409
418
  name="storage"
410
419
  :weight="tabWeightMap['storage']"
420
+ @active="$refs.storage.refresh()"
411
421
  >
412
422
  <Storage
423
+ ref="storage"
413
424
  v-model:value="podTemplateSpec"
414
425
  :namespace="value.metadata.namespace"
415
426
  :register-before-hook="registerBeforeHook"
@@ -448,7 +459,7 @@ export default {
448
459
  <div class="row">
449
460
  <div class="col span-6">
450
461
  <LabeledInput
451
- v-model.number="podTemplateSpec.priority"
462
+ v-model:value.number="podTemplateSpec.priority"
452
463
  :mode="mode"
453
464
  :label="t('workload.scheduling.priority.priority')"
454
465
  />
@@ -517,7 +528,7 @@ export default {
517
528
  <div class="row">
518
529
  <div class="col span-6">
519
530
  <LabeledInput
520
- v-model.number="podFsGroup"
531
+ v-model:value.number="podFsGroup"
521
532
  type="number"
522
533
  :mode="mode"
523
534
  :label="t('workload.container.security.fsGroup')"
@@ -1,14 +1,16 @@
1
1
  <script>
2
- import { clone } from '@shell/utils/object';
2
+ import { clone, set } from '@shell/utils/object';
3
3
  import { _VIEW } from '@shell/config/query-params';
4
- import { randomStr } from '@shell/utils/string';
5
4
 
6
5
  import Mount from '@shell/edit/workload/storage/Mount';
7
6
  import ButtonDropdown from '@shell/components/ButtonDropdown';
8
7
  import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
9
8
 
10
9
  export default {
11
- name: 'ContainerMountPaths',
10
+ name: 'ContainerMountPaths',
11
+
12
+ emits: ['update:container'],
13
+
12
14
  components: {
13
15
  ArrayListGrouped, ButtonDropdown, Mount
14
16
  },
@@ -36,13 +38,10 @@ export default {
36
38
  },
37
39
 
38
40
  data() {
41
+ // set volumeMount field
39
42
  this.initializeStorage();
40
43
 
41
- return {
42
- containerVolumes: [],
43
- storageVolumes: this.getStorageVolumes(),
44
- selectedContainerVolumes: this.getSelectedContainerVolumes()
45
- };
44
+ return { selectedContainerVolumes: this.getSelectedContainerVolumes() };
46
45
  },
47
46
 
48
47
  computed: {
@@ -51,9 +50,9 @@ export default {
51
50
  },
52
51
 
53
52
  availableVolumeOptions() {
54
- const containerVolumes = this.container.volumeMounts.map((item) => item.name);
53
+ const containerVolumes = (this.container?.volumeMounts || []).map((item) => item.name);
55
54
 
56
- return this.value.volumes.filter((vol) => !containerVolumes.includes(vol.name)).map((item) => {
55
+ return (this.value?.volumes || []).filter((vol) => !containerVolumes.includes(vol.name)).map((item) => {
57
56
  return {
58
57
  label: `${ item.name } (${ this.headerFor(item) })`,
59
58
  action: this.selectVolume,
@@ -64,27 +63,13 @@ export default {
64
63
  },
65
64
 
66
65
  watch: {
67
- value(neu, old) {
68
- this.selectedVolumes = this.getSelectedContainerVolumes();
69
- },
70
- storageVolumes(neu, old) {
71
- // removeObjects(this.value.volumes, old);
72
- // addObjects(this.value.volumes, neu);
73
- const names = neu.reduce((all, each) => {
74
- all.push(each.name);
75
-
76
- return all;
77
- }, []);
66
+ selectedContainerVolumes: {
67
+ deep: true,
68
+ handler(neu, old) {
69
+ const names = neu.map((item) => item.name);
78
70
 
79
- this.container.volumeMounts = this.container.volumeMounts.filter((mount) => names.includes(mount.name));
80
- },
81
-
82
- selectedContainerVolumes(neu, old) {
83
- // removeObjects(this.value.volumes, old);
84
- // addObjects(this.value.volumes, neu);
85
- const names = neu.map((item) => item.name);
86
-
87
- this.container.volumeMounts = this.container.volumeMounts.filter((mount) => names.includes(mount.name));
71
+ this.container.volumeMounts = this.container.volumeMounts.filter((mount) => names.includes(mount.name));
72
+ }
88
73
  }
89
74
 
90
75
  },
@@ -95,32 +80,18 @@ export default {
95
80
  */
96
81
  initializeStorage() {
97
82
  if (!this.container.volumeMounts) {
98
- this.container['volumeMounts'] = [];
99
- }
100
- if (!this.value.volumes) {
101
- this.value['volumes'] = [];
83
+ set(this.container, 'volumeMounts', []);
84
+ this.$emit('update:container', this.container);
102
85
  }
103
86
  },
104
87
 
105
- /**
106
- * Get existing paired storage volumes
107
- */
108
- getStorageVolumes() {
109
- // Extract volume mounts to map storage volumes
110
- const { volumeMounts = [] } = this.container;
111
- const names = volumeMounts.map(({ name }) => name);
112
-
113
- // Extract storage volumes to allow mutation, if matches mount map
114
- return clone(this.value.volumes.filter((volume) => names.includes(volume.name)));
115
- },
116
-
117
88
  getSelectedContainerVolumes() {
118
89
  // Extract volume mounts to map storage volumes
119
90
  const { volumeMounts = [] } = this.container;
120
91
  const names = volumeMounts.map(({ name }) => name);
121
92
 
122
93
  // Extract storage volumes to allow mutation, if matches mount map
123
- return clone(this.value.volumes.filter((volume) => names.includes(volume.name)));
94
+ return clone((this.value?.volumes || []).filter((volume) => names.includes(volume.name)));
124
95
  },
125
96
 
126
97
  /**
@@ -133,39 +104,14 @@ export default {
133
104
  },
134
105
 
135
106
  selectVolume(event) {
136
- const selectedVolume = this.value.volumes.find((vol) => vol.name === event.value);
107
+ const selectedVolume = (this.value?.volumes || []).find((vol) => vol.name === event.value);
137
108
 
138
109
  this.selectedContainerVolumes.push(selectedVolume);
139
110
 
140
111
  const { name } = selectedVolume;
141
112
 
142
113
  this.container.volumeMounts.push(name);
143
- },
144
-
145
- addVolume(type) {
146
- const name = `vol-${ randomStr(5).toLowerCase() }`;
147
-
148
- if (type === 'createPVC') {
149
- this.storageVolumes.push({
150
- _type: 'createPVC',
151
- persistentVolumeClaim: {},
152
- name,
153
- });
154
- } else if (type === 'csi') {
155
- this.storageVolumes.push({
156
- _type: type,
157
- csi: { volumeAttributes: {} },
158
- name,
159
- });
160
- } else {
161
- this.storageVolumes.push({
162
- _type: type,
163
- [type]: {},
164
- name,
165
- });
166
- }
167
-
168
- this.container.volumeMounts.push({ name });
114
+ this.$emit('update:container', this.container);
169
115
  },
170
116
 
171
117
  headerFor(value) {
@@ -182,13 +128,6 @@ export default {
182
128
  }
183
129
  },
184
130
 
185
- openPopover() {
186
- const button = this.$refs.buttonDropdown;
187
-
188
- try {
189
- button.togglePopover();
190
- } catch (e) {}
191
- },
192
131
  },
193
132
  };
194
133
  </script>
@@ -197,8 +136,11 @@ export default {
197
136
  <div>
198
137
  <!-- Storage Volumes -->
199
138
  <ArrayListGrouped
139
+ :key="selectedContainerVolumes.length"
200
140
  v-model:value="selectedContainerVolumes"
141
+ :add-allowed="false"
201
142
  :mode="mode"
143
+ data-testid="container-storage-array-list"
202
144
  @remove="removeVolume"
203
145
  >
204
146
  <!-- Custom/default storage volume form -->
@@ -208,24 +150,22 @@ export default {
208
150
  :container="container"
209
151
  :name="props.row.value.name"
210
152
  :mode="mode"
153
+ :data-testid="`container-storage-mount-${props.i}`"
211
154
  />
212
155
  </template>
213
-
214
- <!-- Add Storage Volume -->
215
- <template #add>
216
- <ButtonDropdown
217
- v-if="!isView"
218
- id="add-volume"
219
- :button-label="t('workload.storage.selectVolume')"
220
- :dropdown-options="availableVolumeOptions"
221
- size="sm"
222
- @click-action="e=>selectVolume(e)"
223
- >
224
- <template #no-options>
225
- {{ t('workload.storage.noVolumes') }}
226
- </template>
227
- </ButtonDropdown>
228
- </template>
229
156
  </ArrayListGrouped>
157
+ <ButtonDropdown
158
+ v-if="!isView"
159
+ id="add-volume"
160
+ :button-label="t('workload.storage.selectVolume')"
161
+ :dropdown-options="availableVolumeOptions"
162
+ size="sm"
163
+ data-testid="container-storage-add-button"
164
+ @click-action="e=>selectVolume(e)"
165
+ >
166
+ <template #no-options>
167
+ {{ t('workload.storage.noVolumes') }}
168
+ </template>
169
+ </ButtonDropdown>
230
170
  </div>
231
171
  </template>
@@ -54,7 +54,7 @@ export default {
54
54
  </div>
55
55
  <div class="col span-6">
56
56
  <LabeledInput
57
- v-model.number="value.awsElasticBlockStore.partition"
57
+ v-model:value.number="value.awsElasticBlockStore.partition"
58
58
  :mode="mode"
59
59
  :label="t('workload.storage.csi.partition')"
60
60
  />
@@ -62,7 +62,7 @@ export default {
62
62
  </div>
63
63
  <div class="col span-6">
64
64
  <LabeledInput
65
- v-model.number="value.azureDisk.diskURI"
65
+ v-model:value.number="value.azureDisk.diskURI"
66
66
  :mode="mode"
67
67
  :required="true"
68
68
  :label="t('workload.storage.csi.diskURI')"
@@ -2,6 +2,8 @@
2
2
  import KeyValue from '@shell/components/form/KeyValue';
3
3
 
4
4
  export default {
5
+ emits: ['update:value'],
6
+
5
7
  components: { KeyValue },
6
8
 
7
9
  props: {
@@ -6,6 +6,8 @@ import Mount from '@shell/edit/workload/storage/Mount';
6
6
  import { mapGetters } from 'vuex';
7
7
 
8
8
  export default {
9
+ emits: ['remove'],
10
+
9
11
  components: {
10
12
  LabeledSelect, LabeledInput, Checkbox, Mount
11
13
  },
@@ -54,7 +54,7 @@ export default {
54
54
  </div>
55
55
  <div class="col span-6">
56
56
  <LabeledInput
57
- v-model.number="value.gcePersistentDisk.partition"
57
+ v-model:value.number="value.gcePersistentDisk.partition"
58
58
  :mode="mode"
59
59
  :label="t('workload.storage.csi.partition')"
60
60
  />
@@ -5,14 +5,21 @@ import { _VIEW } from '@shell/config/query-params';
5
5
  import CodeMirror from '@shell/components/CodeMirror';
6
6
  import jsyaml from 'js-yaml';
7
7
  import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
8
+ import YamlEditor, { EDITOR_MODES } from '@shell/components/YamlEditor.vue';
8
9
  import { randomStr } from '@shell/utils/string';
9
10
  import { uniq } from '@shell/utils/array';
10
11
 
11
12
  export default {
12
13
  name: 'Storage',
13
14
 
15
+ emits: ['removePvcForm'],
16
+
14
17
  components: {
15
- ArrayListGrouped, ButtonDropdown, Mount, CodeMirror
18
+ ArrayListGrouped,
19
+ ButtonDropdown,
20
+ Mount,
21
+ CodeMirror,
22
+ YamlEditor
16
23
  },
17
24
 
18
25
  props: {
@@ -108,21 +115,21 @@ export default {
108
115
  pvcNames() {
109
116
  return this.namespacedPvcs.map((pvc) => pvc.metadata.name);
110
117
  },
111
- },
112
-
113
- // watch: {
114
- // storageVolumes(neu, old) {
115
- // removeObjects(this.value.volumes, old);
116
- // addObjects(this.value.volumes, neu);
117
- // const names = neu.reduce((all, each) => {
118
- // all.push(each.name);
119
118
 
120
- // return all;
121
- // }, []);
119
+ yamlEditorMode() {
120
+ return this.isView ? EDITOR_MODES.VIEW_CODE : EDITOR_MODES.EDIT_CODE;
121
+ }
122
+ },
122
123
 
123
- // this.container.volumeMounts = this.container.volumeMounts.filter(mount => names.includes(mount.name));
124
- // }
125
- // },
124
+ // need to refresh codemirror when the tab is opened and hash change === tab change
125
+ watch: {
126
+ '$route.hash': {
127
+ deep: true,
128
+ handler() {
129
+ this.refresh();
130
+ }
131
+ }
132
+ },
126
133
 
127
134
  methods: {
128
135
  /**
@@ -221,14 +228,18 @@ export default {
221
228
 
222
229
  // codemirror needs to refresh if it is in a tab that wasn't visible on page load
223
230
  refresh() {
224
- if (this.$refs.cm) {
225
- this.$refs.cm.forEach((component) => component.refresh());
231
+ if (this.$refs) {
232
+ // if a constant ref is assigned to the codemirror component in the template below, only the last instance of that codemirror component gets the ref
233
+ const cmRefs = Object.keys(this.$refs).filter((ref) => ref.startsWith('cm-'));
234
+
235
+ cmRefs.forEach((r) => this.$refs[r].refresh());
226
236
  }
227
237
  },
228
238
 
229
239
  removePvcForm(hookName) {
230
240
  this.$emit('removePvcForm', hookName);
231
- }
241
+ },
242
+
232
243
  },
233
244
  };
234
245
  </script>
@@ -258,13 +269,18 @@ export default {
258
269
  :register-before-hook="registerBeforeHook"
259
270
  :save-pvc-hook-name="savePvcHookName"
260
271
  :loading="loading"
272
+ :data-testid="`volume-component-${props.i}`"
261
273
  @removePvcForm="removePvcForm"
262
274
  />
263
- <div v-else-if="isView">
264
- <CodeMirror
265
- ref="cm"
266
- :value="yamlDisplay(props.row.value)"
267
- :options="{ readOnly: true, cursorBlinkRate: -1 }"
275
+ <div
276
+ v-else
277
+ >
278
+ <YamlEditor
279
+ :ref="`cm-${props.i}`"
280
+ v-model:value="props.row.value"
281
+ :as-object="true"
282
+ :data-testid="`volume-component-${props.i}`"
283
+ :editor-mode="yamlEditorMode"
268
284
  />
269
285
  </div>
270
286
  </div>
@@ -7,6 +7,8 @@ import PersistentVolumeClaim from '@shell/edit/workload/storage/persistentVolume
7
7
  import { PVC } from '@shell/config/types';
8
8
 
9
9
  export default {
10
+ emits: ['removePvcForm'],
11
+
10
12
  components: {
11
13
  LabeledInput,
12
14
  LabeledSelect,
@@ -11,6 +11,7 @@ import { allHash } from '@shell/utils/promise';
11
11
  import { get } from '@shell/utils/object';
12
12
 
13
13
  export default {
14
+ emits: ['createUniqueId', 'removePvcForm', 'update:value'],
14
15
 
15
16
  components: {
16
17
  LabeledSelect, UnitInput, RadioGroup, Checkbox, LabeledInput
@@ -46,7 +46,7 @@ export default {
46
46
  </div>
47
47
  <div class="col span-6">
48
48
  <LabeledInput
49
- v-model.number="value.vsphereVolume.storagePolicyName"
49
+ v-model:value.number="value.vsphereVolume.storagePolicyName"
50
50
  :mode="mode"
51
51
  :label="t('workload.storage.csi.storagePolicyName')"
52
52
  />
@@ -1,23 +1,11 @@
1
1
 
2
- import NuxtChild from '@shell/components/nuxt/nuxt-child.js';
3
- import { nuxtLinkAlias } from '@shell/components/nuxt/nuxt-link.client.js'; // should be included after ./index.js
4
2
  import vSelect from 'vue-select';
5
3
 
6
4
  /**
7
5
  * Add components to the Vue instance
8
6
  * @param {*} vueApp Vue instance
9
- * TODO: #11070 - Remove Nuxt residuals
10
7
  */
11
8
  export const installComponents = (vueApp) => {
12
- // Component: <NuxtLink>
13
- // TODO: #9541 Remove for Vue 3 migration
14
- vueApp.component('NuxtLink', nuxtLinkAlias('NuxtLink'));
15
- vueApp.component('NLink', nuxtLinkAlias('NLink'));
16
-
17
- // Component: <NuxtChild>
18
- vueApp.component(NuxtChild.name, NuxtChild);
19
- vueApp.component('NChild', NuxtChild);
20
-
21
9
  // Vendor components
22
10
  vueApp.component('v-select', vSelect);
23
11
  };
@@ -1,8 +1,8 @@
1
1
  import PortalVue from 'portal-vue';
2
- import VueResize from 'vue-resize';
2
+ import Vue3Resize from 'vue3-resize';
3
3
  import FloatingVue from 'floating-vue';
4
4
  import vSelect from 'vue-select';
5
- import 'vue-resize/dist/vue-resize.css';
5
+ import 'vue3-resize/dist/vue3-resize.css';
6
6
 
7
7
  // import '@shell/plugins/extend-router';
8
8
  import '@shell/plugins/formatters';
@@ -25,7 +25,6 @@ import plugins from '@shell/core/plugins.js';
25
25
  import pluginsLoader from '@shell/core/plugins-loader.js';
26
26
  import replaceAll from '@shell/plugins/replaceall';
27
27
  import steveCreateWorker from '@shell/plugins/steve-create-worker';
28
- import version from '@shell/plugins/version';
29
28
  import emberCookie from '@shell/plugins/ember-cookie';
30
29
  import ShortKey from '@shell/plugins/shortkey';
31
30
 
@@ -35,7 +34,7 @@ import { floatingVueOptions } from '@shell/plugins/floating-vue';
35
34
  export async function installPlugins(vueApp) {
36
35
  vueApp.use(globalFormatters);
37
36
  vueApp.use(PortalVue);
38
- vueApp.use(VueResize);
37
+ vueApp.use(Vue3Resize);
39
38
  vueApp.use(FloatingVue, floatingVueOptions);
40
39
  vueApp.use(ShortKey, { prevent: ['input', 'textarea', 'select'] });
41
40
  vueApp.use(InstallCodeMirror);
@@ -43,7 +42,7 @@ export async function installPlugins(vueApp) {
43
42
  }
44
43
 
45
44
  export async function installInjectedPlugins(app, vueApp) {
46
- const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, backButton, plugin, version, steveCreateWorker, emberCookie];
45
+ const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, backButton, plugin, steveCreateWorker, emberCookie];
47
46
 
48
47
  const installations = pluginDefinitions.map(async(pluginDefinition) => {
49
48
  if (typeof pluginDefinition === 'function') {
@@ -96,6 +96,8 @@ const storageTypes = [
96
96
  ];
97
97
 
98
98
  export default {
99
+ emits: ['expandAdvanced', 'error'],
100
+
99
101
  components: {
100
102
  ArrayList,
101
103
  Banner,
@@ -6,6 +6,8 @@ import { exceptionToErrorsArray, stringify } from '@shell/utils/error';
6
6
  import Questions from '@shell/components/Questions';
7
7
 
8
8
  export default {
9
+ emits: ['input'],
10
+
9
11
  components: {
10
12
  Loading, Banner, Questions
11
13
  },
@@ -137,6 +137,8 @@ const errorActions = Object.freeze({
137
137
  });
138
138
 
139
139
  export default {
140
+ emits: ['error'],
141
+
140
142
  components: {
141
143
  ArrayListSelect, Card, KeyValue, Loading, LabeledInput, LabeledSelect, Banner, UnitInput, RadioGroup, YamlEditor
142
144
  },
@@ -55,7 +55,7 @@ export default {
55
55
  const type = types[i];
56
56
  const status = hash[type].status;
57
57
  // if it's namespaced, we get the data on 'items' prop, for non-namespaced it's 'data' prop...
58
- const requestData = hash[type].value.items || hash[type].value.data || hash[type].value;
58
+ const requestData = hash[type]?.value?.items || hash[type]?.value?.data || hash[type]?.value;
59
59
 
60
60
  if (status === 'fulfilled' && resourceData.data[type] && resourceData.data[type].applyTo?.length) {
61
61
  for (let y = 0; y < resourceData.data[type].applyTo.length; y++) {