@rancher/shell 3.0.5-rc.1 → 3.0.5-rc.3

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 (280) hide show
  1. package/assets/data/aws-regions.json +2 -0
  2. package/assets/images/providers/sks.svg +1 -0
  3. package/assets/styles/base/_helpers.scss +4 -0
  4. package/assets/styles/base/_variables.scss +1 -0
  5. package/assets/styles/global/_layout.scss +0 -1
  6. package/assets/translations/en-us.yaml +92 -34
  7. package/assets/translations/zh-hans.yaml +4 -13
  8. package/chart/monitoring/index.vue +4 -2
  9. package/components/ActionDropdownShell.vue +71 -0
  10. package/components/AppModal.vue +18 -4
  11. package/components/AsyncButton.vue +2 -0
  12. package/components/CodeMirror.vue +3 -3
  13. package/components/CommunityLinks.vue +3 -58
  14. package/components/CruResource.vue +109 -16
  15. package/components/ExplorerProjectsNamespaces.vue +19 -6
  16. package/components/FixedBanner.vue +19 -5
  17. package/components/GlobalRoleBindings.vue +5 -1
  18. package/components/GrowlManager.vue +1 -0
  19. package/components/LandingPagePreference.vue +2 -0
  20. package/components/LocaleSelector.vue +1 -1
  21. package/components/ModalManager.vue +55 -0
  22. package/components/PaginatedResourceTable.vue +7 -0
  23. package/components/PromptModal.vue +47 -8
  24. package/components/ResourceDetail/Masthead.vue +38 -13
  25. package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
  26. package/components/ResourceDetail/index.vue +47 -12
  27. package/components/ResourceList/index.vue +2 -1
  28. package/components/ResourceTable.vue +54 -19
  29. package/components/SideNav.vue +5 -1
  30. package/components/SlideInPanelManager.vue +125 -0
  31. package/components/SortableTable/THead.vue +5 -2
  32. package/components/SortableTable/actions.js +1 -1
  33. package/components/SortableTable/index.vue +54 -40
  34. package/components/SortableTable/paging.js +16 -19
  35. package/components/SortableTable/selection.js +1 -12
  36. package/components/Tabbed/index.vue +6 -0
  37. package/components/Wizard.vue +2 -2
  38. package/components/__tests__/AsyncButton.test.ts +39 -0
  39. package/components/__tests__/CruResource.test.ts +63 -0
  40. package/components/__tests__/ModalManager.spec.ts +176 -0
  41. package/components/__tests__/PromptModal.test.ts +146 -0
  42. package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
  43. package/components/auth/AuthBanner.vue +13 -11
  44. package/components/auth/Principal.vue +1 -0
  45. package/components/auth/login/ldap.vue +1 -1
  46. package/components/fleet/FleetResources.vue +21 -6
  47. package/components/form/ArrayList.vue +138 -118
  48. package/components/form/BannerSettings.vue +149 -85
  49. package/components/form/ColorInput.vue +35 -6
  50. package/components/form/EnvVars.vue +1 -0
  51. package/components/form/KeyValue.vue +10 -7
  52. package/components/form/LabeledSelect.vue +25 -23
  53. package/components/form/MatchExpressions.vue +9 -2
  54. package/components/form/NameNsDescription.vue +6 -2
  55. package/components/form/NotificationSettings.vue +15 -1
  56. package/components/form/Password.vue +1 -0
  57. package/components/form/Probe.vue +1 -0
  58. package/components/form/ResourceSelector.vue +26 -23
  59. package/components/form/ResourceTabs/index.vue +2 -1
  60. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +15 -34
  61. package/components/form/SSHKnownHosts/index.vue +14 -11
  62. package/components/form/Select.vue +8 -15
  63. package/components/form/UnitInput.vue +13 -0
  64. package/components/form/ValueFromResource.vue +12 -12
  65. package/components/form/__tests__/ArrayList.test.ts +34 -2
  66. package/components/form/__tests__/ColorInput.test.ts +35 -0
  67. package/components/form/__tests__/KeyValue.test.ts +36 -0
  68. package/components/form/__tests__/LabeledSelect.test.ts +73 -0
  69. package/components/form/__tests__/SSHKnownHosts.test.ts +11 -2
  70. package/components/form/__tests__/Select.test.ts +34 -1
  71. package/components/form/__tests__/UnitInput.test.ts +23 -1
  72. package/components/formatter/ClusterLink.vue +5 -8
  73. package/components/formatter/Description.vue +30 -0
  74. package/components/formatter/__tests__/ClusterLink.test.ts +2 -32
  75. package/components/nav/Group.vue +12 -4
  76. package/components/nav/Header.vue +16 -43
  77. package/components/nav/NamespaceFilter.vue +134 -86
  78. package/components/nav/TopLevelMenu.vue +4 -5
  79. package/components/nav/WindowManager/ContainerLogs.vue +87 -61
  80. package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
  81. package/components/nav/WindowManager/index.vue +1 -0
  82. package/components/templates/default.vue +6 -3
  83. package/components/templates/home.vue +6 -0
  84. package/components/templates/plain.vue +6 -3
  85. package/composables/focusTrap.ts +12 -4
  86. package/config/product/explorer.js +16 -13
  87. package/config/product/manager.js +1 -28
  88. package/config/settings.ts +11 -13
  89. package/config/store.js +4 -0
  90. package/config/table-headers.js +7 -5
  91. package/config/uiplugins.js +5 -1
  92. package/core/types.ts +7 -6
  93. package/detail/catalog.cattle.io.app.vue +5 -1
  94. package/detail/fleet.cattle.io.bundle.vue +70 -6
  95. package/detail/fleet.cattle.io.gitrepo.vue +1 -1
  96. package/detail/namespace.vue +0 -3
  97. package/detail/node.vue +17 -13
  98. package/detail/provisioning.cattle.io.cluster.vue +85 -9
  99. package/detail/service.vue +0 -1
  100. package/detail/workload/index.vue +21 -34
  101. package/dialog/AddCustomBadgeDialog.vue +0 -1
  102. package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
  103. package/dialog/AssignToDialog.vue +176 -0
  104. package/dialog/ChangePasswordDialog.vue +106 -0
  105. package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
  106. package/dialog/DisableAuthProviderDialog.vue +101 -0
  107. package/dialog/DrainNode.vue +1 -1
  108. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
  109. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +83 -65
  110. package/dialog/FeatureFlagListDialog.vue +288 -0
  111. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  112. package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
  113. package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
  114. package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -62
  115. package/dialog/MoveNamespaceDialog.vue +157 -0
  116. package/dialog/ScalePoolDownDialog.vue +1 -1
  117. package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
  118. package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
  119. package/dialog/WechatDialog.vue +57 -0
  120. package/edit/__tests__/service.test.ts +2 -1
  121. package/edit/auth/azuread.vue +1 -1
  122. package/edit/auth/github.vue +1 -1
  123. package/edit/auth/googleoauth.vue +1 -1
  124. package/edit/auth/ldap/index.vue +1 -1
  125. package/edit/auth/oidc.vue +1 -1
  126. package/edit/auth/saml.vue +1 -1
  127. package/edit/cloudcredential.vue +24 -10
  128. package/edit/management.cattle.io.user.vue +28 -3
  129. package/edit/namespace.vue +1 -4
  130. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -14
  131. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +57 -62
  132. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +3 -14
  133. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.test.ts +72 -41
  134. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +17 -1
  135. package/edit/networking.k8s.io.networkpolicy/index.vue +18 -30
  136. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
  137. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -10
  138. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
  139. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
  140. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
  141. package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
  142. package/edit/provisioning.cattle.io.cluster/index.vue +21 -73
  143. package/edit/provisioning.cattle.io.cluster/rke2.vue +24 -7
  144. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
  145. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +4 -1
  146. package/edit/service.vue +13 -28
  147. package/initialize/install-plugins.js +2 -1
  148. package/list/harvesterhci.io.management.cluster.vue +4 -1
  149. package/list/management.cattle.io.feature.vue +4 -288
  150. package/list/workload.vue +6 -1
  151. package/machine-config/azure.vue +16 -4
  152. package/mixins/resource-fetch-api-pagination.js +55 -43
  153. package/mixins/resource-fetch.js +14 -5
  154. package/mixins/vue-select-overrides.js +0 -4
  155. package/models/__tests__/workload.test.ts +1 -0
  156. package/models/cluster/node.js +1 -0
  157. package/models/cluster.js +32 -2
  158. package/models/fleet.cattle.io.cluster.js +8 -2
  159. package/models/fleet.cattle.io.gitrepo.js +8 -34
  160. package/models/management.cattle.io.cluster.js +0 -20
  161. package/models/management.cattle.io.feature.js +7 -1
  162. package/models/management.cattle.io.node.js +7 -22
  163. package/models/management.cattle.io.nodepool.js +12 -0
  164. package/models/namespace.js +12 -1
  165. package/models/provisioning.cattle.io.cluster.js +18 -64
  166. package/models/service.js +24 -9
  167. package/models/workload.js +70 -31
  168. package/package.json +1 -1
  169. package/pages/about.vue +13 -3
  170. package/pages/account/index.vue +12 -5
  171. package/pages/auth/login.vue +7 -4
  172. package/pages/auth/setup.vue +1 -0
  173. package/pages/auth/verify.vue +9 -7
  174. package/pages/c/_cluster/apps/charts/install.vue +25 -26
  175. package/pages/c/_cluster/auth/config/index.vue +10 -12
  176. package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
  177. package/pages/c/_cluster/explorer/index.vue +28 -15
  178. package/pages/c/_cluster/istio/index.vue +2 -2
  179. package/pages/c/_cluster/longhorn/index.vue +3 -3
  180. package/pages/c/_cluster/monitoring/index.vue +1 -1
  181. package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
  182. package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
  183. package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
  184. package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
  185. package/pages/c/_cluster/neuvector/index.vue +1 -1
  186. package/pages/c/_cluster/settings/banners.vue +60 -5
  187. package/pages/c/_cluster/settings/performance.vue +7 -26
  188. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
  189. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
  190. package/pages/c/_cluster/uiplugins/index.vue +98 -55
  191. package/pages/diagnostic.vue +12 -9
  192. package/pages/fail-whale.vue +8 -5
  193. package/pages/home.vue +11 -52
  194. package/pages/prefs.vue +7 -6
  195. package/plugins/clean-html.js +2 -0
  196. package/plugins/dashboard-store/__tests__/actions.test.ts +4 -1
  197. package/plugins/dashboard-store/actions.js +122 -21
  198. package/plugins/dashboard-store/getters.js +74 -3
  199. package/plugins/dashboard-store/mutations.js +10 -5
  200. package/plugins/dashboard-store/resource-class.js +23 -3
  201. package/plugins/internal-api/index.ts +37 -0
  202. package/plugins/internal-api/shared/base-api.ts +13 -0
  203. package/plugins/internal-api/shell/shell.api.ts +108 -0
  204. package/plugins/steve/__tests__/getters.test.ts +18 -11
  205. package/plugins/steve/__tests__/steve-class.test.ts +1 -0
  206. package/plugins/steve/actions.js +34 -24
  207. package/plugins/steve/getters.js +39 -10
  208. package/plugins/steve/steve-class.js +5 -0
  209. package/plugins/steve/steve-pagination-utils.ts +199 -37
  210. package/plugins/steve/worker/web-worker.advanced.js +3 -1
  211. package/public/index.html +1 -0
  212. package/rancher-components/Banner/Banner.test.ts +51 -3
  213. package/rancher-components/Banner/Banner.vue +28 -6
  214. package/rancher-components/Card/Card.vue +1 -1
  215. package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
  216. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
  217. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +51 -0
  218. package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
  219. package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
  220. package/rancher-components/Form/Radio/RadioButton.vue +20 -4
  221. package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
  222. package/rancher-components/Form/Radio/RadioGroup.vue +75 -35
  223. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
  224. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +26 -1
  225. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
  226. package/rancher-components/RcButton/RcButton.vue +2 -1
  227. package/rancher-components/RcButton/types.ts +1 -0
  228. package/rancher-components/RcDropdown/RcDropdown.vue +17 -6
  229. package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
  230. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
  231. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
  232. package/rancher-components/RcDropdown/index.ts +2 -0
  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 -13
  239. package/scripts/typegen.sh +2 -4
  240. package/store/action-menu.js +26 -56
  241. package/store/features.js +0 -1
  242. package/store/index.js +5 -0
  243. package/store/modal.ts +71 -0
  244. package/store/slideInPanel.ts +47 -0
  245. package/store/type-map.js +8 -1
  246. package/store/type-map.utils.ts +49 -6
  247. package/types/fleet.d.ts +1 -1
  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/kube/kube-api.ts +22 -0
  253. package/types/resources/fleet.d.ts +0 -14
  254. package/types/resources/settings.d.ts +0 -4
  255. package/types/shell/index.d.ts +375 -306
  256. package/types/store/dashboard-store.types.ts +24 -1
  257. package/types/store/pagination.types.ts +19 -2
  258. package/types/vue-shim.d.ts +4 -1
  259. package/utils/__mocks__/tabbable.js +13 -0
  260. package/utils/__tests__/object.test.ts +38 -4
  261. package/utils/cluster.js +24 -20
  262. package/utils/fleet.ts +15 -73
  263. package/utils/grafana.js +1 -0
  264. package/utils/object.js +36 -5
  265. package/utils/pagination-utils.ts +6 -2
  266. package/utils/perf-setting.utils.ts +28 -0
  267. package/utils/selector-typed.ts +205 -0
  268. package/utils/selector.js +29 -6
  269. package/utils/uiplugins.ts +10 -6
  270. package/utils/v-sphere.ts +5 -1
  271. package/utils/validators/formRules/__tests__/index.test.ts +10 -1
  272. package/utils/validators/formRules/index.ts +27 -3
  273. package/components/AssignTo.vue +0 -199
  274. package/components/DisableAuthProviderModal.vue +0 -115
  275. package/components/MoveModal.vue +0 -167
  276. package/components/PromptChangePassword.vue +0 -123
  277. package/components/fleet/FleetBundleResources.vue +0 -86
  278. package/components/formatter/RKETemplateName.vue +0 -37
  279. package/dialog/SaveAsRKETemplateDialog.vue +0 -139
  280. package/types/vue-shim.d +0 -20
@@ -2,14 +2,12 @@
2
2
  import { _EDIT, _VIEW } from '@shell/config/query-params';
3
3
  import CodeMirror from '@shell/components/CodeMirror';
4
4
  import FileSelector from '@shell/components/form/FileSelector.vue';
5
- import AppModal from '@shell/components/AppModal.vue';
6
5
 
7
6
  export default {
8
- emits: ['closed'],
7
+ emits: ['close'],
9
8
 
10
9
  components: {
11
10
  FileSelector,
12
- AppModal,
13
11
  CodeMirror,
14
12
  },
15
13
 
@@ -22,6 +20,15 @@ export default {
22
20
  mode: {
23
21
  type: String,
24
22
  default: _EDIT
23
+ },
24
+
25
+ /**
26
+ * Callback when modal is closed
27
+ */
28
+ closed: {
29
+ type: Function,
30
+ default: () => {},
31
+ required: true
25
32
  }
26
33
  },
27
34
 
@@ -40,9 +47,7 @@ export default {
40
47
 
41
48
  return {
42
49
  codeMirrorOptions,
43
- text: this.value,
44
- showModal: false,
45
- returnFocusSelector: '#known-ssh-hosts-trigger'
50
+ text: this.value,
46
51
  };
47
52
  },
48
53
 
@@ -56,83 +61,68 @@ export default {
56
61
  onTextChange(value) {
57
62
  this.text = value?.trim();
58
63
  },
59
-
60
- showDialog() {
61
- this.showModal = true;
62
- },
63
-
64
64
  closeDialog(result) {
65
65
  if (!result) {
66
66
  this.text = this.value;
67
67
  }
68
68
 
69
- this.showModal = false;
70
-
71
- this.$emit('closed', {
69
+ this.closed({
72
70
  success: result,
73
71
  value: this.text,
74
72
  });
73
+
74
+ this.$emit('close');
75
75
  },
76
76
  }
77
77
  };
78
78
  </script>
79
79
 
80
80
  <template>
81
- <app-modal
82
- v-if="showModal"
81
+ <div
83
82
  ref="sshKnownHostsDialog"
84
- data-testid="sshKnownHostsDialog"
85
- height="auto"
86
- :scrollable="true"
87
- :trigger-focus-trap="true"
88
- :return-focus-selector="returnFocusSelector"
89
- @close="closeDialog(false)"
83
+ class="ssh-known-hosts-dialog"
90
84
  >
91
- <div
92
- class="ssh-known-hosts-dialog"
93
- >
94
- <h4 class="mt-10">
95
- {{ t('secret.ssh.editKnownHosts.title') }}
96
- </h4>
97
- <div class="custom mt-10">
98
- <div class="dialog-panel">
99
- <CodeMirror
100
- :value="text"
101
- data-testid="ssh-known-hosts-dialog_code-mirror"
102
- :options="codeMirrorOptions"
103
- :showKeyMapBox="true"
104
- @onInput="onTextChange"
85
+ <h4 class="mt-10">
86
+ {{ t('secret.ssh.editKnownHosts.title') }}
87
+ </h4>
88
+ <div class="custom mt-10">
89
+ <div class="dialog-panel">
90
+ <CodeMirror
91
+ :value="text"
92
+ data-testid="ssh-known-hosts-dialog_code-mirror"
93
+ :options="codeMirrorOptions"
94
+ :showKeyMapBox="true"
95
+ @onInput="onTextChange"
96
+ />
97
+ </div>
98
+ <div class="dialog-actions">
99
+ <div class="action-pannel file-selector">
100
+ <FileSelector
101
+ class="btn role-secondary"
102
+ data-testid="ssh-known-hosts-dialog_file-selector"
103
+ :label="t('generic.readFromFile')"
104
+ @selected="onTextChange"
105
105
  />
106
106
  </div>
107
- <div class="dialog-actions">
108
- <div class="action-pannel file-selector">
109
- <FileSelector
110
- class="btn role-secondary"
111
- data-testid="ssh-known-hosts-dialog_file-selector"
112
- :label="t('generic.readFromFile')"
113
- @selected="onTextChange"
114
- />
115
- </div>
116
- <div class="action-pannel form-actions">
117
- <button
118
- class="btn role-secondary"
119
- data-testid="ssh-known-hosts-dialog_cancel-btn"
120
- @click="closeDialog(false)"
121
- >
122
- {{ t('generic.cancel') }}
123
- </button>
124
- <button
125
- class="btn role-primary"
126
- data-testid="ssh-known-hosts-dialog_save-btn"
127
- @click="closeDialog(true)"
128
- >
129
- {{ t('generic.save') }}
130
- </button>
131
- </div>
107
+ <div class="action-pannel form-actions">
108
+ <button
109
+ class="btn role-secondary"
110
+ data-testid="ssh-known-hosts-dialog_cancel-btn"
111
+ @click="closeDialog(false)"
112
+ >
113
+ {{ t('generic.cancel') }}
114
+ </button>
115
+ <button
116
+ class="btn role-primary"
117
+ data-testid="ssh-known-hosts-dialog_save-btn"
118
+ @click="closeDialog(true)"
119
+ >
120
+ {{ t('generic.save') }}
121
+ </button>
132
122
  </div>
133
123
  </div>
134
124
  </div>
135
- </app-modal>
125
+ </div>
136
126
  </template>
137
127
 
138
128
  <style lang="scss" scoped>
@@ -0,0 +1,157 @@
1
+ <script>
2
+ import { mapGetters } from 'vuex';
3
+ import { Card } from '@components/Card';
4
+ import AsyncButton from '@shell/components/AsyncButton';
5
+ import LabeledSelect from '@shell/components/form/LabeledSelect';
6
+ import { MANAGEMENT } from '@shell/config/types';
7
+ import { PROJECT } from '@shell/config/labels-annotations';
8
+
9
+ export default {
10
+ emits: ['close'],
11
+
12
+ components: {
13
+ AsyncButton, Card, LabeledSelect
14
+ },
15
+
16
+ props: {
17
+ resources: {
18
+ type: Array,
19
+ default: () => []
20
+ },
21
+ movingCb: {
22
+ type: Function,
23
+ default: () => {}
24
+ },
25
+ registerBackgroundClosing: {
26
+ type: Function,
27
+ default: () => {}
28
+ }
29
+ },
30
+
31
+ async fetch() {
32
+ this.toMove = this.resources;
33
+ this.projects = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT });
34
+ },
35
+
36
+ data() {
37
+ return {
38
+ projects: [],
39
+ toMove: [],
40
+ targetProject: null
41
+ };
42
+ },
43
+
44
+ computed: {
45
+ ...mapGetters(['currentCluster']),
46
+
47
+ excludedProjects() {
48
+ return this.toMove.filter((namespace) => !!namespace.project).map((namespace) => namespace.project.shortId);
49
+ },
50
+
51
+ projectOptions() {
52
+ return this.projects.reduce((inCluster, project) => {
53
+ if (!this.excludedProjects.includes(project.shortId) && project.spec?.clusterName === this.currentCluster.id) {
54
+ inCluster.push({
55
+ value: project.shortId,
56
+ label: project.nameDisplay
57
+ });
58
+ }
59
+
60
+ return inCluster;
61
+ }, []);
62
+ }
63
+ },
64
+
65
+ methods: {
66
+ close(data) {
67
+ this.$emit('close', data);
68
+ },
69
+
70
+ async move(finish) {
71
+ const cluster = this.$store.getters['currentCluster'];
72
+ const clusterWithProjectId = `${ cluster.id }:${ this.targetProject }`;
73
+
74
+ const promises = this.toMove.map((namespace) => {
75
+ namespace.setLabel(PROJECT, this.targetProject);
76
+ namespace.setAnnotation(PROJECT, clusterWithProjectId);
77
+
78
+ return namespace.save();
79
+ });
80
+
81
+ try {
82
+ await Promise.all(promises);
83
+ finish(true);
84
+ this.targetProject = null;
85
+ this.close({ performCallback: true, moveNamespaceCb: true });
86
+ } catch (ex) {
87
+ finish(false);
88
+ }
89
+ }
90
+ }
91
+ };
92
+ </script>
93
+ <template>
94
+ <Card
95
+ class="move-modal-card"
96
+ :show-highlight-border="false"
97
+ >
98
+ <template #title>
99
+ <h4 class="text-default-text">
100
+ {{ t('moveModal.title') }}
101
+ </h4>
102
+ </template>
103
+ <template #body>
104
+ <div>
105
+ {{ t('moveModal.description') }}
106
+ <ul class="namespaces">
107
+ <li
108
+ v-for="(namespace, i) in toMove"
109
+ :key="i"
110
+ >
111
+ {{ namespace.nameDisplay }}
112
+ </li>
113
+ </ul>
114
+ </div>
115
+ <LabeledSelect
116
+ v-model:value="targetProject"
117
+ :options="projectOptions"
118
+ :label="t('moveModal.targetProject')"
119
+ />
120
+ </template>
121
+ <template #actions>
122
+ <button
123
+ class="btn role-secondary"
124
+ @click="close"
125
+ >
126
+ {{ t('generic.cancel') }}
127
+ </button>
128
+ <AsyncButton
129
+ :action-label="t('moveModal.moveButtonLabel')"
130
+ class="btn bg-primary ml-10"
131
+ :disabled="!targetProject"
132
+ @click="move"
133
+ />
134
+ </template>
135
+ </Card>
136
+ </template>
137
+
138
+ <style lang='scss'>
139
+ .namespaces {
140
+ max-height: 200px;
141
+ overflow-y: scroll;
142
+ }
143
+
144
+ .move-modal-card {
145
+ box-shadow: none;
146
+
147
+ border-radius: var(--border-radius);
148
+ }
149
+
150
+ .actions {
151
+ text-align: right;
152
+ }
153
+ .card-actions {
154
+ display: flex;
155
+ justify-content: center;
156
+ }
157
+ </style>
@@ -27,7 +27,7 @@ export default {
27
27
  },
28
28
  computed: {
29
29
  machinenName() {
30
- const name = this.resources.length > 0 ? this.resources[0].id.split('/')[1] : '';
30
+ const name = this.resources.length > 0 ? this.resources[0]?.id?.split('/')[1] : '';
31
31
 
32
32
  return name;
33
33
  },
@@ -6,7 +6,7 @@ import { BOTH, TYPE_MODES } from '@shell/store/type-map';
6
6
  import { COUNT } from '@shell/config/types';
7
7
 
8
8
  export default {
9
- emits: ['closeSearch'],
9
+ emits: ['close'],
10
10
 
11
11
  components: { Group },
12
12
 
@@ -41,7 +41,7 @@ export default {
41
41
  const allTypes = allTypesByMode[TYPE_MODES.ALL];
42
42
  const out = this.$store.getters['type-map/getTree'](productId, TYPE_MODES.ALL, allTypes, clusterId, BOTH, null, this.value);
43
43
 
44
- // Suplement the output with count info. Usualy the `Type` component would handle this individualy... but scales real bad so give it
44
+ // Supplement the output with count info. Usually the `Type` component would handle this individually... but scales real bad so give it
45
45
  // some help
46
46
  const counts = this.$store.getters[`${ product.inStore }/all`](COUNT)?.[0]?.counts || {};
47
47
 
@@ -77,16 +77,22 @@ export default {
77
77
  >
78
78
  {{ t('nav.resourceSearch.filteringDescription') }}
79
79
  </p>
80
- <input
81
- ref="input"
82
- v-model="value"
83
- :placeholder="t('nav.resourceSearch.placeholder')"
84
- class="search"
85
- role="textbox"
86
- :aria-label="t('nav.resourceSearch.label')"
87
- aria-describedby="describe-filter-resource-search"
88
- @keyup.esc="$emit('closeSearch')"
89
- >
80
+ <div class="dialog-title">
81
+ <div>{{ t('nav.resourceSearch.label') }}</div>
82
+ <p>{{ t('nav.resourceSearch.prompt') }}</p>
83
+ </div>
84
+ <div class="search-box">
85
+ <input
86
+ ref="input"
87
+ v-model="value"
88
+ :placeholder="t('nav.resourceSearch.placeholder')"
89
+ class="search"
90
+ role="textbox"
91
+ :aria-label="t('nav.resourceSearch.label')"
92
+ aria-describedby="describe-filter-resource-search"
93
+ @keyup.esc="$emit('close')"
94
+ >
95
+ </div>
90
96
  <div class="results">
91
97
  <div
92
98
  v-for="g in groups"
@@ -100,7 +106,7 @@ export default {
100
106
  :group="g"
101
107
  :can-collapse="false"
102
108
  :fixed-open="true"
103
- @close="$emit('closeSearch')"
109
+ @close="$emit('close')"
104
110
  >
105
111
  <template #accordion>
106
112
  <h6>{{ g.label }}</h6>
@@ -119,17 +125,31 @@ export default {
119
125
  box-shadow: none;
120
126
  }
121
127
 
128
+ .search-box {
129
+ margin: 8px;
130
+ }
131
+
122
132
  .search:focus-visible {
123
133
  outline-offset: -2px;
124
134
  }
125
135
 
136
+ .dialog-title {
137
+ padding: 8px;
138
+
139
+ > div {
140
+ font-size: 16px;
141
+ font-weight: bold;
142
+ margin: 8px 0;
143
+ }
144
+ }
145
+
126
146
  .results {
127
147
  margin-top: -1px;
128
148
  overflow-y: auto;
129
149
  padding: 10px;
130
150
  color: var(--dropdown-text);
131
151
  background-color: var(--dropdown-bg);
132
- border: 1px solid var(--dropdown-border);
152
+ border-top: 1px solid var(--dropdown-border);
133
153
  height: 75vh;
134
154
  }
135
155
  </style>
@@ -2,47 +2,70 @@
2
2
  import { mapGetters } from 'vuex';
3
3
 
4
4
  import AsyncButton from '@shell/components/AsyncButton';
5
- import AppModal from '@shell/components/AppModal.vue';
6
5
  import { CATALOG } from '@shell/config/types';
7
6
  import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
8
7
 
9
8
  export default {
10
- emits: ['closed', 'update'],
11
-
12
- components: {
13
- AsyncButton,
14
- AppModal,
9
+ emits: ['close'],
10
+
11
+ components: { AsyncButton },
12
+
13
+ props: {
14
+ /**
15
+ * Plugin object
16
+ */
17
+ plugin: {
18
+ type: Object,
19
+ default: () => {},
20
+ required: true
21
+ },
22
+ /**
23
+ * Callback to update install status on extensions main screen
24
+ */
25
+ updateStatus: {
26
+ type: Function,
27
+ default: () => {},
28
+ required: true
29
+ },
30
+ /**
31
+ * Callback when modal is closed
32
+ */
33
+ closed: {
34
+ type: Function,
35
+ default: () => {},
36
+ required: true
37
+ },
38
+ resources: {
39
+ type: Array,
40
+ default: () => []
41
+ },
42
+ registerBackgroundClosing: {
43
+ type: Function,
44
+ default: () => {}
45
+ }
15
46
  },
16
47
 
17
48
  data() {
18
- return {
19
- plugin: undefined, busy: false, showModal: false
20
- };
49
+ return { busy: false };
21
50
  },
22
51
 
23
- computed: {
24
- ...mapGetters({ allCharts: 'catalog/charts' }),
25
- returnFocusSelector() {
26
- return `[data-testid="extension-card-uninstall-btn-${ this.plugin?.name }"]`;
27
- }
28
- },
52
+ computed: { ...mapGetters({ allCharts: 'catalog/charts' }) },
29
53
 
30
54
  methods: {
31
55
  showDialog(plugin) {
32
56
  this.plugin = plugin;
33
57
  this.busy = false;
34
- this.showModal = true;
35
58
  },
36
59
  closeDialog(result) {
37
- this.showModal = false;
38
- this.$emit('closed', result);
60
+ this.closed(result);
61
+ this.$emit('close');
39
62
  },
40
63
  async uninstall() {
41
64
  this.busy = true;
42
65
 
43
66
  const plugin = this.plugin;
44
67
 
45
- this.$emit('update', plugin.name, 'uninstall');
68
+ this.updateStatus(plugin.name, 'uninstall');
46
69
 
47
70
  // Delete the CR if this is a developer plugin (there is no Helm App, so need to remove the CRD ourselves)
48
71
  if (plugin.uiplugin?.isDeveloper) {
@@ -78,47 +101,33 @@ export default {
78
101
  </script>
79
102
 
80
103
  <template>
81
- <app-modal
82
- v-if="showModal"
83
- name="uninstallPluginDialog"
84
- height="auto"
85
- :scrollable="true"
86
- :trigger-focus-trap="true"
87
- :return-focus-selector="returnFocusSelector"
88
- :return-focus-first-iterable-node-selector="'#extensions-main-page'"
89
- @close="closeDialog(false)"
90
- >
91
- <div
92
- v-if="plugin"
93
- class="plugin-install-dialog"
94
- >
95
- <h4 class="mt-10">
96
- {{ t('plugins.uninstall.title', { name: plugin.label }) }}
97
- </h4>
98
- <div class="mt-10 dialog-panel">
99
- <div class="dialog-info">
100
- <p>
101
- {{ t('plugins.uninstall.prompt') }}
102
- </p>
103
- </div>
104
- <div class="dialog-buttons">
105
- <button
106
- :disabled="busy"
107
- class="btn role-secondary"
108
- data-testid="uninstall-ext-modal-cancel-btn"
109
- @click="closeDialog(false)"
110
- >
111
- {{ t('generic.cancel') }}
112
- </button>
113
- <AsyncButton
114
- mode="uninstall"
115
- data-testid="uninstall-ext-modal-uninstall-btn"
116
- @click="uninstall()"
117
- />
118
- </div>
104
+ <div class="plugin-install-dialog">
105
+ <h4 class="mt-10">
106
+ {{ t('plugins.uninstall.title', { name: plugin?.label }) }}
107
+ </h4>
108
+ <div class="mt-10 dialog-panel">
109
+ <div class="dialog-info">
110
+ <p>
111
+ {{ t('plugins.uninstall.prompt') }}
112
+ </p>
113
+ </div>
114
+ <div class="dialog-buttons">
115
+ <button
116
+ :disabled="busy"
117
+ class="btn role-secondary"
118
+ data-testid="uninstall-ext-modal-cancel-btn"
119
+ @click="closeDialog(false)"
120
+ >
121
+ {{ t('generic.cancel') }}
122
+ </button>
123
+ <AsyncButton
124
+ mode="uninstall"
125
+ data-testid="uninstall-ext-modal-uninstall-btn"
126
+ @click="uninstall()"
127
+ />
119
128
  </div>
120
129
  </div>
121
- </app-modal>
130
+ </div>
122
131
  </template>
123
132
 
124
133
  <style lang="scss" scoped>
@@ -0,0 +1,57 @@
1
+ <script>
2
+ // i18n-ignore footer.wechat.modalText, footer.wechat.modalText2
3
+ export default {
4
+ emits: ['close'],
5
+
6
+ name: 'WechatModal',
7
+
8
+ methods: {
9
+ close() {
10
+ this.$emit('close');
11
+ }
12
+ },
13
+ };
14
+ </script>
15
+
16
+ <template>
17
+ <div class="wechat-modal">
18
+ <h1>{{ t('footer.wechat.modalText') }}</h1>
19
+ <h1>{{ t('footer.wechat.modalText2') }}</h1>
20
+ <div class="qr-img" />
21
+ <div>
22
+ <button
23
+ class="btn role-primary"
24
+ tabindex="0"
25
+ :aria-label="t('generic.close')"
26
+ role="button"
27
+ @click="close"
28
+ @keydown.enter.stop
29
+ >
30
+ {{ t('generic.close') }}
31
+ </button>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <style lang='scss' scoped>
37
+ .wechat-modal {
38
+ margin: 60px;
39
+ display: flex;
40
+ flex-direction: column;
41
+ align-items: center;
42
+ }
43
+
44
+ .btn {
45
+ margin: 20px auto 0;
46
+ }
47
+
48
+ .qr-img {
49
+ background-image: url('../assets/images/wechat-qr-code.jpg');
50
+ background-repeat: no-repeat;
51
+ background-size: cover;
52
+ background-position: center center;
53
+ height: 128px;
54
+ width: 128px;
55
+ margin: 15px auto 10px;
56
+ }
57
+ </style>
@@ -61,7 +61,8 @@ describe('service edit', () => {
61
61
  $store: {
62
62
  getters: {
63
63
  'management/all': jest.fn(),
64
- 'i18n/t': jest.fn()
64
+ 'i18n/t': jest.fn(),
65
+ currentStore: () => 'cluster',
65
66
  }
66
67
  }
67
68
  },
@@ -363,7 +363,7 @@ export default {
363
363
  </template>
364
364
  </AuthBanner>
365
365
 
366
- <hr>
366
+ <hr role="none">
367
367
 
368
368
  <AllowedPrincipals
369
369
  provider="azuread"
@@ -143,7 +143,7 @@ export default {
143
143
  </template>
144
144
  </AuthBanner>
145
145
 
146
- <hr>
146
+ <hr role="none">
147
147
 
148
148
  <AllowedPrincipals
149
149
  provider="github"
@@ -90,7 +90,7 @@ export default {
90
90
  </template>
91
91
  </AuthBanner>
92
92
 
93
- <hr>
93
+ <hr role="none">
94
94
 
95
95
  <AllowedPrincipals
96
96
  provider="googleoauth"