@rancher/shell 0.3.0 → 0.3.2

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 (342) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_gauges.scss +1 -1
  4. package/assets/styles/global/_layout.scss +5 -2
  5. package/assets/styles/global/_select.scss +1 -4
  6. package/assets/styles/themes/_dark.scss +5 -4
  7. package/assets/styles/themes/_light.scss +4 -3
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/styles/vendor/vue-select.scss +4 -3
  10. package/assets/translations/en-us.yaml +673 -73
  11. package/assets/translations/zh-hans.yaml +720 -207
  12. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  13. package/cloud-credential/azure.vue +23 -0
  14. package/cloud-credential/harvester.vue +25 -62
  15. package/cloud-credential/pnap.vue +80 -0
  16. package/components/.DS_Store +0 -0
  17. package/components/ActionMenu.vue +28 -7
  18. package/components/AdvancedSection.vue +9 -2
  19. package/components/Alert.vue +2 -2
  20. package/components/ButtonDropdown.vue +0 -2
  21. package/components/ButtonGroup.vue +1 -0
  22. package/components/CollapsibleCard.vue +0 -1
  23. package/components/CruResource.vue +41 -4
  24. package/components/DetailTop.vue +72 -4
  25. package/components/DisableAuthProviderModal.vue +106 -0
  26. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  27. package/components/ExplorerMembers.vue +253 -30
  28. package/components/ExplorerProjectsNamespaces.vue +77 -33
  29. package/components/ExtensionPanel.vue +42 -0
  30. package/components/GrowlManager.vue +3 -3
  31. package/components/IconOrSvg.vue +178 -0
  32. package/components/LogItem.vue +69 -0
  33. package/components/PodSecurityAdmission.vue +302 -0
  34. package/components/PromptModal.vue +1 -0
  35. package/components/ResourceDetail/Masthead.vue +69 -4
  36. package/components/ResourceDetail/index.vue +12 -5
  37. package/components/ResourceList/Masthead.vue +11 -1
  38. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  39. package/components/ResourceList/index.vue +66 -12
  40. package/components/ResourceList/resource-list.config.js +7 -0
  41. package/components/ResourceTable.vue +33 -6
  42. package/components/SimpleBox.vue +1 -1
  43. package/components/SortableTable/THead.vue +21 -14
  44. package/components/SortableTable/filtering.js +1 -1
  45. package/components/SortableTable/index.vue +21 -10
  46. package/components/SortableTable/selection.js +15 -3
  47. package/components/Tabbed/Tab.vue +1 -1
  48. package/components/Tabbed/index.vue +20 -15
  49. package/components/__tests__/.DS_Store +0 -0
  50. package/components/__tests__/AsyncButton.test.ts +140 -0
  51. package/components/__tests__/BackLink.test.ts +33 -0
  52. package/components/__tests__/ButtonGroup.test.ts +124 -0
  53. package/components/__tests__/ClusterBadge.test.ts +32 -0
  54. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  55. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  56. package/components/__tests__/CruResource.test.ts +3 -2
  57. package/components/__tests__/FixedBanner.test.ts +129 -0
  58. package/components/__tests__/GrowlManager.test.ts +147 -0
  59. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  60. package/components/__tests__/PercentageBar.test.ts +32 -0
  61. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  62. package/components/auth/AuthBanner.vue +20 -10
  63. package/components/auth/RoleDetailEdit.vue +26 -17
  64. package/components/auth/SelectPrincipal.vue +36 -5
  65. package/components/form/ArrayList.vue +3 -35
  66. package/components/form/ArrayListGrouped.vue +13 -4
  67. package/components/form/ArrayListSelect.vue +5 -5
  68. package/components/form/Error.vue +8 -0
  69. package/components/form/KeyValue.vue +39 -7
  70. package/components/form/LabeledSelect.vue +5 -2
  71. package/components/form/Labels.vue +46 -16
  72. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  73. package/components/form/Members/MembershipEditor.vue +12 -12
  74. package/components/form/NameNsDescription.vue +1 -1
  75. package/components/form/NodeScheduling.vue +1 -1
  76. package/components/form/Probe.vue +3 -3
  77. package/components/form/ResourceQuota/Project.vue +6 -6
  78. package/components/form/ResourceTabs/index.vue +24 -6
  79. package/components/form/Security.vue +7 -6
  80. package/components/form/Select.vue +3 -2
  81. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  82. package/components/form/ServicePorts.vue +8 -0
  83. package/components/form/WorkloadPorts.vue +7 -1
  84. package/components/form/__tests__/ArrayList.test.ts +74 -0
  85. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  86. package/components/formatter/Checked.vue +1 -1
  87. package/components/formatter/ClusterLink.vue +5 -0
  88. package/components/formatter/IconIsDefault.vue +2 -2
  89. package/components/formatter/InternalExternalIP.vue +11 -8
  90. package/components/formatter/LiveDuration.vue +78 -0
  91. package/components/formatter/WorkloadHealthScale.vue +5 -3
  92. package/components/nav/Header.vue +74 -7
  93. package/components/nav/NamespaceFilter.vue +146 -63
  94. package/components/nav/TopLevelMenu.vue +22 -19
  95. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  96. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  97. package/components/nav/WindowManager/Window.vue +2 -0
  98. package/components/nav/WindowManager/index.vue +10 -0
  99. package/config/elemental-types.js +9 -0
  100. package/config/features.js +2 -0
  101. package/config/home-links.js +4 -1
  102. package/config/pod-security-admission.ts +82 -0
  103. package/config/product/apps.js +1 -1
  104. package/config/product/auth.js +6 -5
  105. package/config/product/backup.js +1 -1
  106. package/config/product/explorer.js +6 -6
  107. package/config/product/fleet.js +1 -1
  108. package/config/product/manager.js +6 -2
  109. package/config/query-params.js +1 -0
  110. package/config/secret.js +0 -1
  111. package/config/settings.ts +26 -9
  112. package/config/table-headers.js +22 -11
  113. package/config/types.js +4 -1
  114. package/config/uiplugins.js +3 -3
  115. package/content/docs/zh-hans/getting-started.md +113 -137
  116. package/content/docs/zh-hans/whats-new.md +8 -46
  117. package/core/plugin-helpers.js +171 -0
  118. package/core/plugin.ts +61 -1
  119. package/core/plugins.js +33 -0
  120. package/core/types.ts +128 -2
  121. package/creators/pkg/package-lock.json +37 -0
  122. package/creators/pkg/package.json +1 -1
  123. package/detail/catalog.cattle.io.app.vue +1 -1
  124. package/detail/pod.vue +1 -1
  125. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  126. package/detail/service.vue +2 -9
  127. package/detail/workload/index.vue +0 -1
  128. package/dialog/AddClusterMemberDialog.vue +22 -28
  129. package/dialog/AddProjectMemberDialog.vue +53 -9
  130. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  131. package/dialog/DrainNode.vue +44 -48
  132. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  133. package/dialog/GenericPrompt.vue +15 -20
  134. package/dialog/RollbackWorkloadDialog.vue +15 -46
  135. package/dialog/RotateCertificatesDialog.vue +5 -7
  136. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  137. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  138. package/dialog/ScaleMachineDownDialog.vue +1 -1
  139. package/dialog/ScalePoolDownDialog.vue +121 -0
  140. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  141. package/edit/auth/azuread.vue +16 -16
  142. package/edit/auth/github.vue +8 -0
  143. package/edit/auth/googleoauth.vue +10 -1
  144. package/edit/auth/ldap/index.vue +10 -0
  145. package/edit/auth/oidc.vue +10 -0
  146. package/edit/auth/saml.vue +10 -0
  147. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  148. package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
  149. package/edit/cloudcredential.vue +3 -7
  150. package/edit/logging-flow/Match.vue +39 -8
  151. package/edit/logging-flow/index.vue +27 -4
  152. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  153. package/edit/management.cattle.io.project.vue +8 -1
  154. package/edit/management.cattle.io.setting.vue +5 -2
  155. package/edit/management.cattle.io.user.vue +7 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +36 -8
  157. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  158. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  159. package/edit/namespace.vue +18 -4
  160. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  161. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  162. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  163. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  164. package/edit/persistentvolume/index.vue +30 -27
  165. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  166. package/edit/persistentvolume/plugins/csi.vue +102 -62
  167. package/edit/persistentvolume/plugins/fc.vue +19 -19
  168. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  169. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  170. package/edit/persistentvolumeclaim.vue +78 -75
  171. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  172. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  173. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  174. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  175. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +96 -0
  176. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  177. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +445 -154
  179. package/edit/secret/index.vue +3 -7
  180. package/edit/service.vue +3 -1
  181. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  182. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  183. package/edit/workload/__tests__/index.test.ts +98 -0
  184. package/edit/workload/index.vue +58 -8
  185. package/edit/workload/mixins/workload.js +107 -70
  186. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  187. package/edit/workload/storage/emptyDir.vue +88 -0
  188. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  189. package/edit/workload/storage/index.vue +8 -0
  190. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  191. package/layouts/default.vue +57 -44
  192. package/list/__tests__/workload.test.ts +5 -2
  193. package/list/catalog.cattle.io.app.vue +1 -0
  194. package/list/cis.cattle.io.clusterscan.vue +1 -0
  195. package/list/fleet.cattle.io.bundle.vue +5 -6
  196. package/list/fleet.cattle.io.cluster.vue +6 -3
  197. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  198. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  199. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  200. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  201. package/list/logging.banzaicloud.io.flow.vue +6 -5
  202. package/list/management.cattle.io.cluster.vue +1 -0
  203. package/list/management.cattle.io.feature.vue +3 -4
  204. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  205. package/list/management.cattle.io.setting.vue +2 -2
  206. package/list/management.cattle.io.user.vue +4 -10
  207. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  208. package/list/node.vue +8 -5
  209. package/list/persistentvolume.vue +3 -3
  210. package/list/persistentvolumeclaim.vue +3 -4
  211. package/list/provisioning.cattle.io.cluster.vue +18 -19
  212. package/list/service.vue +6 -14
  213. package/list/workload.vue +43 -38
  214. package/machine-config/azure.vue +429 -60
  215. package/machine-config/pnap.vue +288 -0
  216. package/mixins/auth-config.js +1 -3
  217. package/mixins/browser-tab-visibility.js +8 -14
  218. package/mixins/chart.js +1 -1
  219. package/mixins/create-edit-view/impl.js +4 -0
  220. package/mixins/create-edit-view/index.js +4 -2
  221. package/mixins/resource-fetch-namespaced.js +98 -0
  222. package/mixins/resource-fetch.js +79 -45
  223. package/mixins/resource-manager.js +1 -23
  224. package/models/apps.controllerrevision.js +7 -0
  225. package/models/apps.daemonset.js +18 -0
  226. package/models/apps.deployment.js +44 -0
  227. package/models/apps.replicaset.js +7 -0
  228. package/models/apps.statefulset.js +18 -0
  229. package/models/batch.job.js +7 -14
  230. package/models/cluster/node.js +10 -2
  231. package/models/cluster.x-k8s.io.machine.js +26 -4
  232. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  233. package/models/event.js +7 -0
  234. package/models/logging.banzaicloud.io.flow.js +4 -0
  235. package/models/management.cattle.io.cluster.js +1 -1
  236. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  237. package/models/management.cattle.io.globalrole.js +2 -2
  238. package/models/management.cattle.io.node.js +37 -2
  239. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  240. package/models/management.cattle.io.project.js +30 -11
  241. package/models/management.cattle.io.setting.js +1 -1
  242. package/models/management.cattle.io.user.js +37 -1
  243. package/models/namespace.js +42 -5
  244. package/models/persistentvolume.js +14 -2
  245. package/models/pod.js +15 -0
  246. package/models/projectroletemplatebinding.js +7 -0
  247. package/models/provisioning.cattle.io.cluster.js +61 -10
  248. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  249. package/models/service.js +14 -13
  250. package/models/storage.k8s.io.storageclass.js +33 -18
  251. package/models/workload.js +38 -7
  252. package/nuxt.config.js +27 -17
  253. package/package.json +7 -7
  254. package/pages/about.vue +14 -2
  255. package/pages/c/_cluster/apps/charts/index.vue +21 -3
  256. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  257. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  258. package/pages/c/_cluster/auth/config/index.vue +8 -6
  259. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  260. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  261. package/pages/c/_cluster/explorer/index.vue +51 -6
  262. package/pages/c/_cluster/longhorn/index.vue +1 -1
  263. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  264. package/pages/c/_cluster/monitoring/index.vue +1 -1
  265. package/pages/c/_cluster/neuvector/index.vue +1 -1
  266. package/pages/c/_cluster/settings/performance.vue +48 -2
  267. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
  268. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
  269. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +42 -2
  270. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
  271. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
  272. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  273. package/pages/c/_cluster/uiplugins/index.vue +42 -3
  274. package/pages/diagnostic.vue +5 -4
  275. package/pages/home.vue +105 -30
  276. package/pages/prefs.vue +23 -12
  277. package/pages/rio/mesh.vue +1 -1
  278. package/pkg/dynamic-importer.lib.js +8 -0
  279. package/pkg/vue.config.js +4 -0
  280. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  281. package/plugins/dashboard-store/actions.js +32 -25
  282. package/plugins/dashboard-store/getters.js +50 -33
  283. package/plugins/dashboard-store/mutations.js +134 -28
  284. package/plugins/dashboard-store/resource-class.js +37 -42
  285. package/plugins/steve/actions.js +30 -0
  286. package/plugins/steve/caches/resourceCache.js +60 -0
  287. package/plugins/steve/getters.js +44 -1
  288. package/plugins/steve/mutations.js +97 -36
  289. package/plugins/steve/resourceWatcher.js +277 -0
  290. package/plugins/steve/schema.utils.js +25 -0
  291. package/plugins/steve/subscribe.js +288 -115
  292. package/plugins/steve/worker/index.js +17 -0
  293. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  294. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  295. package/rancher-components/Card/Card.vue +3 -3
  296. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  297. package/rancher-components/StringList/StringList.test.ts +45 -420
  298. package/rancher-components/StringList/StringList.vue +1 -10
  299. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  300. package/rancher-components/components/Banner/Banner.vue +130 -61
  301. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  302. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  303. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  304. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  305. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  306. package/rancher-components/components/StringList/StringList.vue +21 -15
  307. package/scripts/test-plugins-build.sh +8 -0
  308. package/static/loading-indicator.html +1 -1
  309. package/store/action-menu.js +4 -3
  310. package/store/index.js +54 -3
  311. package/store/plugins.js +0 -17
  312. package/store/pnap.js +128 -0
  313. package/store/prefs.js +4 -2
  314. package/store/type-map.js +81 -13
  315. package/types/pod-security-admission.ts +36 -0
  316. package/types/shell/index.d.ts +497 -396
  317. package/utils/__tests__/object.test.ts +17 -1
  318. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  319. package/utils/async.ts +36 -0
  320. package/utils/color.js +45 -0
  321. package/utils/crypto/browserHashUtils.js +18 -0
  322. package/utils/dynamic-importer.js +8 -0
  323. package/utils/install-redirect.js +1 -1
  324. package/utils/object.js +24 -0
  325. package/utils/pod-security-admission.ts +39 -0
  326. package/utils/socket.js +61 -24
  327. package/utils/string.js +2 -0
  328. package/utils/svg-filter.js +301 -0
  329. package/utils/time.js +49 -0
  330. package/utils/validators/cidr.js +4 -0
  331. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  332. package/utils/validators/formRules/index.ts +14 -0
  333. package/config/product/harvester-manager.js +0 -162
  334. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  335. package/list/harvesterhci.io.management.cluster.vue +0 -241
  336. package/machine-config/harvester.vue +0 -693
  337. package/models/harvesterhci.io.management.cluster.js +0 -228
  338. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  339. package/rancher-components/Card/Card.test.ts +0 -39
  340. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  341. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  342. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -3,7 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import { RadioGroup } from '@components/Form/Radio';
4
4
  import LabeledSelect from '@shell/components/form/LabeledSelect';
5
5
  import NodeAffinity from '@shell/components/form/NodeAffinity';
6
- import { HARVESTER_NAME as VIRTUAL } from '@shell/config/product/harvester-manager';
6
+ import { HARVESTER_NAME as VIRTUAL } from '@shell/config/features';
7
7
  import { _VIEW } from '@shell/config/query-params';
8
8
  import { isEmpty } from '@shell/utils/object';
9
9
  import { HOSTNAME } from '@shell/config/labels-annotations';
@@ -285,10 +285,10 @@ export default {
285
285
  >
286
286
  <UnitInput
287
287
  v-model="probe.timeoutSeconds"
288
+ min="0"
288
289
  :mode="mode"
289
290
  :suffix="t('suffix.sec')"
290
- :label="t('probe.timeout.placeholder')"
291
- min="0"
291
+ :label="t('probe.timeout.label')"
292
292
  :placeholder="t('probe.timeout.placeholder')"
293
293
  @input="update"
294
294
  />
@@ -322,7 +322,7 @@ export default {
322
322
  min="1"
323
323
  :mode="mode"
324
324
  :label="t('probe.failureThreshold.label')"
325
- :placeholder="t('probe.failureThreshold.label')"
325
+ :placeholder="t('probe.failureThreshold.placeholder')"
326
326
  @input="update"
327
327
  />
328
328
  </div>
@@ -72,12 +72,12 @@ export default {
72
72
  @remove="emitRemove"
73
73
  >
74
74
  <template #columns="props">
75
- <Row
76
- v-model="value"
77
- :mode="mode"
78
- :types="remainingTypes(typeValues[props.i])"
79
- :type="typeValues[props.i]"
80
- @type-change="updateType(props.i, $event)"
75
+ <Row
76
+ v-model="value"
77
+ :mode="mode"
78
+ :types="remainingTypes(typeValues[props.i])"
79
+ :type="typeValues[props.i]"
80
+ @type-change="updateType(props.i, $event)"
81
81
  />
82
82
  </template>
83
83
  </ArrayList>
@@ -11,6 +11,8 @@ import { EVENT } from '@shell/config/types';
11
11
  import SortableTable from '@shell/components/SortableTable';
12
12
  import { _VIEW } from '@shell/config/query-params';
13
13
  import RelatedResources from '@shell/components/RelatedResources';
14
+ import { ExtensionPoint, TabLocation } from '@shell/core/types';
15
+ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
14
16
 
15
17
  export default {
16
18
 
@@ -58,11 +60,6 @@ export default {
58
60
  needRelated: {
59
61
  type: Boolean,
60
62
  default: true
61
- },
62
-
63
- alwaysShowEvents: {
64
- type: Boolean,
65
- default: false
66
63
  }
67
64
  },
68
65
 
@@ -74,6 +71,7 @@ export default {
74
71
  allEvents: [],
75
72
  selectedTab: this.defaultTab,
76
73
  didLoadEvents: false,
74
+ extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.RESOURCE_DETAIL, this.$route),
77
75
  };
78
76
  },
79
77
 
@@ -92,7 +90,7 @@ export default {
92
90
  return false;
93
91
  },
94
92
  showEvents() {
95
- return this.isView && this.needEvents && this.hasEvents && (this.events.length || this.alwaysShowEvents);
93
+ return this.isView && this.needEvents && this.hasEvents;
96
94
  },
97
95
  showRelated() {
98
96
  return this.isView && this.needRelated;
@@ -226,5 +224,25 @@ export default {
226
224
  direction="to"
227
225
  />
228
226
  </Tab>
227
+
228
+ <!-- Extension tabs -->
229
+ <Tab
230
+ v-for="tab, i in extensionTabs"
231
+ :key="`${tab.name}${i}`"
232
+ :name="tab.name"
233
+ :label="tab.label"
234
+ :label-key="tab.labelKey"
235
+ :weight="tab.weight"
236
+ :tooltip="tab.tooltip"
237
+ :show-header="tab.showHeader"
238
+ :display-alert-icon="tab.displayAlertIcon"
239
+ :error="tab.error"
240
+ :badge="tab.badge"
241
+ >
242
+ <component
243
+ :is="tab.component"
244
+ :resource="value"
245
+ />
246
+ </Tab>
229
247
  </Tabbed>
230
248
  </template>
@@ -63,10 +63,10 @@ export default {
63
63
 
64
64
  const {
65
65
  capabilities = {},
66
- runAsRoot = true,
66
+ runAsNonRoot = false,
67
67
  readOnlyRootFilesystem = false,
68
68
  privileged = false,
69
- allowPrivilegeEscalation = true,
69
+ allowPrivilegeEscalation = false,
70
70
  runAsUser
71
71
  } = this.value;
72
72
  const {
@@ -78,7 +78,7 @@ export default {
78
78
  privileged,
79
79
  allowPrivilegeEscalation,
80
80
  allCapabilities,
81
- runAsRoot,
81
+ runAsNonRoot,
82
82
  readOnlyRootFilesystem,
83
83
  add,
84
84
  drop,
@@ -105,7 +105,7 @@ export default {
105
105
  methods: {
106
106
  update() {
107
107
  const securityContext = {
108
- runAsRoot: this.runAsRoot,
108
+ runAsNonRoot: this.runAsNonRoot,
109
109
  readOnlyRootFilesystem: this.readOnlyRootFilesystem,
110
110
  capabilities: { add: this.add, drop: this.drop },
111
111
  privileged: this.privileged,
@@ -115,6 +115,7 @@ export default {
115
115
 
116
116
  this.$emit('input', securityContext);
117
117
  }
118
+
118
119
  }
119
120
  };
120
121
  </script>
@@ -164,13 +165,13 @@ export default {
164
165
  class="col span-6"
165
166
  >
166
167
  <RadioGroup
168
+ v-model="runAsNonRoot"
167
169
  name="runasNonRoot"
168
170
  :label="t('workload.container.security.runAsNonRoot.label')"
169
- :value="!runAsRoot"
170
171
  :options="[false, true]"
171
172
  :labels="[t('workload.container.security.runAsNonRoot.false'), t('workload.container.security.runAsNonRoot.true')]"
172
173
  :mode="mode"
173
- @input="e=>{runAsRoot = !e; update()}"
174
+ @input="update"
174
175
  />
175
176
  </div>
176
177
  <div
@@ -135,7 +135,7 @@ export default {
135
135
  return true;
136
136
  },
137
137
  getOptionKey(opt) {
138
- if (opt.optionKey) {
138
+ if (opt?.optionKey) {
139
139
  return get(opt, opt.optionKey);
140
140
  }
141
141
 
@@ -279,9 +279,10 @@ export default {
279
279
 
280
280
  ::v-deep .vs__selected-options {
281
281
  display: flex;
282
+ margin: 3px;
282
283
 
283
284
  .vs__selected {
284
- width: 100%;
285
+ width: initial;
285
286
  }
286
287
  }
287
288
 
@@ -1,6 +1,5 @@
1
1
  <script>
2
2
  import { _EDIT } from '@shell/config/query-params';
3
- import Loading from '@shell/components/Loading';
4
3
  import { LabeledInput } from '@components/Form/LabeledInput';
5
4
  import LabeledSelect from '@shell/components/form/LabeledSelect';
6
5
  import { AUTH_TYPE, NORMAN, SECRET } from '@shell/config/types';
@@ -13,7 +12,6 @@ export default {
13
12
  name: 'SelectOrCreateAuthSecret',
14
13
 
15
14
  components: {
16
- Loading,
17
15
  LabeledInput,
18
16
  LabeledSelect,
19
17
  },
@@ -131,8 +129,6 @@ export default {
131
129
  } else {
132
130
  this.allSecrets = await this.$store.dispatch(`${ this.inStore }/findAll`, { type: SECRET });
133
131
  }
134
- } else {
135
- this.allSecrets = [];
136
132
  }
137
133
 
138
134
  if ( this.allowS3 && this.$store.getters['rancher/canList'](NORMAN.CLOUD_CREDENTIAL) ) {
@@ -170,10 +166,10 @@ export default {
170
166
  this.update();
171
167
  },
172
168
 
173
- data() {
169
+ data(props) {
174
170
  return {
175
- allCloudCreds: null,
176
- allSecrets: null,
171
+ allCloudCreds: [],
172
+ allSecrets: [],
177
173
  selected: null,
178
174
 
179
175
  publicKey: '',
@@ -279,11 +275,26 @@ export default {
279
275
  disabled: true
280
276
  });
281
277
  }
278
+ if ( this.allowNone ) {
279
+ out.unshift({
280
+ label: this.t('generic.none'),
281
+ value: AUTH_TYPE._NONE,
282
+ });
283
+ }
284
+
285
+ if (this.allowSsh || this.allowS3 || this.allowBasic) {
286
+ out.unshift({
287
+ label: 'divider',
288
+ disabled: true,
289
+ kind: 'divider'
290
+ });
291
+ }
282
292
 
283
293
  if ( this.allowSsh ) {
284
294
  out.unshift({
285
295
  label: this.t('selectOrCreateAuthSecret.createSsh'),
286
296
  value: AUTH_TYPE._SSH,
297
+ kind: 'highlighted'
287
298
  });
288
299
  }
289
300
 
@@ -291,6 +302,7 @@ export default {
291
302
  out.unshift({
292
303
  label: this.t('selectOrCreateAuthSecret.createS3'),
293
304
  value: AUTH_TYPE._S3,
305
+ kind: 'highlighted'
294
306
  });
295
307
  }
296
308
 
@@ -298,13 +310,7 @@ export default {
298
310
  out.unshift({
299
311
  label: this.t('selectOrCreateAuthSecret.createBasic'),
300
312
  value: AUTH_TYPE._BASIC,
301
- });
302
- }
303
-
304
- if ( this.allowNone ) {
305
- out.unshift({
306
- label: this.t('generic.none'),
307
- value: AUTH_TYPE._NONE,
313
+ kind: 'highlighted'
308
314
  });
309
315
  }
310
316
 
@@ -455,9 +461,7 @@ export default {
455
461
  </script>
456
462
 
457
463
  <template>
458
- <Loading v-if="$fetchState.pending" />
459
464
  <div
460
- v-else
461
465
  class="select-or-create-auth-secret"
462
466
  >
463
467
  <div
@@ -469,21 +473,10 @@ export default {
469
473
  v-model="selected"
470
474
  :mode="mode"
471
475
  :label-key="labelKey"
476
+ :loading="$fetchState.pending"
472
477
  :options="options"
473
478
  :selectable="option => !option.disabled"
474
- >
475
- <template v-slot:option="opt">
476
- <template v-if="opt.kind === 'divider'">
477
- <hr>
478
- </template>
479
- <template v-else-if="opt.kind === 'title'">
480
- {{ opt.label }}
481
- </template>
482
- <template v-else>
483
- {{ opt.label }}
484
- </template>
485
- </template>
486
- </LabeledSelect>
479
+ />
487
480
  </div>
488
481
  <template v-if="selected === _SSH">
489
482
  <div :class="moreCols">
@@ -136,6 +136,10 @@ export default {
136
136
  </span>
137
137
  <span class="port">
138
138
  <t k="servicePorts.rules.listening.label" />
139
+ <i
140
+ v-tooltip="t('servicesPage.listeningPorts')"
141
+ class="icon icon-info flex"
142
+ />
139
143
  <span class="text-error">*</span>
140
144
  </span>
141
145
  <span
@@ -146,6 +150,10 @@ export default {
146
150
  </span>
147
151
  <span class="target-port">
148
152
  <t k="servicePorts.rules.target.label" />
153
+ <i
154
+ v-tooltip="t('servicesPage.targetPorts')"
155
+ class="icon icon-info flex"
156
+ />
149
157
  <span class="text-error">*</span>
150
158
 
151
159
  </span>
@@ -8,7 +8,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
8
8
  import LabeledSelect from '@shell/components/form/LabeledSelect';
9
9
  import { HCI as HCI_LABELS_ANNOTATIONS } from '@shell/config/labels-annotations';
10
10
  import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
11
- import { HARVESTER_NAME as HARVESTER } from '@shell/config/product/harvester-manager';
11
+ import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
12
12
  import { CAPI, SERVICE } from '@shell/config/types';
13
13
 
14
14
  export default {
@@ -259,6 +259,12 @@ export default {
259
259
 
260
260
  <template>
261
261
  <div :style="{'width':'100%'}">
262
+ <p
263
+ v-if="rows.length > 0"
264
+ class="padded"
265
+ >
266
+ {{ t('workload.container.ports.detailedDescription') }}
267
+ </p>
262
268
  <div
263
269
  v-for="(row, idx) in rows"
264
270
  :key="idx"
@@ -0,0 +1,74 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import ArrayList from '@shell/components/form/ArrayList.vue';
3
+ import { _EDIT, _VIEW } from '@shell/config/query-params';
4
+
5
+ describe('the ArrayList', () => {
6
+ it('is empty', () => {
7
+ const wrapper = mount(ArrayList, {
8
+ propsData: {
9
+ value: [],
10
+ mode: _EDIT
11
+ },
12
+ });
13
+ const elements = wrapper.findAll('[data-testid^="array-list-box"]');
14
+
15
+ expect(elements).toHaveLength(0);
16
+ });
17
+
18
+ it('shows an initial empty row', () => {
19
+ const wrapper = mount(ArrayList, {
20
+ propsData: {
21
+ value: [],
22
+ mode: _EDIT,
23
+ initialEmptyRow: true
24
+ },
25
+ });
26
+ const arrayListBoxes = wrapper.findAll('[data-testid="array-list-box"]');
27
+
28
+ expect(arrayListBoxes).toHaveLength(1);
29
+ });
30
+
31
+ it('expands when the add button is clicked', async() => {
32
+ const wrapper = mount(ArrayList, {
33
+ propsData: {
34
+ value: [],
35
+ mode: _EDIT,
36
+ },
37
+ });
38
+
39
+ const arrayListButton = wrapper.find('[data-testid="array-list-button"]').element as HTMLElement;
40
+
41
+ await arrayListButton.click();
42
+ await arrayListButton.click();
43
+ const arrayListBoxes = wrapper.findAll('[data-testid="array-list-box"]');
44
+
45
+ expect(arrayListBoxes).toHaveLength(2);
46
+ });
47
+
48
+ it('contracts when a delete button is clicked', async() => {
49
+ const wrapper = mount(ArrayList, {
50
+ propsData: {
51
+ value: ['string 1', 'string 2'],
52
+ mode: _EDIT,
53
+ },
54
+ });
55
+ const deleteButton = wrapper.get('[data-testid^="remove-item"]').element as HTMLElement;
56
+
57
+ await deleteButton.click();
58
+ const arrayListBoxes = wrapper.findAll('[data-testid="array-list-box"]');
59
+
60
+ expect(arrayListBoxes).toHaveLength(1);
61
+ });
62
+
63
+ it('add button is hidden in read-only mode', () => {
64
+ const wrapper = mount(ArrayList, {
65
+ propsData: {
66
+ value: ['read-only example'],
67
+ mode: _VIEW,
68
+ },
69
+ });
70
+ const arrayListButtons = wrapper.findAll('[data-testid="array-list-button"]');
71
+
72
+ expect(arrayListButtons).toHaveLength(0);
73
+ });
74
+ });
@@ -4,7 +4,7 @@ import ArrayListGrouped from '@shell/components/form/ArrayListGrouped.vue';
4
4
  describe('component: ArrayListGrouped', () => {
5
5
  it('should display enabled add button', () => {
6
6
  const wrapper = mount(ArrayListGrouped);
7
- const button = wrapper.find('[data-testid^="add-item"]').element as HTMLInputElement;
7
+ const button = wrapper.find('[data-testid="array-list-button"]').element as HTMLButtonElement;
8
8
 
9
9
  expect(button.disabled).toBe(false);
10
10
  });
@@ -14,7 +14,7 @@ describe('component: ArrayListGrouped', () => {
14
14
  mocks: { propsData: { value: ['a', 'b'] } },
15
15
  slots: { default: '<div id="test"/>' }
16
16
  });
17
- const button = wrapper.find('[data-testid^="add-item"]');
17
+ const button = wrapper.find('[data-testid^="array-list-button"]');
18
18
 
19
19
  await button.trigger('click');
20
20
  await button.trigger('click');
@@ -28,12 +28,14 @@ describe('component: ArrayListGrouped', () => {
28
28
  mocks: { propsData: { value: ['a', 'b'] } },
29
29
  slots: { default: '<div id="test"/>' }
30
30
  });
31
+ const button = wrapper.find('[data-testid^="array-list-button"]');
31
32
 
32
- await wrapper.find('[data-testid^="add-item"]').trigger('click');
33
+ await button.trigger('click');
34
+ await button.trigger('click');
33
35
  await wrapper.find('[data-testid^="remove-item"]').trigger('click');
34
36
 
35
37
  const elements = wrapper.findAll('#test');
36
38
 
37
- expect(elements).toHaveLength(0);
39
+ expect(elements).toHaveLength(1);
38
40
  });
39
41
  });
@@ -12,7 +12,7 @@ export default {
12
12
 
13
13
  <template>
14
14
  <span v-if="value">
15
- <i class="icon icon-lg icon-checkmark" />
15
+ <i class="icon icon-checkmark" />
16
16
  </span>
17
17
  <span
18
18
  v-else
@@ -62,6 +62,11 @@ export default {
62
62
  {{ value }}
63
63
  </n-link>
64
64
  <span v-else>{{ value }}</span>
65
+ <i
66
+ v-if="row.unavailableMachines"
67
+ v-tooltip="row.unavailableMachines"
68
+ class="conditions-alert-icon icon-alert icon"
69
+ />
65
70
  <i
66
71
  v-if="row.rkeTemplateUpgrade"
67
72
  v-tooltip="t('cluster.rkeTemplateUpgrade', { name: row.rkeTemplateUpgrade })"
@@ -23,12 +23,12 @@ export default {
23
23
  <template>
24
24
  <span v-if="row[col.value]">
25
25
  <span>
26
- <i class="icon icon-2x icon-checkmark" />
26
+ <i class="icon icon-checkmark" />
27
27
  </span>
28
28
  </span>
29
29
  <span v-else>
30
30
  <span>
31
- <i class="icon icon-2x icon-x" />
31
+ <i class="icon icon-x" />
32
32
  </span>
33
33
  </span>
34
34
  </template>
@@ -11,8 +11,8 @@ export default {
11
11
  },
12
12
  },
13
13
  computed: {
14
- showBoth() {
15
- return this.row.internalIp !== this.row.externalIp;
14
+ internalSameAsExternal() {
15
+ return this.row.internalIp === this.row.externalIp;
16
16
  },
17
17
  ...mapGetters({ t: 'i18n/t' })
18
18
  },
@@ -35,12 +35,15 @@ export default {
35
35
  />
36
36
  </template>
37
37
  <template v-else>
38
- {{ t('generic.none') }}
38
+ -
39
39
  </template>
40
-
41
- <template v-if="showBoth">
42
- <template v-if="isIp(row.internalIp)">
43
- / {{ row.internalIp }} <CopyToClipboard
40
+ /
41
+ <template>
42
+ <template v-if="internalSameAsExternal && isIp(row.internalIp)">
43
+ {{ t('tableHeaders.internalIpSameAsExternal') }}
44
+ </template>
45
+ <template v-else-if="isIp(row.internalIp)">
46
+ {{ row.internalIp }}<CopyToClipboard
44
47
  label-as="tooltip"
45
48
  :text="row.internalIp"
46
49
  class="icon-btn"
@@ -48,7 +51,7 @@ export default {
48
51
  />
49
52
  </template>
50
53
  <template v-else>
51
- {{ t('generic.none') }}
54
+ -
52
55
  </template>
53
56
  </template>
54
57
  </span>
@@ -0,0 +1,78 @@
1
+ <script>
2
+ import day from 'dayjs';
3
+ import { elapsedTime } from '@shell/utils/time';
4
+
5
+ export default {
6
+ props: {
7
+ value: {
8
+ type: Object,
9
+ default: () => {}
10
+ },
11
+ },
12
+
13
+ mounted() {
14
+ // Set initial value;
15
+ if (this.value.startTime) {
16
+ this.liveUpdate(day());
17
+ }
18
+ },
19
+
20
+ data() {
21
+ return { label: '-' };
22
+ },
23
+
24
+ computed: {
25
+ dayValue() {
26
+ if (!this.value.startTime) {
27
+ return null;
28
+ }
29
+
30
+ return day(this.value.startTime);
31
+ }
32
+ },
33
+
34
+ watch: {
35
+ value() {
36
+ if (this.value.startTime) {
37
+ this.liveUpdate(day());
38
+ }
39
+ }
40
+ },
41
+
42
+ methods: {
43
+ liveUpdate(now) {
44
+ if (!this.dayValue) {
45
+ this.label = '-';
46
+
47
+ return 300;
48
+ }
49
+
50
+ const { label, diff } = this.getDuration(this.dayValue, now);
51
+
52
+ this.label = label;
53
+
54
+ return diff;
55
+ },
56
+ getDuration(value, from) {
57
+ const now = day();
58
+
59
+ from = from || now;
60
+ const seconds = Math.abs(value.diff(now, 'seconds'));
61
+
62
+ return elapsedTime(seconds);
63
+ },
64
+ }
65
+ };
66
+ </script>
67
+
68
+ <template>
69
+ <span v-if="value.staticValue">
70
+ {{ value.staticValue }}
71
+ </span>
72
+ <span
73
+ v-else
74
+ class="live-date"
75
+ >
76
+ {{ label }}
77
+ </span>
78
+ </template>
@@ -261,15 +261,17 @@ $width: 150px;
261
261
  }
262
262
  }
263
263
 
264
+ $icon-width: 21px;
265
+
264
266
  .health {
265
- width: $width - $height; // height is width of icon;
267
+ width: $width - $icon-width;
266
268
  margin-left: 5px;
267
269
  }
268
270
  .icon {
269
- font-size: $height;
270
- width: $height;
271
+ width: $icon-width;
271
272
  color: var(--primary);
272
273
  margin-top: 1px;
274
+ padding: 0 5px 0 3px; // It would be better to display flex here... but the icon looks a pixel off to the right
273
275
  }
274
276
  }
275
277