@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
@@ -7,9 +7,11 @@ export default {
7
7
  components: { ResourceDetail },
8
8
 
9
9
  data() {
10
- const { query:{ resource } } = this.$route;
10
+ return { resource: null };
11
+ },
11
12
 
12
- return { resource };
13
+ created() {
14
+ this.resource = this.$route.query.resource;
13
15
  }
14
16
  };
15
17
  </script>
@@ -15,9 +15,11 @@ export default {
15
15
  components: { ResourceDetail },
16
16
 
17
17
  data() {
18
- const { query:{ resource } } = this.$route;
18
+ return { resource: null };
19
+ },
19
20
 
20
- return { resource };
21
+ created() {
22
+ this.resource = this.$route.query.resource;
21
23
  }
22
24
  };
23
25
  </script>
@@ -15,9 +15,11 @@ export default {
15
15
  components: { ResourceDetail },
16
16
 
17
17
  data() {
18
- const { query:{ resource } } = this.$route;
18
+ return { resource: null };
19
+ },
19
20
 
20
- return { resource };
21
+ created() {
22
+ this.resource = this.$route.query.resource;
21
23
  }
22
24
  };
23
25
  </script>
@@ -7,10 +7,13 @@ export default {
7
7
  components: { ResourceDetail },
8
8
 
9
9
  data() {
10
- const { query:{ resource } } = this.$route;
10
+ return { resource: null };
11
+ },
11
12
 
12
- return { resource };
13
+ created() {
14
+ this.resource = this.$route.query.resource;
13
15
  }
16
+
14
17
  };
15
18
  </script>
16
19
 
@@ -65,7 +65,7 @@ export default {
65
65
  <div class="link-content">
66
66
  <t :k="fel.label" />
67
67
  <i class="icon icon-external-link pull-right" />
68
- <hr>
68
+ <hr role="none">
69
69
  <div class="description"><t :k="fel.description" /></div>
70
70
  </div>
71
71
  </a>
@@ -207,7 +207,7 @@ export default {
207
207
 
208
208
  <!-- Header Settings -->
209
209
  <h2 class="mt-40 mb-10 setting-title">
210
- {{ t('banner.headerBanner') }}
210
+ {{ t('banner.bannerHeader') }}
211
211
  <i
212
212
  v-if="!!uiBannerIndividual.bannerHeader"
213
213
  class="icon icon-lock"
@@ -242,7 +242,7 @@ export default {
242
242
 
243
243
  <!-- Footer settings -->
244
244
  <h2 class="mt-40 mb-10 setting-title">
245
- {{ t('banner.footerBanner') }}
245
+ {{ t('banner.bannerFooter') }}
246
246
  <i
247
247
  v-if="!!uiBannerIndividual.bannerFooter"
248
248
  class="icon icon-lock"
@@ -277,7 +277,7 @@ export default {
277
277
 
278
278
  <!-- Consent settings -->
279
279
  <h2 class="mt-40 mb-10 setting-title">
280
- {{ t('banner.loginScreenBanner') }}
280
+ {{ t('banner.bannerConsent') }}
281
281
  <i
282
282
  v-if="!!uiBannerIndividual.bannerConsent"
283
283
  class="icon icon-lock"
@@ -316,6 +316,7 @@ export default {
316
316
  v-model:value="bannerVal.loginError"
317
317
  :mode="mode"
318
318
  :label="t('notifications.loginError.messageLabel')"
319
+ :hidden-aria-described-label="t('notifications.loginError.header')"
319
320
  />
320
321
  </div>
321
322
  <template
@@ -19,17 +19,15 @@ export default {
19
19
  mixins: [ResourceManager],
20
20
 
21
21
  data() {
22
- const actions = [
23
- {
24
- action: 'showCatalogUninstallDialog',
25
- label: this.t('plugins.uninstall.label'),
26
- icon: 'icon icon-trash',
27
- enabled: true,
28
- }
29
- ];
30
-
31
22
  return {
32
- actions,
23
+ actions: [
24
+ {
25
+ action: 'showCatalogUninstallDialog',
26
+ label: this.t('plugins.uninstall.label'),
27
+ icon: 'icon icon-trash',
28
+ enabled: true,
29
+ }
30
+ ],
33
31
  catalogHeaders: UI_PLUGIN_CATALOG,
34
32
  };
35
33
  },
@@ -1,7 +1,7 @@
1
1
  import { nextTick } from 'vue';
2
2
  import { mount } from '@vue/test-utils';
3
3
  import { UI_PLUGINS_REPOS } from '@shell/config/uiplugins';
4
- import AddExtensionRepos from '@shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue';
4
+ import AddExtensionReposDialog from '@shell/dialog/AddExtensionReposDialog.vue';
5
5
  const mockedStore = () => {
6
6
  return {
7
7
  getters: {
@@ -26,19 +26,17 @@ const requiredSetup = () => {
26
26
  };
27
27
  };
28
28
 
29
- describe('component: AddExtensionRepos', () => {
29
+ describe('component: AddExtensionReposDialog', () => {
30
30
  it('should NOT SHOW a checkbox to install official Rancher repo if NOT prime', async() => {
31
31
  jest.useFakeTimers();
32
32
 
33
- const wrapper = mount(AddExtensionRepos, {
33
+ const wrapper = mount(AddExtensionReposDialog, {
34
34
  global: {
35
35
  ...requiredSetup(),
36
36
  stubs: { Dialog: { template: '<span><slot/></span>' } },
37
37
  }
38
38
  });
39
39
 
40
- wrapper.vm.showDialog();
41
-
42
40
  await nextTick();
43
41
 
44
42
  const rancherCheckbox = wrapper.findComponent('[data-testid="add-extensions-repos-modal-add-official-repo"]');
@@ -53,7 +51,7 @@ describe('component: AddExtensionRepos', () => {
53
51
  it('should SHOW a checkbox to install official Rancher repo if IS prime', async() => {
54
52
  jest.useFakeTimers();
55
53
 
56
- const wrapper = mount(AddExtensionRepos, {
54
+ const wrapper = mount(AddExtensionReposDialog, {
57
55
  global: {
58
56
  ...requiredSetup(),
59
57
  stubs: { Dialog: { template: '<span><slot/></span>' } },
@@ -61,7 +59,6 @@ describe('component: AddExtensionRepos', () => {
61
59
  });
62
60
 
63
61
  wrapper.vm.prime = true;
64
- wrapper.vm.showDialog();
65
62
 
66
63
  await nextTick();
67
64
 
@@ -15,14 +15,8 @@ import Tab from '@shell/components/Tabbed/Tab.vue';
15
15
  import IconMessage from '@shell/components/IconMessage.vue';
16
16
  import LazyImage from '@shell/components/LazyImage';
17
17
  import { BadgeState } from '@components/BadgeState';
18
- import UninstallDialog from './UninstallDialog.vue';
19
- import InstallDialog from './InstallDialog.vue';
20
- import CatalogLoadDialog from './CatalogList/CatalogLoadDialog.vue';
21
- import CatalogUninstallDialog from './CatalogList/CatalogUninstallDialog.vue';
22
- import DeveloperInstallDialog from './DeveloperInstallDialog.vue';
23
18
  import PluginInfoPanel from './PluginInfoPanel.vue';
24
19
  import SetupUIPlugins from './SetupUIPlugins.vue';
25
- import AddExtensionRepos from './AddExtensionRepos';
26
20
  import CatalogList from './CatalogList/index.vue';
27
21
  import Banner from '@components/Banner/Banner.vue';
28
22
  import {
@@ -53,20 +47,14 @@ export default {
53
47
  components: {
54
48
  ActionMenu,
55
49
  BadgeState,
56
- DeveloperInstallDialog,
57
50
  IconMessage,
58
51
  CatalogList,
59
52
  Banner,
60
- CatalogLoadDialog,
61
- CatalogUninstallDialog,
62
- InstallDialog,
63
53
  LazyImage,
64
54
  PluginInfoPanel,
65
55
  Tab,
66
56
  Tabbed,
67
- UninstallDialog,
68
57
  SetupUIPlugins,
69
- AddExtensionRepos,
70
58
  TabTitle
71
59
  },
72
60
 
@@ -253,15 +241,13 @@ export default {
253
241
  // Label can be overridden by chart annotation
254
242
  const label = uiPluginAnnotation(chart, UI_PLUGIN_CHART_ANNOTATIONS.DISPLAY_NAME) || chart.chartNameDisplay;
255
243
  const item = {
256
- name: chart.chartName,
244
+ name: chart.chartName,
257
245
  label,
258
- description: chart.chartDescription,
259
- id: chart.id,
260
- versions: [],
261
- installed: false,
262
- builtin: false,
263
- experimental: uiPluginHasAnnotation(chart, CATALOG_ANNOTATIONS.EXPERIMENTAL, 'true'),
264
- certified: uiPluginHasAnnotation(chart, CATALOG_ANNOTATIONS.CERTIFIED, CATALOG_ANNOTATIONS._RANCHER)
246
+ description: chart.chartDescription,
247
+ id: chart.id,
248
+ versions: [],
249
+ installed: false,
250
+ builtin: false,
265
251
  };
266
252
 
267
253
  item.versions = [...chart.versions];
@@ -282,9 +268,15 @@ export default {
282
268
  const latestNotCompatible = item.versions.find((version) => !version.isVersionCompatible);
283
269
 
284
270
  if (latestCompatible) {
271
+ item.experimental = latestCompatible?.annotations?.[CATALOG_ANNOTATIONS.EXPERIMENTAL] === 'true';
272
+ item.certified = latestCompatible?.annotations?.[CATALOG_ANNOTATIONS.CERTIFIED] === CATALOG_ANNOTATIONS._RANCHER;
273
+
285
274
  item.displayVersion = latestCompatible.version;
286
275
  item.icon = latestCompatible.icon;
287
276
  } else {
277
+ item.experimental = uiPluginHasAnnotation(chart, CATALOG_ANNOTATIONS.EXPERIMENTAL, 'true');
278
+ item.certified = uiPluginHasAnnotation(chart, CATALOG_ANNOTATIONS.CERTIFIED, CATALOG_ANNOTATIONS._RANCHER);
279
+
288
280
  item.displayVersion = item.versions?.[0]?.version;
289
281
  item.icon = chart.icon || latestCompatible?.annotations?.['catalog.cattle.io/ui-icon'];
290
282
  }
@@ -323,6 +315,7 @@ export default {
323
315
  if (!chart) {
324
316
  // A plugin is loaded, but there is no chart, so add an item so that it shows up
325
317
  const rancher = typeof p.metadata?.rancher === 'object' ? p.metadata.rancher : {};
318
+
326
319
  const label = rancher.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.DISPLAY_NAME] || p.name;
327
320
  const item = {
328
321
  name: p.name,
@@ -334,6 +327,8 @@ export default {
334
327
  displayVersion: p.metadata?.version || '-',
335
328
  installed: true,
336
329
  builtin: !!p.builtin,
330
+ experimental: rancher?.annotations?.[CATALOG_ANNOTATIONS.EXPERIMENTAL] === 'true',
331
+ certified: rancher?.annotations?.[CATALOG_ANNOTATIONS.CERTIFIED] === CATALOG_ANNOTATIONS._RANCHER
337
332
  };
338
333
 
339
334
  // Built-in plugins can chose to be hidden - used where we implement as extensions
@@ -357,7 +352,15 @@ export default {
357
352
  chart.installing = this.installing[chart.name];
358
353
 
359
354
  // Check for upgrade
355
+ // Use the currently installed version's metadata to show/hide the experimental and certified labels
360
356
  if (chart.installableVersions?.length && p.version !== chart.installableVersions?.[0]?.version) {
357
+ const installedVersion = (chart.installableVersions || []).find((v) => v?.version === p.version);
358
+
359
+ if (installedVersion) {
360
+ chart.experimental = installedVersion?.annotations?.[CATALOG_ANNOTATIONS.EXPERIMENTAL] === 'true';
361
+ chart.certified = installedVersion?.annotations?.[CATALOG_ANNOTATIONS.CERTIFIED] === CATALOG_ANNOTATIONS._RANCHER;
362
+ }
363
+
361
364
  chart.upgrade = chart.installableVersions[0].version;
362
365
  }
363
366
  } else {
@@ -525,21 +528,61 @@ export default {
525
528
 
526
529
  // Developer Load is in the action menu
527
530
  showDeveloperLoadDialog() {
528
- this.$refs.developerInstallDialog.showDialog();
531
+ this.$store.dispatch('management/promptModal', {
532
+ component: 'DeveloperLoadExtensionDialog',
533
+ returnFocusSelector: '[data-testid="extensions-page-menu"]',
534
+ componentProps: {
535
+ closed: (res) => {
536
+ this.didInstall(res);
537
+ }
538
+ }
539
+ });
529
540
  },
530
541
 
531
542
  showAddExtensionReposDialog() {
532
543
  this.updateAddReposSetting();
533
544
  this.refreshCharts(true);
534
- this.$refs.addExtensionReposDialog.showDialog();
545
+
546
+ this.$store.dispatch('management/promptModal', {
547
+ component: 'AddExtensionReposDialog',
548
+ testId: 'add-extensions-repos-modal',
549
+ componentProps: {
550
+ done: () => {
551
+ this.updateInstallStatus(true);
552
+ }
553
+ }
554
+ });
535
555
  },
536
556
 
537
557
  showCatalogLoadDialog() {
538
- this.$refs.catalogLoadDialog.showDialog();
558
+ this.$store.dispatch('management/promptModal', {
559
+ component: 'ExtensionCatalogInstallDialog',
560
+ returnFocusSelector: '[data-testid="extensions-catalog-load-dialog"]',
561
+ componentProps: {
562
+ refresh: () => {
563
+ this.reloadRequired = true;
564
+ },
565
+ closed: (res) => {
566
+ this.didInstall(res);
567
+ }
568
+ }
569
+ });
539
570
  },
540
571
 
541
572
  showCatalogUninstallDialog(ev) {
542
- this.$refs.catalogUninstallDialog.showDialog(ev);
573
+ this.$store.dispatch('management/promptModal', {
574
+ component: 'ExtensionCatalogUninstallDialog',
575
+ returnFocusSelector: '[data-testid="extensions-catalog-load-dialog"]',
576
+ componentProps: {
577
+ catalog: ev,
578
+ refresh: () => {
579
+ this.reloadRequired = true;
580
+ },
581
+ closed: (res) => {
582
+ this.didUninstall(res);
583
+ }
584
+ }
585
+ });
543
586
  },
544
587
 
545
588
  showInstallDialog(plugin, mode, ev) {
@@ -547,7 +590,22 @@ export default {
547
590
  ev.preventDefault();
548
591
  ev.stopPropagation();
549
592
 
550
- this.$refs.installDialog.showDialog(plugin, mode);
593
+ this.$store.dispatch('management/promptModal', {
594
+ component: 'InstallExtensionDialog',
595
+ testId: 'install-extension-modal',
596
+ returnFocusSelector: `[data-testid="extension-card-${ mode }-btn-${ plugin?.name }"]`,
597
+ returnFocusFirstIterableNodeSelector: '#extensions-main-page',
598
+ componentProps: {
599
+ plugin,
600
+ mode,
601
+ updateStatus: (pluginName, type) => {
602
+ this.updatePluginInstallStatus(pluginName, type);
603
+ },
604
+ closed: (res) => {
605
+ this.didInstall(res);
606
+ }
607
+ }
608
+ });
551
609
  },
552
610
 
553
611
  showUninstallDialog(plugin, ev) {
@@ -555,7 +613,21 @@ export default {
555
613
  ev.preventDefault();
556
614
  ev.stopPropagation();
557
615
 
558
- this.$refs.uninstallDialog.showDialog(plugin);
616
+ this.$store.dispatch('management/promptModal', {
617
+ component: 'UninstallExtensionDialog',
618
+ testId: 'uninstall-extension-modal',
619
+ returnFocusSelector: `[data-testid="extension-card-uninstall-btn-${ plugin.name }"]`,
620
+ returnFocusFirstIterableNodeSelector: '#extensions-main-page',
621
+ componentProps: {
622
+ plugin,
623
+ updateStatus: (pluginName, type) => {
624
+ this.updatePluginInstallStatus(pluginName, type);
625
+ },
626
+ closed: (res) => {
627
+ this.didUninstall(res);
628
+ }
629
+ }
630
+ });
559
631
  },
560
632
 
561
633
  didUninstall(plugin) {
@@ -996,35 +1068,6 @@ export default {
996
1068
  </div>
997
1069
  </template>
998
1070
  </div>
999
-
1000
- <InstallDialog
1001
- ref="installDialog"
1002
- @closed="didInstall"
1003
- @update="updatePluginInstallStatus"
1004
- />
1005
- <UninstallDialog
1006
- ref="uninstallDialog"
1007
- @closed="didUninstall"
1008
- @update="updatePluginInstallStatus"
1009
- />
1010
- <CatalogLoadDialog
1011
- ref="catalogLoadDialog"
1012
- @closed="didInstall"
1013
- @refresh="() => reloadRequired = true"
1014
- />
1015
- <CatalogUninstallDialog
1016
- ref="catalogUninstallDialog"
1017
- @closed="didUninstall"
1018
- @refresh="() => reloadRequired = true"
1019
- />
1020
- <DeveloperInstallDialog
1021
- ref="developerInstallDialog"
1022
- @closed="didInstall"
1023
- />
1024
- <AddExtensionRepos
1025
- ref="addExtensionReposDialog"
1026
- @done="updateInstallStatus(true)"
1027
- />
1028
1071
  </div>
1029
1072
  </template>
1030
1073
 
@@ -17,6 +17,7 @@ export default {
17
17
  const finalCounts = [];
18
18
  const promises = [];
19
19
  const topFifteenForResponseTime = [];
20
+ const schemaPromises = [];
20
21
 
21
22
  clusterForCounts.forEach((cluster, i) => {
22
23
  // Necessary to retrieve the proper display name of the cluster
@@ -31,9 +32,11 @@ export default {
31
32
  isTableVisible: !!(i === 0 && clusterForCounts.length === 1)
32
33
  });
33
34
  promises.push(this.$store.dispatch('management/request', { url: `/k8s/clusters/${ cluster.mgmt?.id }/v1/counts` }));
35
+ schemaPromises.push(this.$store.dispatch('management/request', { url: `/k8s/clusters/${ cluster.mgmt?.id }/v1/schemas?exclude=metadata.managedFields` }));
34
36
  });
35
37
 
36
38
  const countsPerCluster = await Promise.all(promises);
39
+ const schemasPerCluster = await Promise.all(schemaPromises);
37
40
 
38
41
  countsPerCluster.forEach((clusterCount, index) => {
39
42
  const counts = clusterCount.data?.[0]?.counts;
@@ -69,9 +72,27 @@ export default {
69
72
 
70
73
  this.topFifteenForResponseTime = topFifteenForResponseTime;
71
74
  this.finalCounts = finalCounts;
75
+
76
+ // Schemas
77
+ schemasPerCluster.forEach((schemas, index) => {
78
+ finalCounts[index].schemaCount = schemas?.data?.length || 0;
79
+ finalCounts[index].customSchemas = (schemas?.data?.filter((schema) => {
80
+ return schema.attributes?.group.includes('.') && !schema.attributes?.group.includes('.cattle.io') && !schema.attributes?.group.includes('.k8s.io');
81
+ }).map((schema) => schema.id) || []).sort();
82
+ });
72
83
  },
73
84
 
74
85
  data() {
86
+ return {
87
+ systemInformation: null,
88
+ topFifteenForResponseTime: null,
89
+ responseTimes: null,
90
+ finalCounts: null,
91
+ includeResponseTimes: true,
92
+ };
93
+ },
94
+
95
+ created() {
75
96
  const {
76
97
  userAgent,
77
98
  userAgentData,
@@ -118,14 +139,7 @@ export default {
118
139
  systemInformation.jsMemory.value += `, ${ this.t('about.diagnostic.systemInformation.memUsedJsHeapSize', { usedJSHeapSize: window?.performance?.memory?.usedJSHeapSize }) }`;
119
140
  }
120
141
 
121
- return {
122
- systemInformation,
123
- topFifteenForResponseTime: null,
124
- responseTimes: null,
125
- finalCounts: null,
126
- includeResponseTimes: true,
127
- storeMapping: this.$store?._modules?.root?.state,
128
- };
142
+ this.systemInformation = systemInformation;
129
143
  },
130
144
 
131
145
  computed: {
@@ -146,9 +160,9 @@ export default {
146
160
  const fileName = 'rancher-diagnostic-data.json';
147
161
  const data = {
148
162
  systemInformation: this.systemInformation,
149
- storeMapping: this.parseStoreData(this.storeMapping),
163
+ storeMapping: this.parseStoreData(this.$store?._modules?.root?.state),
150
164
  resourceCounts: this.finalCounts,
151
- responseTimes: this.responseTimes
165
+ responseTimes: this.responseTimes,
152
166
  };
153
167
 
154
168
  downloadFile(fileName, JSON.stringify(data), 'application/json')
@@ -352,6 +366,7 @@ export default {
352
366
  <span>Cluster: <b>{{ cluster.name }}</b></span>
353
367
  <span>Namespace: <b>{{ cluster.namespace }}</b></span>
354
368
  <span>Total Resources: <b>{{ sumResourceCount(cluster.counts) }}</b></span>
369
+ <span>Total Schemas: <b>{{ cluster.schemaCount }}</b></span>
355
370
  <span>Nodes: <b>{{ nodeCount(cluster.counts) }}</b></span>
356
371
  <i
357
372
  class="icon"
@@ -365,6 +380,22 @@ export default {
365
380
  </tr>
366
381
  </thead>
367
382
  <tbody v-show="cluster.isTableVisible">
383
+ <tr>
384
+ <td colspan="3">
385
+ <div class="schema-title">
386
+ Custom Schemas
387
+ </div>
388
+ <div class="custom-schemas">
389
+ <div
390
+ v-for="name in cluster.customSchemas"
391
+ :key="name"
392
+ class="schema-name"
393
+ >
394
+ {{ name }}
395
+ </div>
396
+ </div>
397
+ </td>
398
+ </tr>
368
399
  <tr>
369
400
  <th>
370
401
  Resource
@@ -445,6 +476,23 @@ table {
445
476
  padding: 8px 5px;
446
477
  min-width: 150px;
447
478
  text-align: left;
479
+
480
+ .schema-title {
481
+ font-weight: bold;
482
+ margin-bottom: 4px;
483
+ }
484
+
485
+ .custom-schemas {
486
+ display: flex;
487
+ flex-wrap: wrap;
488
+
489
+ > .schema-name {
490
+ margin-right: 5px;
491
+ margin-bottom: 2px;
492
+ border: 1px solid var(--border);
493
+ padding: 2px 5px;
494
+ }
495
+ }
448
496
  }
449
497
 
450
498
  th {
@@ -511,7 +559,7 @@ table {
511
559
  .resources-count-container {
512
560
  .cluster-row {
513
561
  display: grid;
514
- grid-template-columns: repeat(4, 1fr) 20px;
562
+ grid-template-columns: repeat(5, 1fr) 20px;
515
563
  grid-template-rows: 1fr;
516
564
  align-content: center;
517
565
  font-weight: normal;
@@ -17,17 +17,19 @@ export default {
17
17
  mixins: [Brand, BrowserTabVisibility],
18
18
 
19
19
  data() {
20
+ return {
21
+ previousRoute: '',
22
+ styles: { '--custom-content': `'${ this.t('nav.failWhale.separator') }'` }
23
+ };
24
+ },
25
+
26
+ created() {
20
27
  const store = this.$store;
21
28
 
22
29
  if (!store.state.error && !store.state.cameFromError) {
23
30
  store.commit('cameFromError');
24
31
  this.$router.replace('/');
25
32
  }
26
-
27
- return {
28
- previousRoute: '',
29
- styles: { '--custom-content': `'${ this.t('nav.failWhale.separator') }'` }
30
- };
31
33
  },
32
34
 
33
35
  computed: {
@@ -70,12 +72,15 @@ export default {
70
72
  :simple="true"
71
73
  />
72
74
 
73
- <main class="main-layout">
75
+ <main
76
+ class="main-layout"
77
+ aria-label="Fail whale layout"
78
+ >
74
79
  <div
75
80
  v-if="error"
76
81
  class="outlet"
77
82
  >
78
- <main class="main-layout error">
83
+ <div class="main-layout error">
79
84
  <div class="text-center">
80
85
  <BrandImage
81
86
  file-name="error-desert-landscape.svg"
@@ -105,6 +110,7 @@ export default {
105
110
  <hr
106
111
  class="custom-content"
107
112
  :style="styles"
113
+ role="none"
108
114
  >
109
115
  <p class="mt-20">
110
116
  <a
@@ -115,7 +121,7 @@ export default {
115
121
  </a>
116
122
  </p>
117
123
  </div>
118
- </main>
124
+ </div>
119
125
  </div>
120
126
  </main>
121
127
  </div>