@rancher/shell 0.3.14 → 0.3.16

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 (400) hide show
  1. package/assets/images/providers/nutanix.svg +1 -0
  2. package/assets/translations/en-us.yaml +84 -3
  3. package/assets/translations/zh-hans.yaml +68 -26
  4. package/chart/gatekeeper.vue +2 -2
  5. package/chart/monitoring/alerting/index.vue +3 -3
  6. package/chart/monitoring/index.vue +2 -2
  7. package/chart/monitoring/prometheus/index.vue +1 -1
  8. package/chart/rancher-backup/index.vue +2 -2
  9. package/cloud-credential/generic.vue +1 -1
  10. package/cloud-credential/harvester.vue +2 -2
  11. package/components/AssignTo.vue +1 -1
  12. package/components/AwsComplianceBanner.vue +1 -1
  13. package/components/BackLink.vue +7 -0
  14. package/components/BannerGraphic.vue +1 -0
  15. package/components/BrandImage.vue +3 -3
  16. package/components/ClusterProviderIcon.vue +1 -1
  17. package/components/CommunityLinks.vue +2 -2
  18. package/components/ConsumptionGauge.vue +17 -2
  19. package/components/CruResource.vue +3 -2
  20. package/components/DashboardMetrics.vue +8 -0
  21. package/components/DetailTop.vue +1 -1
  22. package/components/EmberPage.vue +1 -0
  23. package/components/ExplorerMembers.vue +8 -8
  24. package/components/ExplorerProjectsNamespaces.vue +9 -9
  25. package/components/FixedBanner.vue +1 -1
  26. package/components/GlobalRoleBindings.vue +11 -11
  27. package/components/GrafanaDashboard.vue +14 -2
  28. package/components/GrowlManager.vue +1 -1
  29. package/components/HarvesterServiceAddOnConfig.vue +4 -3
  30. package/components/IconOrSvg.vue +10 -3
  31. package/components/LandingPagePreference.vue +2 -2
  32. package/components/MoveModal.vue +1 -1
  33. package/components/PodSecurityAdmission.vue +3 -3
  34. package/components/ProgressBarMulti.vue +2 -2
  35. package/components/PromptRemove.vue +52 -28
  36. package/components/PromptRestore.vue +3 -3
  37. package/components/Questions/index.vue +5 -5
  38. package/components/RelatedWorkloadsTable.vue +1 -1
  39. package/components/ResourceList/Masthead.vue +1 -1
  40. package/components/ResourceTable.vue +3 -3
  41. package/components/ResourceYaml.vue +1 -1
  42. package/components/RoleBindings.vue +2 -2
  43. package/components/SimpleBox.vue +1 -0
  44. package/components/SingleClusterInfo.vue +1 -1
  45. package/components/SortableTable/actions.js +3 -3
  46. package/components/SortableTable/advanced-filtering.js +7 -7
  47. package/components/SortableTable/filtering.js +1 -1
  48. package/components/SortableTable/index.vue +14 -10
  49. package/components/SortableTable/selection.js +5 -5
  50. package/components/SortableTable/sorting.js +5 -5
  51. package/components/Tabbed/index.vue +7 -7
  52. package/components/TableSparkLine.vue +1 -1
  53. package/components/Wizard.vue +11 -23
  54. package/components/__tests__/Collapse.spec.ts +1 -1
  55. package/components/__tests__/CruResource.test.ts +74 -0
  56. package/components/__tests__/SimpleBox.spec.ts +1 -1
  57. package/components/auth/RoleDetailEdit.vue +7 -3
  58. package/components/auth/SelectPrincipal.vue +3 -3
  59. package/components/fleet/FleetResources.vue +1 -1
  60. package/components/fleet/FleetStatus.vue +4 -4
  61. package/components/fleet/FleetSummary.vue +1 -1
  62. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +1 -1
  63. package/components/fleet/ForceDirectedTreeChart/index.vue +1 -1
  64. package/components/form/ArrayList.vue +11 -3
  65. package/components/form/ArrayListSelect.vue +2 -2
  66. package/components/form/FileSelector.vue +6 -0
  67. package/components/form/GitPicker.vue +528 -0
  68. package/components/form/KeyValue.vue +82 -41
  69. package/components/form/LabeledSelect.vue +2 -2
  70. package/components/form/MatchExpressions.vue +2 -2
  71. package/components/form/Members/ClusterMembershipEditor.vue +1 -2
  72. package/components/form/Members/ClusterPermissionsEditor.vue +6 -5
  73. package/components/form/Members/MembershipEditor.vue +4 -4
  74. package/components/form/Members/ProjectMembershipEditor.vue +1 -2
  75. package/components/form/NameNsDescription.vue +13 -6
  76. package/components/form/Networking.vue +2 -2
  77. package/components/form/NodeScheduling.vue +1 -1
  78. package/components/form/PodAffinity.vue +7 -2
  79. package/components/form/ProjectMemberEditor.vue +4 -4
  80. package/components/form/ResourceQuota/Namespace.vue +2 -2
  81. package/components/form/ResourceQuota/NamespaceRow.vue +2 -2
  82. package/components/form/ResourceQuota/Project.vue +1 -1
  83. package/components/form/ResourceQuota/shared.js +2 -2
  84. package/components/form/ResourceSelector.vue +1 -1
  85. package/components/form/ResourceTabs/index.vue +1 -1
  86. package/components/form/RuleSelector.vue +1 -1
  87. package/components/form/SecretSelector.vue +4 -4
  88. package/components/form/Select.vue +2 -2
  89. package/components/form/SelectOrCreateAuthSecret.vue +3 -3
  90. package/components/form/ServiceNameSelect.vue +1 -1
  91. package/components/form/ServicePorts.vue +1 -1
  92. package/components/form/ShellInput.vue +1 -1
  93. package/components/form/SimpleSecretSelector.vue +4 -4
  94. package/components/form/Taints.vue +1 -1
  95. package/components/form/ValueFromResource.vue +3 -3
  96. package/components/form/WorkloadPorts.vue +8 -7
  97. package/components/form/__tests__/Error.test.ts +1 -1
  98. package/components/form/__tests__/KeyValue.test.ts +21 -0
  99. package/components/formatter/ClusterLink.vue +1 -1
  100. package/components/formatter/ClusterProvider.vue +13 -2
  101. package/components/formatter/Endpoints.vue +1 -1
  102. package/components/formatter/FleetSummaryGraph.vue +2 -2
  103. package/components/formatter/IngressTarget.vue +2 -2
  104. package/components/formatter/PodImages.vue +1 -1
  105. package/components/formatter/PrincipalGroupBindings.vue +1 -1
  106. package/components/formatter/ReceiverIcons.vue +3 -3
  107. package/components/formatter/ServiceType.vue +1 -1
  108. package/components/formatter/WorkloadDetailEndpoints.vue +1 -1
  109. package/components/formatter/WorkloadHealthScale.vue +1 -1
  110. package/components/formatter/__tests__/LiveDate.test.ts +1 -1
  111. package/components/graph/Bar.vue +1 -1
  112. package/components/graph/LinePlot.vue +3 -3
  113. package/components/nav/Group.vue +2 -2
  114. package/components/nav/Header.vue +5 -5
  115. package/components/nav/NamespaceFilter.vue +14 -14
  116. package/components/nav/TopLevelMenu.vue +76 -11
  117. package/components/nav/WindowManager/ContainerLogs.vue +2 -2
  118. package/components/nav/WindowManager/ContainerShell.vue +1 -1
  119. package/components/nav/WorkspaceSwitcher.vue +1 -1
  120. package/config/home-links.js +4 -4
  121. package/config/labels-annotations.js +8 -9
  122. package/config/pod-security-admission.ts +1 -1
  123. package/config/product/auth.js +5 -5
  124. package/config/product/explorer.js +14 -0
  125. package/config/store.js +2 -0
  126. package/config/table-headers.js +13 -13
  127. package/config/uiplugins.js +8 -1
  128. package/core/plugin-routes.ts +3 -2
  129. package/core/plugin.ts +3 -3
  130. package/core/plugins.js +7 -7
  131. package/creators/pkg/files/index.ts +1 -1
  132. package/detail/catalog.cattle.io.clusterrepo.vue +8 -1
  133. package/detail/cis.cattle.io.clusterscan.vue +3 -3
  134. package/detail/fleet.cattle.io.bundle.vue +1 -1
  135. package/detail/helm.cattle.io.projecthelmchart.vue +16 -29
  136. package/detail/management.cattle.io.user.vue +12 -12
  137. package/detail/namespace.vue +4 -4
  138. package/detail/networking.k8s.io.ingress.vue +3 -3
  139. package/detail/node.vue +2 -2
  140. package/detail/provisioning.cattle.io.cluster.vue +9 -10
  141. package/detail/service.vue +1 -1
  142. package/detail/workload/index.vue +3 -3
  143. package/dialog/AddProjectMemberDialog.vue +2 -2
  144. package/dialog/DrainNode.vue +1 -1
  145. package/dialog/GenericPrompt.vue +9 -5
  146. package/dialog/RotateEncryptionKeyDialog.vue +2 -2
  147. package/dialog/ScaleMachineDownDialog.vue +2 -2
  148. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +56 -0
  149. package/edit/auth/azuread.vue +3 -3
  150. package/edit/autoscaling.horizontalpodautoscaler/index.vue +5 -5
  151. package/edit/cis.cattle.io.clusterscan.vue +5 -5
  152. package/edit/cloudcredential.vue +4 -4
  153. package/edit/constraints.gatekeeper.sh.constraint/NamespaceList.vue +1 -1
  154. package/edit/constraints.gatekeeper.sh.constraint/index.vue +4 -4
  155. package/edit/fleet.cattle.io.gitrepo.vue +6 -6
  156. package/edit/helm.cattle.io.projecthelmchart.vue +3 -3
  157. package/edit/logging-flow/index.vue +4 -4
  158. package/edit/logging.banzaicloud.io.output/index.vue +3 -3
  159. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +1 -1
  160. package/edit/logging.banzaicloud.io.output/providers/forward.vue +1 -1
  161. package/edit/logging.banzaicloud.io.output/providers/logz.vue +1 -1
  162. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +1 -1
  163. package/edit/logging.banzaicloud.io.output/providers/redis.vue +1 -1
  164. package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +1 -1
  165. package/edit/management.cattle.io.clusterroletemplatebinding.vue +1 -1
  166. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +1 -1
  167. package/edit/management.cattle.io.project.vue +3 -3
  168. package/edit/management.cattle.io.projectroletemplatebinding.vue +2 -2
  169. package/edit/management.cattle.io.setting.vue +1 -1
  170. package/edit/management.cattle.io.user.vue +2 -2
  171. package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +2 -2
  172. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  173. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +1 -1
  174. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +3 -3
  175. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +5 -5
  176. package/edit/monitoring.coreos.com.prometheusrule/duration.js +1 -1
  177. package/edit/monitoring.coreos.com.prometheusrule/index.vue +8 -3
  178. package/edit/monitoring.coreos.com.receiver/auth.vue +2 -2
  179. package/edit/monitoring.coreos.com.receiver/tls.vue +3 -4
  180. package/edit/monitoring.coreos.com.receiver/types/__tests__/email.test.ts +53 -0
  181. package/edit/monitoring.coreos.com.receiver/types/email.vue +2 -0
  182. package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +3 -3
  183. package/edit/monitoring.coreos.com.receiver/types/webhook.add.vue +1 -1
  184. package/edit/monitoring.coreos.com.route.vue +2 -2
  185. package/edit/namespace.vue +21 -13
  186. package/edit/networking.k8s.io.ingress/Certificate.vue +2 -2
  187. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  188. package/edit/networking.k8s.io.ingress/RulePath.vue +2 -2
  189. package/edit/networking.k8s.io.ingress/Rules.vue +2 -2
  190. package/edit/networking.k8s.io.ingress/index.vue +4 -4
  191. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +3 -3
  192. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  193. package/edit/persistentvolume/index.vue +4 -4
  194. package/edit/persistentvolumeclaim.vue +3 -3
  195. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +1 -1
  196. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +2 -2
  197. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  198. package/edit/provisioning.cattle.io.cluster/index.vue +7 -7
  199. package/edit/provisioning.cattle.io.cluster/rke2.vue +28 -29
  200. package/edit/resources.cattle.io.backup.vue +2 -2
  201. package/edit/resources.cattle.io.restore.vue +3 -3
  202. package/edit/secret/generic.vue +1 -1
  203. package/edit/secret/index.vue +3 -3
  204. package/edit/service.vue +3 -21
  205. package/edit/serviceaccount.vue +2 -2
  206. package/edit/storage.k8s.io.storageclass/index.vue +4 -4
  207. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +1 -1
  208. package/edit/token.vue +5 -5
  209. package/edit/workload/index.vue +1 -1
  210. package/edit/workload/mixins/workload.js +8 -8
  211. package/edit/workload/storage/ContainerMountPaths.vue +9 -9
  212. package/edit/workload/storage/Mount.vue +2 -2
  213. package/edit/workload/storage/csi/index.vue +1 -1
  214. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  215. package/edit/workload/storage/index.vue +6 -6
  216. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +2 -2
  217. package/initialize/client.js +8 -8
  218. package/initialize/index.js +1 -4
  219. package/layouts/default.vue +38 -11
  220. package/list/catalog.cattle.io.clusterrepo.vue +9 -1
  221. package/list/cis.cattle.io.clusterscan.vue +1 -1
  222. package/list/fleet.cattle.io.cluster.vue +2 -2
  223. package/list/group.principal.vue +1 -1
  224. package/list/helm.cattle.io.projecthelmchart.vue +2 -2
  225. package/list/management.cattle.io.cluster.vue +1 -1
  226. package/list/management.cattle.io.feature.vue +1 -1
  227. package/list/management.cattle.io.user.vue +2 -2
  228. package/list/node.vue +5 -5
  229. package/list/provisioning.cattle.io.cluster.vue +4 -5
  230. package/machine-config/amazonec2.vue +2 -2
  231. package/machine-config/digitalocean.vue +4 -4
  232. package/machine-config/linode.vue +4 -4
  233. package/machine-config/vmwarevsphere.vue +12 -12
  234. package/middleware/authenticated.js +7 -6
  235. package/mixins/brand.js +1 -1
  236. package/mixins/chart.js +6 -6
  237. package/mixins/fetch.client.js +2 -2
  238. package/mixins/form-validation.js +7 -7
  239. package/mixins/resource-fetch-namespaced.js +1 -1
  240. package/mixins/resource-fetch.js +2 -2
  241. package/models/apps.statefulset.js +2 -2
  242. package/models/batch.cronjob.js +1 -1
  243. package/models/catalog.cattle.io.app.js +4 -4
  244. package/models/cis.cattle.io.clusterscan.js +1 -1
  245. package/models/cis.cattle.io.clusterscanbenchmark.js +1 -1
  246. package/models/cis.cattle.io.clusterscanreport.js +1 -1
  247. package/models/cloudcredential.js +1 -1
  248. package/models/cluster/node.js +5 -5
  249. package/models/cluster.x-k8s.io.machinedeployment.js +2 -2
  250. package/models/fleet.cattle.io.gitrepo.js +3 -3
  251. package/models/group.principal.js +4 -4
  252. package/models/helm.cattle.io.projecthelmchart.js +2 -2
  253. package/models/logging.banzaicloud.io.clusterflow.js +2 -2
  254. package/models/logging.banzaicloud.io.flow.js +5 -5
  255. package/models/logging.banzaicloud.io.output.js +2 -2
  256. package/models/management.cattle.io.cluster.js +10 -14
  257. package/models/management.cattle.io.globalrole.js +4 -4
  258. package/models/management.cattle.io.node.js +2 -2
  259. package/models/management.cattle.io.nodepool.js +3 -3
  260. package/models/management.cattle.io.nodetemplate.js +4 -4
  261. package/models/management.cattle.io.project.js +2 -2
  262. package/models/management.cattle.io.roletemplate.js +1 -1
  263. package/models/management.cattle.io.setting.js +1 -1
  264. package/models/management.cattle.io.user.js +5 -5
  265. package/models/monitoring.coreos.com.receiver.js +9 -9
  266. package/models/namespace.js +1 -1
  267. package/models/networking.k8s.io.ingress.js +5 -5
  268. package/models/persistentvolume.js +3 -3
  269. package/models/pod.js +3 -3
  270. package/models/provisioning.cattle.io.cluster.js +39 -27
  271. package/models/rbac.authorization.k8s.io.clusterrole.js +2 -2
  272. package/models/rbac.authorization.k8s.io.role.js +3 -3
  273. package/models/secret.js +1 -1
  274. package/models/service.js +2 -2
  275. package/models/storage.k8s.io.storageclass.js +2 -2
  276. package/models/token.js +1 -1
  277. package/models/workload.js +6 -6
  278. package/models/workload.service.js +5 -21
  279. package/package.json +3 -2
  280. package/pages/about.vue +9 -9
  281. package/pages/account/index.vue +2 -2
  282. package/pages/auth/login.vue +25 -12
  283. package/pages/auth/setup.vue +4 -0
  284. package/pages/auth/verify.vue +6 -0
  285. package/pages/c/_cluster/apps/charts/index.vue +4 -4
  286. package/pages/c/_cluster/apps/charts/install.vue +28 -20
  287. package/pages/c/_cluster/auth/roles/index.vue +10 -10
  288. package/pages/c/_cluster/explorer/index.vue +41 -16
  289. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  290. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +1 -1
  291. package/pages/c/_cluster/fleet/index.vue +11 -11
  292. package/pages/c/_cluster/monitoring/index.vue +1 -1
  293. package/pages/c/_cluster/settings/links.vue +3 -3
  294. package/pages/c/_cluster/settings/performance.vue +1 -1
  295. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +6 -6
  296. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +3 -3
  297. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -3
  298. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  299. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +3 -3
  300. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +6 -6
  301. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +4 -4
  302. package/pages/c/_cluster/uiplugins/index.vue +22 -19
  303. package/pages/diagnostic.vue +6 -6
  304. package/pages/home.vue +8 -3
  305. package/pages/prefs.vue +2 -2
  306. package/pages/rio/mesh.vue +3 -3
  307. package/pages/support/index.vue +10 -1
  308. package/pkg/auto-import.js +1 -1
  309. package/pkg/tsconfig.json +1 -0
  310. package/pkg/vue.config.js +1 -1
  311. package/plugins/axios.js +1 -1
  312. package/plugins/clean-html-directive.js +1 -1
  313. package/plugins/dashboard-store/__tests__/mutations.spec.js +4 -4
  314. package/plugins/dashboard-store/actions.js +4 -4
  315. package/plugins/dashboard-store/getters.js +1 -1
  316. package/plugins/dashboard-store/index.js +1 -1
  317. package/plugins/dashboard-store/mutations.js +2 -2
  318. package/plugins/dashboard-store/resource-class.js +8 -8
  319. package/plugins/i18n.js +1 -1
  320. package/plugins/plugin.js +5 -1
  321. package/plugins/steve/actions.js +25 -3
  322. package/plugins/steve/getters.js +3 -3
  323. package/plugins/steve/hybrid-class.js +1 -1
  324. package/plugins/steve/mutations.js +1 -1
  325. package/plugins/steve/performanceTesting.js +1 -1
  326. package/plugins/steve/resourceWatcher.js +1 -1
  327. package/plugins/steve/subscribe.js +6 -6
  328. package/plugins/steve/worker/web-worker.basic.js +1 -1
  329. package/promptRemove/management.cattle.io.project.vue +3 -3
  330. package/promptRemove/mixin/roleDeletionCheck.js +4 -4
  331. package/promptRemove/pod.vue +1 -1
  332. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +2 -2
  333. package/rancher-components/components/Form/Checkbox/Checkbox.vue +1 -1
  334. package/rancher-components/components/Form/Radio/RadioButton.test.ts +1 -1
  335. package/rancher-components/components/Form/Radio/RadioButton.vue +2 -2
  336. package/rancher-components/components/Form/Radio/RadioGroup.vue +2 -2
  337. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  338. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +1 -1
  339. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -7
  340. package/rancher-components/components/StringList/StringList.test.ts +10 -9
  341. package/rancher-components/components/StringList/StringList.vue +5 -5
  342. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
  343. package/store/action-menu.js +4 -4
  344. package/store/auth.js +40 -7
  345. package/store/aws.js +1 -1
  346. package/store/catalog.js +12 -11
  347. package/store/digitalocean.js +4 -4
  348. package/store/features.js +1 -0
  349. package/store/github.js +70 -213
  350. package/store/gitlab.js +159 -0
  351. package/store/growl.js +1 -1
  352. package/store/i18n.js +7 -7
  353. package/store/index.js +63 -22
  354. package/store/linode.js +1 -1
  355. package/store/plugins.js +5 -5
  356. package/store/pnap.js +1 -1
  357. package/store/prefs.js +6 -6
  358. package/store/resource-fetch.js +3 -3
  359. package/store/type-map.js +61 -42
  360. package/store/uiplugins.ts +2 -1
  361. package/store/wm.js +5 -4
  362. package/tsconfig.default.json +10 -0
  363. package/tsconfig.json +2 -9
  364. package/types/shell/index.d.ts +10 -2
  365. package/utils/__tests__/version.test.ts +28 -0
  366. package/utils/alertmanagerconfig.js +4 -4
  367. package/utils/array.ts +4 -4
  368. package/utils/async.ts +1 -1
  369. package/utils/auth.js +3 -3
  370. package/utils/axios.js +5 -5
  371. package/utils/cluster.js +4 -3
  372. package/utils/color.js +10 -0
  373. package/utils/create-yaml.js +4 -4
  374. package/utils/crypto/browserHashUtils.js +1 -1
  375. package/utils/crypto/browserMd5.js +1 -1
  376. package/utils/crypto/browserSha1.js +1 -1
  377. package/utils/crypto/browserSha256.js +1 -1
  378. package/utils/crypto/index.js +3 -3
  379. package/utils/favicon.js +2 -3
  380. package/utils/gatekeeper/util.js +3 -3
  381. package/utils/gc/gc.ts +2 -2
  382. package/utils/git.ts +92 -0
  383. package/utils/grafana.js +4 -4
  384. package/utils/monitoring.js +2 -2
  385. package/utils/nuxt.js +2 -2
  386. package/utils/object.js +5 -5
  387. package/utils/pod-security-admission.ts +1 -1
  388. package/utils/projectAndNamespaceFiltering.utils.ts +1 -1
  389. package/utils/select.js +2 -2
  390. package/utils/selector.js +2 -2
  391. package/utils/settings.ts +17 -2
  392. package/utils/socket.js +30 -6
  393. package/utils/sort.js +1 -1
  394. package/utils/string.js +1 -1
  395. package/utils/url.ts +1 -1
  396. package/utils/validators/formRules/index.ts +3 -3
  397. package/utils/validators/role-template.js +4 -4
  398. package/utils/version.js +14 -1
  399. package/vue.config.js +19 -13
  400. package/components/form/GithubPicker.vue +0 -390
@@ -252,6 +252,7 @@ export default {
252
252
  if (iframeEl === null) {
253
253
  iframeEl = document.createElement('iframe');
254
254
  iframeEl.setAttribute('id', EMBER_FRAME);
255
+ iframeEl.setAttribute('data-testid', EMBER_FRAME);
255
256
  iframeEl.classList.add(EMBER_FRAME_HIDE_CLASS);
256
257
 
257
258
  if (this.inline) {
@@ -70,7 +70,7 @@ export default {
70
70
  }
71
71
 
72
72
  this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT })
73
- .then(projects => this.$set(this, 'projects', projects));
73
+ .then((projects) => this.$set(this, 'projects', projects));
74
74
 
75
75
  const hydration = {
76
76
  normanPrincipals: this.$store.dispatch('rancher/findAll', { type: NORMAN.PRINCIPAL }),
@@ -123,11 +123,11 @@ export default {
123
123
  computed: {
124
124
  ...mapGetters(['currentCluster']),
125
125
  clusterRoleTemplateBindings() {
126
- return this.normanClusterRoleTemplateBindings.map(b => b.clusterroletemplatebinding) ;
126
+ return this.normanClusterRoleTemplateBindings.map((b) => b.clusterroletemplatebinding) ;
127
127
  },
128
128
  filteredClusterRoleTemplateBindings() {
129
129
  return this.clusterRoleTemplateBindings.filter(
130
- b => b?.clusterName === this.$store.getters['currentCluster'].id
130
+ (b) => b?.clusterName === this.$store.getters['currentCluster'].id
131
131
  );
132
132
  },
133
133
  filteredProjects() {
@@ -222,10 +222,10 @@ export default {
222
222
  return this.$store.getters['currentCluster'].isLocal;
223
223
  },
224
224
  canEditProjectMembers() {
225
- return this.normanProjectRTBSchema?.collectionMethods.find(x => x.toLowerCase() === 'post');
225
+ return this.normanProjectRTBSchema?.collectionMethods.find((x) => x.toLowerCase() === 'post');
226
226
  },
227
227
  canEditClusterMembers() {
228
- return this.normanClusterRTBSchema?.collectionMethods.find(x => x.toLowerCase() === 'post');
228
+ return this.normanClusterRTBSchema?.collectionMethods.find((x) => x.toLowerCase() === 'post');
229
229
  },
230
230
  },
231
231
  methods: {
@@ -250,12 +250,12 @@ export default {
250
250
  },
251
251
 
252
252
  getProjectRoleBinding(row, role) {
253
- // Each row is a combination of user/group and project
254
- // So find the specfic roleBindingTemplate corresponding to the specific role + project
253
+ // Each row is a combination of project, role and user/group
254
+ // So find the specfic roleBindingTemplate corresponding to the specific project, role + user/group
255
255
  const userOrGroupKey = row.userId ? 'userId' : 'groupPrincipalId';
256
256
 
257
257
  return this.projectRoleTemplateBindings.find((r) => {
258
- return r.roleTemplateId === role.id && r[userOrGroupKey] === row[userOrGroupKey];
258
+ return r.projectId === row.projectId && r.roleTemplateId === role.id && r[userOrGroupKey] === row[userOrGroupKey];
259
259
  });
260
260
  },
261
261
 
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { mapGetters } from 'vuex';
3
- import ResourceTable from '@shell/components/ResourceTable';
3
+ import ResourceTable, { defaultTableSortGenerationFn } from '@shell/components/ResourceTable';
4
4
  import { STATE, AGE, NAME } from '@shell/config/table-headers';
5
5
  import { uniq } from '@shell/utils/array';
6
6
  import { MANAGEMENT, NAMESPACE, VIRTUAL_TYPES } from '@shell/config/types';
@@ -8,7 +8,7 @@ import { PROJECT_ID, FLAT_VIEW } from '@shell/config/query-params';
8
8
  import Masthead from '@shell/components/ResourceList/Masthead';
9
9
  import { mapPref, GROUP_RESOURCES, ALL_NAMESPACES } from '@shell/store/prefs';
10
10
  import MoveModal from '@shell/components/MoveModal';
11
- import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
11
+
12
12
  import { NAMESPACE_FILTER_ALL_ORPHANS } from '@shell/utils/namespace-filter';
13
13
  import ResourceFetch from '@shell/mixins/resource-fetch';
14
14
  import DOMPurify from 'dompurify';
@@ -97,12 +97,12 @@ export default {
97
97
  NAME,
98
98
  this.groupPreference === 'none' ? project : null,
99
99
  AGE
100
- ].filter(h => h);
100
+ ].filter((h) => h);
101
101
  },
102
102
  projectIdsWithNamespaces() {
103
103
  const ids = this.rows
104
- .map(row => row.projectId)
105
- .filter(id => id);
104
+ .map((row) => row.projectId)
105
+ .filter((id) => id);
106
106
 
107
107
  return uniq(ids);
108
108
  },
@@ -117,13 +117,13 @@ export default {
117
117
  return this.$store.getters[`${ this.currentProduct.inStore }/filterProject`];
118
118
  }
119
119
 
120
- const clustersInProjects = projectsInAllClusters.filter(project => project.spec.clusterName === clusterId);
120
+ const clustersInProjects = projectsInAllClusters.filter((project) => project.spec.clusterName === clusterId);
121
121
 
122
122
  return clustersInProjects;
123
123
  },
124
124
  projectsWithoutNamespaces() {
125
125
  return this.activeProjects.filter((project) => {
126
- return !this.projectIdsWithNamespaces.find(item => project?.id?.endsWith(`/${ item }`));
126
+ return !this.projectIdsWithNamespaces.find((item) => project?.id?.endsWith(`/${ item }`));
127
127
  });
128
128
  },
129
129
  // We're using this because we need to show projects as groups even if the project doesn't have any namespaces.
@@ -226,7 +226,7 @@ export default {
226
226
  return false;
227
227
  }
228
228
 
229
- const someNamespacesAreNotInProject = !this.rows.some(row => !row.project);
229
+ const someNamespacesAreNotInProject = !this.rows.some((row) => !row.project);
230
230
 
231
231
  // Hide the "Not in a Project" group if the user is filtering
232
232
  // for specific namespaces or projects.
@@ -250,7 +250,7 @@ export default {
250
250
  const dictionary = row.psaTooltipsDescription;
251
251
  const list = Object.values(dictionary)
252
252
  .sort()
253
- .map(text => `<li>${ text }</li>`).join('');
253
+ .map((text) => `<li>${ text }</li>`).join('');
254
254
  const title = `<p>${ this.t('podSecurityAdmission.name') }: </p>`;
255
255
 
256
256
  return `${ title }<ul class="psa-tooltip">${ list }</ul>`;
@@ -41,7 +41,7 @@ export default {
41
41
  handleLineBreaksConsentText(banner) {
42
42
  if (banner.text?.length) {
43
43
  // split text by newline char
44
- const textArray = banner.text.split(/\\n/).filter(element => element);
44
+ const textArray = banner.text.split(/\\n/).filter((element) => element);
45
45
 
46
46
  if (textArray.length > 1) {
47
47
  textArray.forEach((str, i) => {
@@ -120,7 +120,7 @@ export default {
120
120
  },
121
121
  methods: {
122
122
  getRoleType(role) {
123
- if (this.globalPermissions.find(p => p === role.id)) {
123
+ if (this.globalPermissions.find((p) => p === role.id)) {
124
124
  return 'global';
125
125
  } else if (role.builtin) {
126
126
  return 'builtin';
@@ -159,7 +159,7 @@ export default {
159
159
 
160
160
  Object.values(this.sortedRoles).forEach((roles) => {
161
161
  roles.forEach((mappedRole) => {
162
- const boundRole = boundRoles.find(boundRole => boundRole.globalRoleName === mappedRole.id);
162
+ const boundRole = boundRoles.find((boundRole) => boundRole.globalRoleName === mappedRole.id);
163
163
 
164
164
  if (!!boundRole) {
165
165
  this.selectedRoles.push(mappedRole.id);
@@ -184,10 +184,10 @@ export default {
184
184
  },
185
185
  checkboxChanged() {
186
186
  const addRoles = this.selectedRoles
187
- .filter(selected => !this.startingSelectedRoles.find(startingRole => startingRole.roleId === selected));
187
+ .filter((selected) => !this.startingSelectedRoles.find((startingRole) => startingRole.roleId === selected));
188
188
  const removeBindings = this.startingSelectedRoles
189
- .filter(startingRole => !this.selectedRoles.find(selected => selected === startingRole.roleId))
190
- .map(startingRole => startingRole.bindingId);
189
+ .filter((startingRole) => !this.selectedRoles.find((selected) => selected === startingRole.roleId))
190
+ .map((startingRole) => startingRole.bindingId);
191
191
 
192
192
  this.roleChanges = {
193
193
  initialRoles: this.startingSelectedRoles,
@@ -210,22 +210,22 @@ export default {
210
210
  } else {
211
211
  requestOptions.userName = userId || this.userId;
212
212
  }
213
- const newBindings = await Promise.all(this.roleChanges.addRoles.map(role => this.$store.dispatch(`management/create`, {
213
+ const newBindings = await Promise.all(this.roleChanges.addRoles.map((role) => this.$store.dispatch(`management/create`, {
214
214
  ...requestOptions,
215
215
  globalRoleName: role,
216
216
  })));
217
217
 
218
218
  // Save all changes (and ensure user isn't logged out if they don't have permissions to make a change)
219
- await Promise.all(newBindings.map(newBinding => newBinding.save({ redirectUnauthorized: false })));
219
+ await Promise.all(newBindings.map((newBinding) => newBinding.save({ redirectUnauthorized: false })));
220
220
  },
221
221
  async saveRemovedRoles() {
222
- const existingBindings = await Promise.all(this.roleChanges.removeBindings.map(bindingId => this.$store.dispatch('management/find', {
222
+ const existingBindings = await Promise.all(this.roleChanges.removeBindings.map((bindingId) => this.$store.dispatch('management/find', {
223
223
  type: MANAGEMENT.GLOBAL_ROLE_BINDING,
224
224
  id: bindingId
225
225
  })));
226
226
 
227
227
  // Save all changes (and ensure user isn't logged out if they don't have permissions to make a change)
228
- await Promise.all(existingBindings.map(existingBinding => existingBinding.remove({ redirectUnauthorized: false })));
228
+ await Promise.all(existingBindings.map((existingBinding) => existingBinding.remove({ redirectUnauthorized: false })));
229
229
  },
230
230
  /**
231
231
  * userId is optional, used when a user has just been created
@@ -250,7 +250,7 @@ export default {
250
250
  });
251
251
  });
252
252
 
253
- return allRolesRules.some(rule => this.isRuleValid(rule));
253
+ return allRolesRules.some((rule) => this.isRuleValid(rule));
254
254
  },
255
255
  isRuleValid(rule) {
256
256
  // Brought over from Ember
@@ -281,7 +281,7 @@ export default {
281
281
 
282
282
  if (isArray(verbs) && verbs.length > 1) {
283
283
  // console.log(`verbsRequiredForLogin status 1: `, restrictedTarget.every(rt => verbs.includes(rt)), verbs);
284
- return restrictedTarget.every(rt => verbs.includes(rt));
284
+ return restrictedTarget.every((rt) => verbs.includes(rt));
285
285
  }
286
286
 
287
287
  // console.log(`verbsRequiredForLogin status 2: `, verbsRequiredForLogin.includes(verbs[0]), verbsRequiredForLogin, verbs);
@@ -23,6 +23,12 @@ export default {
23
23
  type: String,
24
24
  default: null
25
25
  },
26
+ // change the grafana url prefix for local clusters in certain monitoring versions
27
+ // project monitoring (projectHelmCharts) supply a grafana url that never needs to be modified in this way
28
+ modifyPrefix: {
29
+ type: Boolean,
30
+ default: true
31
+ },
26
32
  backgroundColor: {
27
33
  type: String,
28
34
  default: '#1b1c21'
@@ -138,7 +144,7 @@ export default {
138
144
  const clusterId = this.$store.getters['currentCluster'].id;
139
145
  const params = this.computeParams();
140
146
 
141
- return computeDashboardUrl(this.monitoringVersion, embedUrl, clusterId, params);
147
+ return computeDashboardUrl(this.monitoringVersion, embedUrl, clusterId, params, this.modifyPrefix);
142
148
  },
143
149
  computeParams() {
144
150
  const params = {};
@@ -253,10 +259,16 @@ export default {
253
259
  v-if="!loading && !error"
254
260
  class="external-link"
255
261
  >
262
+ <!-- https://github.com/harvester/harvester-installer/pull/512/files -->
263
+ <!-- It is necessary to include the parameter referer when accessing the Grafana page. -->
264
+ <!-- This parameter is required by the backend to identify the origin of the request from which cluster -->
265
+ <!-- The matching mechanism as follows: -->
266
+ <!-- ~.*/k8s/clusters/(c-m-.+)/.* -->
267
+ <!-- ~.*/dashboard/harvester/c/(c-m-.+)/.* -->
256
268
  <a
257
269
  :href="grafanaUrl"
258
270
  target="_blank"
259
- rel="noopener noreferrer nofollow"
271
+ rel="noopener nofollow"
260
272
  >{{ t('grafanaDashboard.grafana') }} <i class="icon icon-external-link" /></a>
261
273
  </div>
262
274
  </div>
@@ -10,7 +10,7 @@ export default {
10
10
  ...mapState('growl', ['stack']),
11
11
 
12
12
  shouldRun() {
13
- return this.stack.length && this.stack.find(x => x.timeout > 0);
13
+ return this.stack.length && this.stack.find((x) => x.timeout > 0);
14
14
  }
15
15
  },
16
16
 
@@ -98,7 +98,7 @@ export default {
98
98
  portOptions() {
99
99
  const ports = this.value?.spec?.ports || [];
100
100
 
101
- return ports.filter(p => p.port && p.protocol === 'TCP').map(p => p.port) || [];
101
+ return ports.filter((p) => p.port && p.protocol === 'TCP').map((p) => p.port) || [];
102
102
  },
103
103
 
104
104
  serviceOptions() {
@@ -116,7 +116,7 @@ export default {
116
116
  namespaces[s.metadata.namespace];
117
117
  });
118
118
 
119
- return out.map(s => s.id);
119
+ return out.map((s) => s.id);
120
120
  },
121
121
 
122
122
  shareIPEnabled() {
@@ -124,7 +124,7 @@ export default {
124
124
  const kubernetesVersionExtension = this.currentCluster.kubernetesVersionExtension;
125
125
 
126
126
  if (kubernetesVersionExtension.startsWith('+rke2')) {
127
- const charts = ((this.rke2Versions?.data || []).find(v => v.id === kubernetesVersion) || {}).charts;
127
+ const charts = ((this.rke2Versions?.data || []).find((v) => v.id === kubernetesVersion) || {}).charts;
128
128
  let ccmVersion = charts?.['harvester-cloud-provider']?.version || '';
129
129
 
130
130
  if (ccmVersion.endsWith('00')) {
@@ -188,6 +188,7 @@ export default {
188
188
  :mode="mode"
189
189
  :options="ipamOptions"
190
190
  :label="t('servicesPage.harvester.ipam.label')"
191
+ :disabled="mode === 'edit'"
191
192
  />
192
193
  <div
193
194
  v-if="mode === 'create'"
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import Vue from 'vue';
20
20
  import { Solver } from '@shell/utils/svg-filter';
21
- import { colorToRgb, mapStandardColors } from '@shell/utils/color';
21
+ import { colorToRgb, mapStandardColors, normalizeHex } from '@shell/utils/color';
22
22
 
23
23
  const filterCache = {};
24
24
  const cssCache = {};
@@ -75,11 +75,18 @@ export default {
75
75
  if (stylesheet && stylesheet.cssRules) {
76
76
  for (let x = 0; x < Object.keys(stylesheet.cssRules).length; x++) {
77
77
  const cssRules = stylesheet.cssRules[x];
78
- const selectorText = currTheme === 'light' ? 'body, .theme-light' : '.theme-dark';
79
78
 
80
- if (cssRules.selectorText && cssRules.selectorText === selectorText) {
79
+ if (cssRules.selectorText && ((currTheme === 'light' && cssRules.selectorText.includes('body') &&
80
+ cssRules.selectorText.includes('.theme-light') && cssRules.style.cssText.includes('--link:')) ||
81
+ (currTheme === 'dark' && cssRules.selectorText.includes('.theme-dark')))) {
82
+ // grab the colors to be used on the icon from the css rules
81
83
  uiColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].color).trim());
82
84
  hoverColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].hover).trim());
85
+
86
+ // normalize hex colors (#xxx to #xxxxxx)
87
+ uiColor = normalizeHex(uiColor);
88
+ hoverColor = normalizeHex(hoverColor);
89
+
83
90
  found = true;
84
91
  break;
85
92
  }
@@ -35,7 +35,7 @@ export default {
35
35
  routeFromDropdown: {
36
36
  get() {
37
37
  const route = this.customRoute || {};
38
- const out = this.routeDropdownOptions.find(opt => opt.value.name === route.name && opt.value.params?.cluster === route.params?.cluster);
38
+ const out = this.routeDropdownOptions.find((opt) => opt.value.name === route.name && opt.value.params?.cluster === route.params?.cluster);
39
39
 
40
40
  return out || this.routeDropdownOptions[0];
41
41
  },
@@ -72,7 +72,7 @@ export default {
72
72
  routeDropdownOptions() {
73
73
  // Drop-down shows list of clusters that can ber set as login landing page
74
74
  const out = [];
75
- const kubeClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(this.clusters), this.$store);
75
+ const kubeClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(this.clusters, this.$store), this.$store);
76
76
 
77
77
  kubeClusters.forEach((c) => {
78
78
  if (c.isReady) {
@@ -27,7 +27,7 @@ export default {
27
27
  ...mapGetters(['currentCluster']),
28
28
 
29
29
  excludedProjects() {
30
- return this.toMove.filter(namespace => !!namespace.project).map(namespace => namespace.project.shortId);
30
+ return this.toMove.filter((namespace) => !!namespace.project).map((namespace) => namespace.project.shortId);
31
31
  },
32
32
 
33
33
  projectOptions() {
@@ -83,7 +83,7 @@ export default Vue.extend({
83
83
  // Generate PSA form controls
84
84
  psaControls: toDictionary(PSAModes, getPsaControl) as Record<PSAMode, PSAControl>,
85
85
  psaExemptionsControls: toDictionary(PSADimensions, getExemptionControl) as Record<PSADimension, PSAExemptionControl>,
86
- options: PSALevels.map(level => ({
86
+ options: PSALevels.map((level) => ({
87
87
  value: level,
88
88
  label: this.t(`podSecurityAdmission.labels.${ level }`)
89
89
  })),
@@ -145,7 +145,7 @@ export default Vue.extend({
145
145
  */
146
146
  updateExemptions(): void {
147
147
  const exemptions = PSADimensions.reduce((acc, dimension) => {
148
- const value = this.psaExemptionsControls[dimension].value.split(',').map(value => value.trim());
148
+ const value = this.psaExemptionsControls[dimension].value.split(',').map((value) => value.trim());
149
149
  const active = this.psaExemptionsControls[dimension].active;
150
150
 
151
151
  return {
@@ -182,7 +182,7 @@ export default Vue.extend({
182
182
  */
183
183
  getPsaExemptions(): Record<PSADimension, PSAExemptionControl> {
184
184
  return PSADimensions.reduce((acc, dimension) => {
185
- const values = (this.exemptions[dimension] || []).map(value => value.trim()).join(',');
185
+ const values = (this.exemptions[dimension] || []).map((value) => value.trim()).join(',');
186
186
 
187
187
  return {
188
188
  ...acc,
@@ -68,7 +68,7 @@ export default {
68
68
  if ( !this.max ) {
69
69
  max = 100;
70
70
  if ( out.length ) {
71
- max = out.map(x => x.value).reduce((a, b) => a + b);
71
+ max = out.map((x) => x.value).reduce((a, b) => a + b);
72
72
  }
73
73
  }
74
74
 
@@ -88,7 +88,7 @@ export default {
88
88
  obj.style = `width: ${ obj.percent }%`;
89
89
  }
90
90
 
91
- return out.filter(obj => obj.percent);
91
+ return out.filter((obj) => obj.percent);
92
92
  },
93
93
  }
94
94
  };
@@ -9,11 +9,13 @@ import { uniq } from '@shell/utils/array';
9
9
  import AsyncButton from '@shell/components/AsyncButton';
10
10
  import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
11
11
  import { CATALOG } from '@shell/config/types';
12
+ import { LabeledInput } from '@components/Form/LabeledInput';
13
+
12
14
  export default {
13
15
  name: 'PromptRemove',
14
16
 
15
17
  components: {
16
- Card, Checkbox, AsyncButton
18
+ Card, Checkbox, AsyncButton, LabeledInput
17
19
  },
18
20
  props: {
19
21
  /**
@@ -42,7 +44,7 @@ export default {
42
44
  },
43
45
  computed: {
44
46
  names() {
45
- return this.toRemove.map(obj => obj.nameDisplay).slice(0, 5);
47
+ return this.toRemove.map((obj) => obj.nameDisplay).slice(0, 5);
46
48
  },
47
49
 
48
50
  nameToMatchPosition() {
@@ -100,6 +102,11 @@ export default {
100
102
  if (this.toRemove.length > 1) {
101
103
  return null;
102
104
  }
105
+
106
+ if (this.toRemove[0].doneLocationRemove) {
107
+ return this.toRemove[0].doneLocationRemove;
108
+ }
109
+
103
110
  const currentRoute = this.toRemove[0].currentRoute();
104
111
  const out = {};
105
112
  const params = { ...currentRoute.params };
@@ -184,7 +191,7 @@ export default {
184
191
  // if none found (delete is allowed), then check for any resources with a warning message
185
192
  toRemove(neu) {
186
193
  let message;
187
- const preventDeletionMessages = neu.filter(item => item.preventDeletionMessage);
194
+ const preventDeletionMessages = neu.filter((item) => item.preventDeletionMessage);
188
195
 
189
196
  this.preventDelete = false;
190
197
 
@@ -192,7 +199,7 @@ export default {
192
199
  this.preventDelete = true;
193
200
  message = preventDeletionMessages[0].preventDeletionMessage;
194
201
  } else {
195
- const warnDeletionMessages = neu.filter(item => item.warnDeletionMessage);
202
+ const warnDeletionMessages = neu.filter((item) => item.warnDeletionMessage);
196
203
 
197
204
  if (!!warnDeletionMessages.length) {
198
205
  message = warnDeletionMessages[0].warnDeletionMessage;
@@ -224,6 +231,7 @@ export default {
224
231
  // doneLocation will recompute to undefined when delete request completes
225
232
  this.cachedDoneLocation = { ...this.doneLocation };
226
233
  }
234
+
227
235
  if (this.hasCustomRemove && this.$refs?.customPrompt?.remove) {
228
236
  let handled = this.$refs.customPrompt.remove(btnCB);
229
237
 
@@ -247,7 +255,7 @@ export default {
247
255
  return;
248
256
  }
249
257
  }
250
- const serialRemove = this.toRemove.some(resource => resource.removeSerially);
258
+ const serialRemove = this.toRemove.some((resource) => resource.removeSerially);
251
259
 
252
260
  if (serialRemove) {
253
261
  this.serialRemove(btnCB);
@@ -272,10 +280,16 @@ export default {
272
280
  },
273
281
  async parallelRemove(btnCB) {
274
282
  try {
283
+ if (typeof this.toRemove[0].bulkRemove !== 'undefined') {
284
+ await this.toRemove[0].bulkRemove(this.toRemove, {});
285
+ } else {
286
+ await Promise.all(this.toRemove.map((resource) => resource.remove()));
287
+ }
288
+
275
289
  const spoofedTypes = this.getSpoofedTypes(this.toRemove);
276
290
 
277
- await Promise.all(this.toRemove.map(resource => resource.remove()));
278
291
  await this.refreshSpoofedTypes(spoofedTypes);
292
+
279
293
  this.done();
280
294
  } catch (err) {
281
295
  this.error = err.message || err;
@@ -289,7 +303,7 @@ export default {
289
303
  this.close();
290
304
  },
291
305
  getSpoofedTypes(resources) {
292
- const uniqueResourceTypes = uniq(this.toRemove.map(resource => resource.type));
306
+ const uniqueResourceTypes = uniq(this.toRemove.map((resource) => resource.type));
293
307
 
294
308
  return uniqueResourceTypes.filter(this.$store.getters['type-map/isSpoofed']);
295
309
  },
@@ -297,7 +311,7 @@ export default {
297
311
  // If spoofed we need to reload the values as the server can't have watchers for them.
298
312
  refreshSpoofedTypes(types) {
299
313
  const inStore = this.$store.getters['currentProduct'].inStore;
300
- const promises = types.map(type => this.$store.dispatch(`${ inStore }/findAll`, { type, opt: { force: true } }, { root: true }));
314
+ const promises = types.map((type) => this.$store.dispatch(`${ inStore }/findAll`, { type, opt: { force: true } }, { root: true }));
301
315
 
302
316
  return Promise.all(promises);
303
317
  },
@@ -372,32 +386,42 @@ export default {
372
386
  </div>
373
387
  </template>
374
388
  </div>
375
- <input
389
+ <LabeledInput
376
390
  v-if="needsConfirm"
377
391
  id="confirm"
378
392
  v-model="confirmName"
393
+ v-focus
379
394
  :data-testid="componentTestid + '-input'"
380
395
  type="text"
381
396
  >
382
- <div class="text-warning mb-10 mt-10">
383
- {{ warning }}
384
- </div>
385
- <div class="text-error mb-10 mt-10">
386
- {{ error }}
387
- </div>
388
- <div
389
- v-if="!needsConfirm"
390
- class="text-info mt-20"
391
- >
392
- {{ protip }}
393
- </div>
394
- <Checkbox
395
- v-if="chartsToRemoveIsApp"
396
- v-model="chartsDeleteCrd"
397
- label-key="promptRemoveApp.removeCrd"
398
- class="mt-10 type"
399
- @input="chartAddCrdToRemove"
400
- />
397
+ <div class="text-warning mb-10 mt-10">
398
+ {{ warning }}
399
+ </div>
400
+ <div class="text-error mb-10 mt-10">
401
+ {{ error }}
402
+ </div>
403
+ <div
404
+ v-if="!needsConfirm"
405
+ class="text-info mt-20"
406
+ >
407
+ {{ protip }}
408
+ </div>
409
+ <Checkbox
410
+ v-if="chartsToRemoveIsApp"
411
+ v-model="chartsDeleteCrd"
412
+ label-key="promptRemoveApp.removeCrd"
413
+ class="mt-10 type"
414
+ @input="chartAddCrdToRemove"
415
+ />
416
+ </labeledinput>
417
+ <template v-else>
418
+ <div class="text-warning mb-10 mt-10">
419
+ {{ warning }}
420
+ </div>
421
+ <div class="text-error mb-10 mt-10">
422
+ {{ error }}
423
+ </div>
424
+ </template>
401
425
  </div>
402
426
  <template #actions>
403
427
  <button
@@ -70,7 +70,7 @@ export default {
70
70
 
71
71
  clusterSnapshots() {
72
72
  if (this.sortedSnapshots) {
73
- return this.sortedSnapshots.map(snapshot => ({ label: this.snapshotLabel(snapshot), value: snapshot.name }));
73
+ return this.sortedSnapshots.map((snapshot) => ({ label: this.snapshotLabel(snapshot), value: snapshot.name }));
74
74
  } else {
75
75
  return [];
76
76
  }
@@ -115,13 +115,13 @@ export default {
115
115
 
116
116
  if (!cluster.isRke2) {
117
117
  promise = this.$store.dispatch('rancher/findAll', { type: NORMAN.ETCD_BACKUP }).then((snapshots) => {
118
- return snapshots.filter(s => s.clusterId === cluster.metadata.name);
118
+ return snapshots.filter((s) => s.clusterId === cluster.metadata.name);
119
119
  });
120
120
  } else {
121
121
  promise = this.$store.dispatch('management/findAll', { type: SNAPSHOT }).then((snapshots) => {
122
122
  const toRestoreClusterName = cluster?.clusterName || cluster?.metadata?.name;
123
123
 
124
- return snapshots.filter(s => s.clusterName === toRestoreClusterName);
124
+ return snapshots.filter((s) => s.clusterName === toRestoreClusterName);
125
125
  });
126
126
  }
127
127
 
@@ -67,9 +67,9 @@ function migrate(expr) {
67
67
  let out;
68
68
 
69
69
  if ( expr.includes('||') ) {
70
- out = expr.split('||').map(x => migrate(x)).join(' || ');
70
+ out = expr.split('||').map((x) => migrate(x)).join(' || ');
71
71
  } else if ( expr.includes('&&') ) {
72
- out = expr.split('&&').map(x => migrate(x)).join(' && ');
72
+ out = expr.split('&&').map((x) => migrate(x)).join(' && ');
73
73
  } else {
74
74
  const parts = expr.match(/^(.*)(!?=)(.*)$/);
75
75
 
@@ -311,9 +311,9 @@ export default {
311
311
  let result;
312
312
 
313
313
  if ( get(or, 'length') > 1 ) {
314
- result = or.some(showIf => this.calExpression(showIf, allQuestions));
314
+ result = or.some((showIf) => this.calExpression(showIf, allQuestions));
315
315
  } else {
316
- result = and.every(showIf => this.calExpression(showIf, allQuestions));
316
+ result = and.every((showIf) => this.calExpression(showIf, allQuestions));
317
317
  }
318
318
 
319
319
  return result;
@@ -368,7 +368,7 @@ export default {
368
368
  return null;
369
369
  },
370
370
  getAnswer(variable, questions) {
371
- const found = questions.find(q => q.variable === variable);
371
+ const found = questions.find((q) => q.variable === variable);
372
372
 
373
373
  if ( found ) {
374
374
  // Equivalent to finding question.answer in Ember
@@ -22,7 +22,7 @@ export default {
22
22
  WORKLOAD_TYPES.JOB,
23
23
  WORKLOAD_TYPES.STATEFUL_SET
24
24
  ];
25
- const allWorkloadsNested = await Promise.all(types.map(type => this.$store.dispatch('cluster/findAll', { type })));
25
+ const allWorkloadsNested = await Promise.all(types.map((type) => this.$store.dispatch('cluster/findAll', { type })));
26
26
  const allWorkloads = allWorkloadsNested.flat();
27
27
 
28
28
  this.relatedWorkloadRows = allWorkloads.filter(this.filter);
@@ -139,7 +139,7 @@ export default {
139
139
  }
140
140
 
141
141
  // blocked-post means you can post through norman, but not through steve.
142
- if ( this.schema && !this.schema?.collectionMethods.find(x => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
142
+ if ( this.schema && !this.schema?.collectionMethods.find((x) => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
143
143
  return false;
144
144
  }
145
145