@rancher/shell 3.0.4 → 3.0.5-rc.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 (270) hide show
  1. package/assets/images/providers/sks.svg +1 -0
  2. package/assets/styles/base/_basic.scss +6 -0
  3. package/assets/styles/base/_helpers.scss +4 -0
  4. package/assets/styles/base/_variables.scss +1 -0
  5. package/assets/styles/global/_button.scss +1 -0
  6. package/assets/translations/en-us.yaml +65 -15
  7. package/assets/translations/zh-hans.yaml +4 -3
  8. package/chart/monitoring/index.vue +3 -1
  9. package/cloud-credential/aws.vue +2 -0
  10. package/components/ActionDropdownShell.vue +71 -0
  11. package/components/AppModal.vue +18 -4
  12. package/components/AsyncButton.vue +24 -7
  13. package/components/BannerGraphic.vue +1 -0
  14. package/components/CommunityLinks.vue +4 -59
  15. package/components/CopyToClipboardText.vue +2 -1
  16. package/components/CruResource.vue +6 -1
  17. package/components/DetailText.vue +5 -0
  18. package/components/ExplorerMembers.vue +1 -1
  19. package/components/ExplorerProjectsNamespaces.vue +68 -18
  20. package/components/GlobalRoleBindings.vue +5 -1
  21. package/components/GrowlManager.vue +1 -0
  22. package/components/LandingPagePreference.vue +7 -3
  23. package/components/LocaleSelector.vue +39 -95
  24. package/components/ModalManager.vue +55 -0
  25. package/components/ModalWithCard.vue +1 -0
  26. package/components/PromptModal.vue +47 -8
  27. package/components/PromptRemove.vue +1 -0
  28. package/components/PromptRestore.vue +1 -0
  29. package/components/ResourceCancelModal.vue +1 -0
  30. package/components/ResourceDetail/Masthead.vue +38 -12
  31. package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
  32. package/components/ResourceDetail/index.vue +47 -12
  33. package/components/ResourceTable.vue +54 -19
  34. package/components/SideNav.vue +5 -1
  35. package/components/SlideInPanelManager.vue +126 -0
  36. package/components/SortableTable/THead.vue +5 -2
  37. package/components/SortableTable/actions.js +1 -1
  38. package/components/SortableTable/index.vue +64 -51
  39. package/components/SortableTable/paging.js +16 -19
  40. package/components/SortableTable/selection.js +0 -11
  41. package/components/Wizard.vue +2 -2
  42. package/components/__tests__/AsyncButton.test.ts +2 -2
  43. package/components/__tests__/ModalManager.spec.ts +176 -0
  44. package/components/__tests__/PromptModal.test.ts +148 -0
  45. package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
  46. package/components/auth/AuthBanner.vue +13 -11
  47. package/components/auth/Principal.vue +1 -0
  48. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  49. package/components/auth/login/ldap.vue +1 -1
  50. package/components/fleet/FleetResources.vue +21 -6
  51. package/components/form/ArrayList.vue +76 -60
  52. package/components/form/BannerSettings.vue +17 -2
  53. package/components/form/ColorInput.vue +35 -6
  54. package/components/form/Command.vue +6 -15
  55. package/components/form/EnvVars.vue +16 -8
  56. package/components/form/HealthCheck.vue +3 -3
  57. package/components/form/HookOption.vue +11 -16
  58. package/components/form/LabeledSelect.vue +18 -22
  59. package/components/form/LifecycleHooks.vue +3 -3
  60. package/components/form/MatchExpressions.vue +14 -8
  61. package/components/form/NameNsDescription.vue +128 -104
  62. package/components/form/Networking.vue +20 -12
  63. package/components/form/NodeAffinity.vue +31 -23
  64. package/components/form/NodeScheduling.vue +13 -3
  65. package/components/form/NotificationSettings.vue +15 -1
  66. package/components/form/Password.vue +1 -0
  67. package/components/form/PodAffinity.vue +43 -43
  68. package/components/form/Probe.vue +68 -66
  69. package/components/form/ResourceQuota/Project.vue +5 -1
  70. package/components/form/ResourceSelector.vue +7 -9
  71. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +16 -24
  72. package/components/form/SSHKnownHosts/index.vue +30 -13
  73. package/components/form/Security.vue +54 -56
  74. package/components/form/Select.vue +32 -21
  75. package/components/form/ShellInput.vue +5 -1
  76. package/components/form/Tolerations.vue +5 -1
  77. package/components/form/ValueFromResource.vue +134 -121
  78. package/components/form/WorkloadPorts.vue +18 -18
  79. package/components/form/__tests__/ArrayList.test.ts +5 -2
  80. package/components/form/__tests__/ColorInput.test.ts +35 -0
  81. package/components/form/__tests__/LabeledSelect.test.ts +40 -0
  82. package/components/form/__tests__/MatchExpressions.test.ts +12 -12
  83. package/components/form/__tests__/NameNsDescription.test.ts +115 -14
  84. package/components/form/__tests__/Probe.test.ts +12 -8
  85. package/components/form/__tests__/SSHKnownHosts.test.ts +22 -2
  86. package/components/form/__tests__/Select.test.ts +37 -0
  87. package/components/formatter/InternalExternalIP.vue +2 -0
  88. package/components/formatter/SecretData.vue +20 -7
  89. package/components/nav/Group.vue +27 -5
  90. package/components/nav/Header.vue +17 -43
  91. package/components/nav/NamespaceFilter.vue +134 -86
  92. package/components/nav/TopLevelMenu.vue +4 -5
  93. package/components/nav/Type.vue +12 -1
  94. package/components/nav/WindowManager/ContainerLogs.vue +87 -61
  95. package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
  96. package/components/templates/blank.vue +4 -1
  97. package/components/templates/default.vue +8 -3
  98. package/components/templates/home.vue +10 -1
  99. package/components/templates/plain.vue +10 -4
  100. package/composables/focusTrap.ts +12 -4
  101. package/composables/useRuntimeFlag.ts +29 -0
  102. package/config/router/routes.js +20 -13
  103. package/config/store.js +4 -0
  104. package/config/uiplugins.js +5 -1
  105. package/core/types.ts +12 -6
  106. package/detail/catalog.cattle.io.app.vue +6 -1
  107. package/detail/fleet.cattle.io.bundle.vue +70 -6
  108. package/detail/fleet.cattle.io.gitrepo.vue +1 -1
  109. package/detail/namespace.vue +0 -3
  110. package/detail/node.vue +17 -13
  111. package/detail/provisioning.cattle.io.cluster.vue +72 -6
  112. package/dialog/AddCustomBadgeDialog.vue +1 -1
  113. package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
  114. package/{components/AssignTo.vue → dialog/AssignToDialog.vue} +71 -80
  115. package/dialog/ChangePasswordDialog.vue +106 -0
  116. package/dialog/DeactivateDriverDialog.vue +1 -0
  117. package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
  118. package/dialog/DisableAuthProviderDialog.vue +101 -0
  119. package/dialog/DrainNode.vue +1 -1
  120. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
  121. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +69 -57
  122. package/dialog/FeatureFlagListDialog.vue +288 -0
  123. package/dialog/ForceMachineRemoveDialog.vue +5 -2
  124. package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
  125. package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
  126. package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -59
  127. package/dialog/MoveNamespaceDialog.vue +157 -0
  128. package/dialog/ScalePoolDownDialog.vue +1 -1
  129. package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
  130. package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
  131. package/dialog/WechatDialog.vue +57 -0
  132. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
  133. package/edit/auth/__tests__/oidc.test.ts +152 -109
  134. package/edit/auth/azuread.vue +2 -1
  135. package/edit/auth/github.vue +1 -1
  136. package/edit/auth/googleoauth.vue +5 -1
  137. package/edit/auth/ldap/index.vue +1 -1
  138. package/edit/auth/oidc.vue +38 -5
  139. package/edit/auth/saml.vue +1 -1
  140. package/edit/cloudcredential.vue +24 -9
  141. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
  142. package/edit/management.cattle.io.user.vue +28 -3
  143. package/edit/namespace.vue +1 -4
  144. package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
  145. package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
  146. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
  147. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
  148. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
  149. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
  150. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
  151. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
  152. package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
  153. package/edit/provisioning.cattle.io.cluster/rke2.vue +49 -41
  154. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
  155. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
  156. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
  157. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
  158. package/edit/token.vue +2 -0
  159. package/edit/workload/index.vue +1 -0
  160. package/edit/workload/mixins/workload.js +0 -2
  161. package/initialize/install-plugins.js +2 -1
  162. package/list/harvesterhci.io.management.cluster.vue +4 -1
  163. package/list/management.cattle.io.feature.vue +4 -287
  164. package/list/provisioning.cattle.io.cluster.vue +20 -12
  165. package/machine-config/azure.vue +16 -4
  166. package/mixins/vue-select-overrides.js +0 -4
  167. package/models/__tests__/namespace.test.ts +25 -1
  168. package/models/cloudcredential.js +5 -0
  169. package/models/fleet.cattle.io.cluster.js +8 -2
  170. package/models/fleet.cattle.io.gitrepo.js +8 -34
  171. package/models/kontainerdriver.js +6 -3
  172. package/models/management.cattle.io.feature.js +7 -1
  173. package/models/management.cattle.io.node.js +3 -3
  174. package/models/namespace.js +11 -6
  175. package/models/nodedriver.js +6 -3
  176. package/models/workload.js +4 -1
  177. package/package.json +3 -3
  178. package/pages/about.vue +13 -3
  179. package/pages/account/index.vue +16 -6
  180. package/pages/auth/login.vue +18 -7
  181. package/pages/auth/logout.vue +4 -1
  182. package/pages/auth/setup.vue +2 -0
  183. package/pages/auth/verify.vue +13 -8
  184. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  185. package/pages/c/_cluster/apps/charts/install.vue +26 -26
  186. package/pages/c/_cluster/auth/config/index.vue +10 -12
  187. package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
  188. package/pages/c/_cluster/explorer/index.vue +17 -15
  189. package/pages/c/_cluster/istio/index.vue +2 -2
  190. package/pages/c/_cluster/longhorn/index.vue +1 -1
  191. package/pages/c/_cluster/monitoring/index.vue +1 -1
  192. package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
  193. package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
  194. package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
  195. package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
  196. package/pages/c/_cluster/neuvector/index.vue +1 -1
  197. package/pages/c/_cluster/settings/banners.vue +4 -3
  198. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
  199. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
  200. package/pages/c/_cluster/uiplugins/index.vue +98 -55
  201. package/pages/diagnostic.vue +59 -11
  202. package/pages/fail-whale.vue +14 -8
  203. package/pages/home.vue +24 -18
  204. package/pages/prefs.vue +7 -6
  205. package/pages/support/index.vue +4 -1
  206. package/plugins/internal-api/index.ts +37 -0
  207. package/plugins/internal-api/shared/base-api.ts +13 -0
  208. package/plugins/internal-api/shell/shell.api.ts +108 -0
  209. package/plugins/steve/actions.js +0 -12
  210. package/public/index.html +1 -0
  211. package/rancher-components/Card/Card.vue +1 -1
  212. package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
  213. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
  214. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +47 -0
  215. package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
  216. package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
  217. package/rancher-components/Form/Radio/RadioButton.vue +20 -4
  218. package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
  219. package/rancher-components/Form/Radio/RadioGroup.vue +52 -10
  220. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
  221. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +5 -0
  222. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
  223. package/rancher-components/RcButton/RcButton.vue +2 -1
  224. package/rancher-components/RcButton/types.ts +1 -0
  225. package/rancher-components/RcDropdown/RcDropdown.vue +18 -6
  226. package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
  227. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
  228. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
  229. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
  230. package/rancher-components/RcDropdown/index.ts +2 -0
  231. package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
  232. package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
  233. package/rancher-components/RcDropdown/useDropdownItem.ts +63 -0
  234. package/scripts/extension/bundle +20 -0
  235. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
  236. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  237. package/scripts/extension/helmpatch +44 -31
  238. package/scripts/extension/publish +12 -12
  239. package/scripts/typegen.sh +2 -4
  240. package/server/har-file.js +25 -3
  241. package/store/action-menu.js +26 -56
  242. package/store/features.js +2 -1
  243. package/store/index.js +5 -0
  244. package/store/modal.ts +71 -0
  245. package/store/slideInPanel.ts +47 -0
  246. package/store/type-map.js +12 -1
  247. package/store/type-map.utils.ts +4 -4
  248. package/types/global-vue.d.ts +5 -0
  249. package/types/internal-api/shell/growl.d.ts +25 -0
  250. package/types/internal-api/shell/modal.d.ts +77 -0
  251. package/types/internal-api/shell/slideIn.d.ts +15 -0
  252. package/types/resources/fleet.d.ts +0 -14
  253. package/types/shell/index.d.ts +43 -24
  254. package/types/vue-shim.d.ts +4 -1
  255. package/utils/__mocks__/tabbable.js +13 -0
  256. package/utils/__tests__/object.test.ts +38 -4
  257. package/utils/cluster.js +35 -0
  258. package/utils/fleet.ts +15 -73
  259. package/utils/object.js +48 -5
  260. package/utils/validators/formRules/__tests__/index.test.ts +10 -1
  261. package/utils/validators/formRules/index.ts +27 -3
  262. package/utils/validators/machine-pool.ts +20 -0
  263. package/components/DisableAuthProviderModal.vue +0 -114
  264. package/components/MoveModal.vue +0 -166
  265. package/components/PromptChangePassword.vue +0 -123
  266. package/components/fleet/FleetBundleResources.vue +0 -86
  267. package/components/formatter/ExtensionCache.vue +0 -74
  268. package/components/formatter/Port.vue +0 -24
  269. package/components/formatter/SecretType.vue +0 -41
  270. package/types/vue-shim.d +0 -20
@@ -29,6 +29,20 @@ export default {
29
29
 
30
30
  data() {
31
31
  const t = this.$store.getters['i18n/t'];
32
+
33
+ return {
34
+ dnsPolicy: this.value.dnsPolicy || 'ClusterFirst',
35
+ networkMode: this.value.hostNetwork ? { label: t('workload.networking.networkMode.options.hostNetwork'), value: true } : { label: t('workload.networking.networkMode.options.normal'), value: false },
36
+ hostAliases: [],
37
+ nameservers: null,
38
+ searches: null,
39
+ hostname: null,
40
+ subdomain: null,
41
+ options: null,
42
+ };
43
+ },
44
+
45
+ created() {
32
46
  const hostAliases = (this.value.hostAliases || []).map((entry) => {
33
47
  return {
34
48
  ip: entry.ip,
@@ -38,18 +52,12 @@ export default {
38
52
  const { dnsConfig = {}, hostname, subdomain } = this.value;
39
53
  const { nameservers, searches, options } = dnsConfig;
40
54
 
41
- const out = {
42
- dnsPolicy: this.value.dnsPolicy || 'ClusterFirst',
43
- networkMode: this.value.hostNetwork ? { label: t('workload.networking.networkMode.options.hostNetwork'), value: true } : { label: t('workload.networking.networkMode.options.normal'), value: false },
44
- hostAliases,
45
- nameservers,
46
- searches,
47
- hostname,
48
- subdomain,
49
- options
50
- };
51
-
52
- return out;
55
+ this.hostAliases = hostAliases;
56
+ this.nameservers = nameservers;
57
+ this.searches = searches;
58
+ this.hostname = hostname;
59
+ this.subdomain = subdomain;
60
+ this.options = options;
53
61
  },
54
62
 
55
63
  computed: {
@@ -42,31 +42,18 @@ export default {
42
42
  data() {
43
43
  // VolumeNodeAffinity only has 'required' field
44
44
  if (this.value.required) {
45
- return { nodeSelectorTerms: this.value.required.nodeSelectorTerms };
46
45
  } else {
47
- const { preferredDuringSchedulingIgnoredDuringExecution = [], requiredDuringSchedulingIgnoredDuringExecution = {} } = this.value;
48
- const { nodeSelectorTerms = [] } = requiredDuringSchedulingIgnoredDuringExecution;
49
- const allSelectorTerms = [...preferredDuringSchedulingIgnoredDuringExecution, ...nodeSelectorTerms].map((term) => {
50
- const neu = clone(term);
51
-
52
- neu._id = randomStr(4);
53
- if (term.preference) {
54
- Object.assign(neu, term.preference);
55
- delete neu.preference;
56
- }
57
-
58
- return neu;
59
- });
60
-
61
- return {
62
- allSelectorTerms,
63
- weightedNodeSelectorTerms: preferredDuringSchedulingIgnoredDuringExecution,
64
- defaultWeight: 1,
65
- // rules in MatchExpressions.vue can not catch changes what happens on parent component
66
- // we need re-render it via key changing
67
- rerenderNums: randomStr(4)
68
- };
69
46
  }
47
+
48
+ return {
49
+ nodeSelectorTerms: null,
50
+ allSelectorTerms: null,
51
+ weightedNodeSelectorTerms: null,
52
+ defaultWeight: 1,
53
+ // rules in MatchExpressions.vue can not catch changes what happens on parent component
54
+ // we need re-render it via key changing
55
+ rerenderNums: randomStr(4)
56
+ };
70
57
  },
71
58
 
72
59
  computed: {
@@ -88,6 +75,27 @@ export default {
88
75
  },
89
76
 
90
77
  created() {
78
+ if (this.value.required) {
79
+ this.nodeSelectorTerms = this.value.required.nodeSelectorTerms;
80
+ } else {
81
+ const { preferredDuringSchedulingIgnoredDuringExecution = [], requiredDuringSchedulingIgnoredDuringExecution = {} } = this.value;
82
+ const { nodeSelectorTerms = [] } = requiredDuringSchedulingIgnoredDuringExecution;
83
+ const allSelectorTerms = [...preferredDuringSchedulingIgnoredDuringExecution, ...nodeSelectorTerms].map((term) => {
84
+ const neu = clone(term);
85
+
86
+ neu._id = randomStr(4);
87
+ if (term.preference) {
88
+ Object.assign(neu, term.preference);
89
+ delete neu.preference;
90
+ }
91
+
92
+ return neu;
93
+ });
94
+
95
+ this.allSelectorTerms = allSelectorTerms;
96
+ this.weightedNodeSelectorTerms = preferredDuringSchedulingIgnoredDuringExecution;
97
+ }
98
+
91
99
  this.queueUpdate = debounce(this.update, 500);
92
100
  },
93
101
 
@@ -40,6 +40,15 @@ export default {
40
40
  },
41
41
 
42
42
  data() {
43
+ return {
44
+ selectNode: null,
45
+ nodeName: '',
46
+ nodeAffinity: {},
47
+ nodeSelector: {},
48
+ };
49
+ },
50
+
51
+ created() {
43
52
  const isHarvester = this.$store.getters['currentProduct'].inStore === VIRTUAL;
44
53
 
45
54
  let { nodeName = '' } = this.value;
@@ -65,9 +74,10 @@ export default {
65
74
  nodeAffinity['preferredDuringSchedulingIgnoredDuringExecution'] = [];
66
75
  }
67
76
 
68
- return {
69
- selectNode, nodeName, nodeAffinity, nodeSelector
70
- };
77
+ this.selectNode = selectNode;
78
+ this.nodeName = nodeName;
79
+ this.nodeAffinity = nodeAffinity;
80
+ this.nodeSelector = nodeSelector;
71
81
  },
72
82
 
73
83
  computed: {
@@ -21,7 +21,12 @@ export default ({
21
21
  return [_EDIT, _VIEW].includes(value);
22
22
  },
23
23
  default: _EDIT,
24
- }
24
+ },
25
+
26
+ hiddenAriaDescribedLabel: {
27
+ type: String,
28
+ default: ''
29
+ },
25
30
  },
26
31
 
27
32
  });
@@ -29,12 +34,20 @@ export default ({
29
34
 
30
35
  <template>
31
36
  <div>
37
+ <p
38
+ v-if="hiddenAriaDescribedLabel"
39
+ id="hidden-label-notification-settings"
40
+ class="sr-only"
41
+ >
42
+ {{ hiddenAriaDescribedLabel }}
43
+ </p>
32
44
  <div class="row mb-20">
33
45
  <div class="col span-6">
34
46
  <Checkbox
35
47
  :mode="mode"
36
48
  :value="value.showMessage === 'true'"
37
49
  :label="t('notifications.loginError.showCheckboxLabel')"
50
+ aria-describedby="hidden-label-notification-settings"
38
51
  @update:value="value.showMessage = $event.toString()"
39
52
  />
40
53
  </div>
@@ -48,6 +61,7 @@ export default ({
48
61
  :mode="mode"
49
62
  :disabled="value.showMessage === 'false'"
50
63
  :label="t('notifications.loginError.messageLabel')"
64
+ aria-describedby="hidden-label-notification-settings"
51
65
  />
52
66
  </div>
53
67
  </div>
@@ -137,6 +137,7 @@ export default {
137
137
  tabindex="0"
138
138
  class="hide-show"
139
139
  role="button"
140
+ :aria-label="reveal ? t('action.ariaLabel.hidePass', { area: label }) : t('action.ariaLabel.showPass', { area: label })"
140
141
  @click.prevent.stop="hideShowFn"
141
142
  @keyup.space.prevent.stop="hideShowFn"
142
143
  >
@@ -84,53 +84,14 @@ export default {
84
84
  },
85
85
 
86
86
  data() {
87
- if (!this.value[this.field]) {
88
- this.value[this.field] = {};
89
- }
90
- const { podAffinity = {}, podAntiAffinity = {} } = this.value[this.field];
91
- const allAffinityTerms = [...(podAffinity.preferredDuringSchedulingIgnoredDuringExecution || []), ...(podAffinity.requiredDuringSchedulingIgnoredDuringExecution || [])].map((term) => {
92
- let out = clone(term);
93
-
94
- out._id = randomStr(4);
95
- out._anti = false;
96
- if (term.podAffinityTerm) {
97
- Object.assign(out, term.podAffinityTerm);
98
- out = this.parsePodAffinityTerm(out);
99
-
100
- delete out.podAffinityTerm;
101
- } else {
102
- out = this.parsePodAffinityTerm(out);
103
- }
104
-
105
- return out;
106
- });
107
- const allAntiTerms = [...(podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution || []), ...(podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution || [])].map((term) => {
108
- let out = clone(term);
109
-
110
- out._id = randomStr(4);
111
- out._anti = true;
112
- if (term.podAffinityTerm) {
113
- Object.assign(out, term.podAffinityTerm);
114
- out = this.parsePodAffinityTerm(out);
115
-
116
- delete out.podAffinityTerm;
117
- } else {
118
- out = this.parsePodAffinityTerm(out);
119
- }
120
-
121
- return out;
122
- });
123
-
124
- const allSelectorTerms = [...allAffinityTerms, ...allAntiTerms];
125
-
126
87
  return {
127
- allSelectorTerms,
128
- defaultWeight: 1,
88
+ allSelectorTerms: [],
89
+ defaultWeight: 1,
129
90
  // rules in MatchExpressions.vue can not catch changes what happens on parent component
130
91
  // we need re-render it via key changing
131
- rerenderNums: randomStr(4),
92
+ rerenderNums: randomStr(4),
132
93
  NAMESPACE_SELECTION_OPTION_VALUES,
133
- defaultAddValue: {
94
+ defaultAddValue: {
134
95
  _namespaceOption: NAMESPACE_SELECTION_OPTION_VALUES.POD,
135
96
  matchExpressions: [],
136
97
  namespaces: null,
@@ -138,6 +99,7 @@ export default {
138
99
  }
139
100
  };
140
101
  },
102
+
141
103
  computed: {
142
104
  ...mapGetters({ t: 'i18n/t' }),
143
105
  isView() {
@@ -226,6 +188,44 @@ export default {
226
188
  },
227
189
 
228
190
  created() {
191
+ if (!this.value[this.field]) {
192
+ this.value[this.field] = {};
193
+ }
194
+ const { podAffinity = {}, podAntiAffinity = {} } = this.value[this.field];
195
+ const allAffinityTerms = [...(podAffinity.preferredDuringSchedulingIgnoredDuringExecution || []), ...(podAffinity.requiredDuringSchedulingIgnoredDuringExecution || [])].map((term) => {
196
+ let out = clone(term);
197
+
198
+ out._id = randomStr(4);
199
+ out._anti = false;
200
+ if (term.podAffinityTerm) {
201
+ Object.assign(out, term.podAffinityTerm);
202
+ out = this.parsePodAffinityTerm(out);
203
+
204
+ delete out.podAffinityTerm;
205
+ } else {
206
+ out = this.parsePodAffinityTerm(out);
207
+ }
208
+
209
+ return out;
210
+ });
211
+ const allAntiTerms = [...(podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution || []), ...(podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution || [])].map((term) => {
212
+ let out = clone(term);
213
+
214
+ out._id = randomStr(4);
215
+ out._anti = true;
216
+ if (term.podAffinityTerm) {
217
+ Object.assign(out, term.podAffinityTerm);
218
+ out = this.parsePodAffinityTerm(out);
219
+
220
+ delete out.podAffinityTerm;
221
+ } else {
222
+ out = this.parsePodAffinityTerm(out);
223
+ }
224
+
225
+ return out;
226
+ });
227
+
228
+ this.allSelectorTerms = [...allAffinityTerms, ...allAntiTerms];
229
229
  this.queueUpdate = debounce(this.update, 500);
230
230
  },
231
231
 
@@ -6,6 +6,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
6
6
  import LabeledSelect from '@shell/components/form/LabeledSelect';
7
7
  import ShellInput from '@shell/components/form/ShellInput';
8
8
  import KeyValue from '@shell/components/form/KeyValue';
9
+ import { computed, ref, watch } from 'vue';
9
10
 
10
11
  const KINDS = [
11
12
  'none',
@@ -43,29 +44,29 @@ export default {
43
44
  },
44
45
  },
45
46
 
46
- data() {
47
- let kind = 'none';
48
- let probe = null;
49
- let exec = null;
50
- let httpGet = null;
51
- let tcpSocket = null;
52
-
53
- if ( this.value ) {
54
- probe = clone(this.value);
55
-
56
- if ( probe.exec ) {
57
- kind = 'exec';
58
- } else if ( probe.httpGet ) {
59
- if ( (probe.httpGet.scheme || '').toLowerCase() === 'https' ) {
60
- kind = 'HTTPS';
47
+ setup(props, { emit }) {
48
+ const kind = ref('none');
49
+ const probe = ref(null);
50
+ const exec = ref(null);
51
+ const httpGet = ref(null);
52
+ const tcpSocket = ref(null);
53
+
54
+ if ( props.value ) {
55
+ probe.value = clone(props.value);
56
+
57
+ if ( probe.value.exec ) {
58
+ kind.value = 'exec';
59
+ } else if ( probe.value.httpGet ) {
60
+ if ( (probe.value.httpGet.scheme || '').toLowerCase() === 'https' ) {
61
+ kind.value = 'HTTPS';
61
62
  } else {
62
- kind = 'HTTP';
63
+ kind.value = 'HTTP';
63
64
  }
64
- } else if ( probe.tcpSocket ) {
65
- kind = 'tcp';
65
+ } else if ( probe.value.tcpSocket ) {
66
+ kind.value = 'tcp';
66
67
  }
67
68
  } else {
68
- probe = {
69
+ probe.value = {
69
70
  failureThreshold: 3,
70
71
  successThreshold: 1,
71
72
  initialDelaySeconds: 0,
@@ -77,68 +78,68 @@ export default {
77
78
  };
78
79
  }
79
80
 
80
- exec = probe.exec || {};
81
- httpGet = probe.httpGet || {};
82
- tcpSocket = probe.tcpSocket || {};
81
+ exec.value = probe.value.exec || {};
82
+ httpGet.value = probe.value.httpGet || {};
83
+ tcpSocket.value = probe.value.tcpSocket || {};
83
84
 
84
- return {
85
- probe, kind, exec, httpGet, tcpSocket
86
- };
87
- },
88
-
89
- computed: {
90
- isView() {
91
- return this.mode === _VIEW;
92
- },
93
-
94
- isNone() {
95
- return this.kind === 'none';
96
- },
85
+ const isNone = computed(() => {
86
+ return kind.value === 'none';
87
+ });
97
88
 
98
- kindOptions() {
99
- return KINDS.map((k) => {
100
- return { label: this.t(`workload.container.healthCheck.kind.${ k }`), value: k };
101
- });
102
- }
103
- },
104
-
105
- watch: {
106
- kind() {
107
- this.update();
108
- }
109
- },
110
-
111
- methods: {
112
- update() {
113
- const probe = this.probe;
114
-
115
- if ( this.isNone ) {
116
- this.$emit('update:value', null);
89
+ const update = () => {
90
+ if ( isNone.value ) {
91
+ emit('update:value', null);
117
92
 
118
93
  return;
119
94
  }
120
95
 
121
- switch ( this.kind ) {
96
+ switch ( kind.value ) {
122
97
  case 'HTTP':
123
98
  case 'HTTPS':
124
- this.httpGet.scheme = this.kind;
125
- probe.httpGet = this.httpGet;
126
- probe.tcpSocket = null;
127
- probe.exec = null;
99
+ httpGet.value.scheme = kind.value;
100
+ probe.value.httpGet = httpGet.value;
101
+ probe.value.tcpSocket = null;
102
+ probe.value.exec = null;
128
103
  break;
129
104
  case 'tcp':
130
- probe.httpGet = null;
131
- probe.tcpSocket = this.tcpSocket;
132
- probe.exec = null;
105
+ probe.value.httpGet = null;
106
+ probe.value.tcpSocket = tcpSocket.value;
107
+ probe.value.exec = null;
133
108
  break;
134
109
  case 'exec':
135
- probe.httpGet = null;
136
- probe.tcpSocket = null;
137
- probe.exec = this.exec;
110
+ probe.value.httpGet = null;
111
+ probe.value.tcpSocket = null;
112
+ probe.value.exec = exec.value;
138
113
  break;
139
114
  }
140
115
 
141
- this.$emit('update:value', probe);
116
+ emit('update:value', probe.value);
117
+ };
118
+
119
+ watch(kind, () => {
120
+ update();
121
+ });
122
+
123
+ return {
124
+ probe,
125
+ kind,
126
+ exec,
127
+ httpGet,
128
+ tcpSocket,
129
+ update,
130
+ isNone,
131
+ };
132
+ },
133
+
134
+ computed: {
135
+ isView() {
136
+ return this.mode === _VIEW;
137
+ },
138
+
139
+ kindOptions() {
140
+ return KINDS.map((k) => {
141
+ return { label: this.t(`workload.container.healthCheck.kind.${ k }`), value: k };
142
+ });
142
143
  }
143
144
  },
144
145
  };
@@ -244,6 +245,7 @@ export default {
244
245
  v-if="kind && kind!=='none'"
245
246
  :style="{'position':'relative', 'margin':'0px'}"
246
247
  class="vertical"
248
+ role="none"
247
249
  >
248
250
  </div>
249
251
 
@@ -28,11 +28,15 @@ export default {
28
28
  },
29
29
 
30
30
  data() {
31
+ return { typeValues: null };
32
+ },
33
+
34
+ created() {
31
35
  this.value['spec'] = this.value.spec || {};
32
36
  this.value.spec['namespaceDefaultResourceQuota'] = this.value.spec.namespaceDefaultResourceQuota || { limit: {} };
33
37
  this.value.spec['resourceQuota'] = this.value.spec.resourceQuota || { limit: {} };
34
38
 
35
- return { typeValues: Object.keys(this.value.spec.resourceQuota.limit) };
39
+ this.typeValues = Object.keys(this.value.spec.resourceQuota.limit);
36
40
  },
37
41
 
38
42
  computed: { ...QUOTA_COMPUTED },
@@ -45,16 +45,14 @@ export default {
45
45
  },
46
46
 
47
47
  data() {
48
- const matchingResources = {
49
- matched: 0,
50
- matches: [],
51
- none: true,
52
- sample: null,
53
- total: 0,
54
- };
55
-
56
48
  return {
57
- matchingResources,
49
+ matchingResources: {
50
+ matched: 0,
51
+ matches: [],
52
+ none: true,
53
+ sample: null,
54
+ total: 0,
55
+ },
58
56
  allResources: [],
59
57
  allResourcesInScope: [],
60
58
  tableHeaders: this.$store.getters['type-map/headersFor'](
@@ -1,6 +1,6 @@
1
1
  import { mount, VueWrapper } from '@vue/test-utils';
2
2
  import { _EDIT } from '@shell/config/query-params';
3
- import KnownHostsEditDialog from '@shell/components/form/SSHKnownHosts/KnownHostsEditDialog.vue';
3
+ import KnownHostsEditDialog from '@shell/dialog/KnownHostsEditDialog.vue';
4
4
  import CodeMirror from '@shell/components/CodeMirror.vue';
5
5
  import FileSelector from '@shell/components/form/FileSelector.vue';
6
6
 
@@ -21,7 +21,7 @@ describe('component: KnownHostsEditDialog', () => {
21
21
  attachTo: document.body,
22
22
  props: {
23
23
  mode: _EDIT,
24
- value: 'line1\nline2\n',
24
+ value: 'line1\nline2\n'
25
25
  },
26
26
  ...requiredSetup(),
27
27
  });
@@ -33,8 +33,6 @@ describe('component: KnownHostsEditDialog', () => {
33
33
  });
34
34
 
35
35
  it('should update text from CodeMirror', async() => {
36
- await wrapper.setData({ showModal: true });
37
-
38
36
  expect(wrapper.vm.text).toBe('line1\nline2\n');
39
37
 
40
38
  const codeMirror = wrapper.getComponent(CodeMirror);
@@ -51,8 +49,6 @@ describe('component: KnownHostsEditDialog', () => {
51
49
  });
52
50
 
53
51
  it('should update text from FileSelector', async() => {
54
- await wrapper.setData({ showModal: true });
55
-
56
52
  expect(wrapper.vm.text).toBe('line1\nline2\n');
57
53
 
58
54
  const fileSelector = wrapper.getComponent(FileSelector);
@@ -67,38 +63,34 @@ describe('component: KnownHostsEditDialog', () => {
67
63
  });
68
64
 
69
65
  it('should save changes and close dialog', async() => {
70
- await wrapper.setData({
71
- showModal: true,
72
- text: 'foo',
73
- });
66
+ const closed = jest.spyOn(wrapper.vm, 'closed');
67
+
68
+ await wrapper.setData({ text: 'foo' });
74
69
 
75
70
  expect(wrapper.vm.value).toBe('line1\nline2\n');
76
71
  expect(wrapper.vm.text).toBe('foo');
77
72
 
78
73
  await wrapper.vm.closeDialog(true);
79
74
 
80
- expect((wrapper.emitted('closed') as any)[0][0].value).toBe('foo');
81
-
82
- const dialog = wrapper.vm.$refs['sshKnownHostsDialog'];
83
-
84
- expect(dialog).toBeNull();
75
+ expect(closed).toHaveBeenCalledWith({
76
+ success: true,
77
+ value: 'foo'
78
+ });
85
79
  });
86
80
 
87
81
  it('should discard changes and close dialog', async() => {
88
- await wrapper.setData({
89
- showModal: true,
90
- text: 'foo',
91
- });
82
+ const closed = jest.spyOn(wrapper.vm, 'closed');
83
+
84
+ await wrapper.setData({ text: 'foo' });
92
85
 
93
86
  expect(wrapper.vm.value).toBe('line1\nline2\n');
94
87
  expect(wrapper.vm.text).toBe('foo');
95
88
 
96
89
  await wrapper.vm.closeDialog(false);
97
90
 
98
- expect((wrapper.emitted('closed') as any)[0][0].value).toBe('line1\nline2\n');
99
-
100
- const dialog = wrapper.vm.$refs['sshKnownHostsDialog'];
101
-
102
- expect(dialog).toBeNull();
91
+ expect(closed).toHaveBeenCalledWith({
92
+ success: false,
93
+ value: 'line1\nline2\n'
94
+ });
103
95
  });
104
96
  });