@rancher/shell 3.0.5-rc.2 → 3.0.5-rc.5

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 (289) hide show
  1. package/assets/data/aws-regions.json +2 -0
  2. package/assets/images/icons/document.svg +3 -0
  3. package/assets/images/vendor/cognito.svg +1 -0
  4. package/assets/styles/app.scss +1 -0
  5. package/assets/styles/base/_basic.scss +10 -0
  6. package/assets/styles/base/_spacing.scss +29 -0
  7. package/assets/styles/global/_layout.scss +1 -2
  8. package/assets/styles/themes/_dark.scss +25 -0
  9. package/assets/styles/themes/_light.scss +65 -0
  10. package/assets/translations/en-us.yaml +377 -37
  11. package/assets/translations/zh-hans.yaml +8 -15
  12. package/chart/monitoring/index.vue +1 -1
  13. package/components/AsyncButton.vue +2 -0
  14. package/components/Certificates.vue +5 -0
  15. package/components/CodeMirror.vue +3 -3
  16. package/components/CruResource.vue +103 -15
  17. package/components/ExplorerProjectsNamespaces.vue +7 -2
  18. package/components/FilterPanel.vue +156 -0
  19. package/components/FixedBanner.vue +19 -5
  20. package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
  21. package/components/IconOrSvg.vue +14 -35
  22. package/components/PaginatedResourceTable.vue +7 -0
  23. package/components/PromptRemove.vue +5 -1
  24. package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
  25. package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
  26. package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
  27. package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
  28. package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
  29. package/components/Resource/Detail/Card/Scaler.vue +89 -0
  30. package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
  31. package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
  32. package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
  33. package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
  34. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
  35. package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
  36. package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
  37. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
  38. package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
  39. package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
  40. package/components/Resource/Detail/Card/index.vue +56 -0
  41. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
  42. package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
  43. package/components/Resource/Detail/Metadata/Annotations/index.vue +26 -0
  44. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
  45. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +281 -0
  46. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +111 -0
  47. package/components/Resource/Detail/Metadata/KeyValue.vue +130 -0
  48. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
  49. package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
  50. package/components/Resource/Detail/Metadata/Labels/index.vue +27 -0
  51. package/components/Resource/Detail/Metadata/Rectangle.vue +32 -0
  52. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
  53. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
  54. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
  55. package/components/Resource/Detail/Metadata/composables.ts +29 -0
  56. package/components/Resource/Detail/Metadata/index.vue +66 -0
  57. package/components/Resource/Detail/Page.vue +22 -0
  58. package/components/Resource/Detail/PercentageBar.vue +40 -0
  59. package/components/Resource/Detail/ResourceRow.vue +119 -0
  60. package/components/Resource/Detail/SpacedRow.vue +14 -0
  61. package/components/Resource/Detail/StatusBar.vue +59 -0
  62. package/components/Resource/Detail/StatusRow.vue +61 -0
  63. package/components/Resource/Detail/TitleBar/Title.vue +13 -0
  64. package/components/Resource/Detail/TitleBar/Top.vue +14 -0
  65. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
  66. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
  67. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
  68. package/components/Resource/Detail/TitleBar/composable.ts +31 -0
  69. package/components/Resource/Detail/TitleBar/index.vue +124 -0
  70. package/components/Resource/Detail/Top/index.vue +34 -0
  71. package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
  72. package/components/ResourceDetail/Masthead.vue +0 -1
  73. package/components/ResourceDetail/__tests__/index.test.ts +114 -0
  74. package/components/ResourceDetail/index.vue +64 -562
  75. package/components/ResourceDetail/legacy.vue +545 -0
  76. package/components/ResourceList/index.vue +2 -1
  77. package/components/ResourceTable.vue +41 -7
  78. package/components/SlideInPanelManager.vue +77 -10
  79. package/components/SortableTable/index.vue +13 -2
  80. package/components/SortableTable/selection.js +22 -9
  81. package/components/StatusBadge.vue +6 -4
  82. package/components/SubtleLink.vue +25 -0
  83. package/components/Tabbed/index.vue +6 -0
  84. package/components/Wizard.vue +12 -1
  85. package/components/YamlEditor.vue +1 -1
  86. package/components/__tests__/AsyncButton.test.ts +39 -0
  87. package/components/__tests__/CruResource.test.ts +63 -0
  88. package/components/__tests__/FilterPanel.test.ts +81 -0
  89. package/components/__tests__/PromptModal.test.ts +0 -2
  90. package/components/auth/AuthBanner.vue +2 -3
  91. package/components/auth/RoleDetailEdit.vue +45 -3
  92. package/components/auth/login/oidc.vue +6 -1
  93. package/components/fleet/FleetApplications.vue +181 -0
  94. package/components/fleet/FleetHelmOps.vue +115 -0
  95. package/components/fleet/FleetIntro.vue +58 -28
  96. package/components/fleet/FleetNoWorkspaces.vue +5 -1
  97. package/components/fleet/FleetOCIStorageSecret.vue +171 -0
  98. package/components/fleet/FleetRepos.vue +38 -76
  99. package/components/fleet/FleetResources.vue +50 -22
  100. package/components/fleet/FleetSummary.vue +26 -51
  101. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
  102. package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
  103. package/components/fleet/dashboard/Empty.vue +73 -0
  104. package/components/fleet/dashboard/ResourceCard.vue +183 -0
  105. package/components/fleet/dashboard/ResourceCardSummary.vue +199 -0
  106. package/components/fleet/dashboard/ResourceDetails.vue +196 -0
  107. package/components/fleet/dashboard/ResourcePanel.vue +376 -0
  108. package/components/form/ArrayList.vue +139 -117
  109. package/components/form/BannerSettings.vue +145 -96
  110. package/components/form/KeyValue.vue +10 -7
  111. package/components/form/LabeledSelect.vue +9 -2
  112. package/components/form/MatchExpressions.vue +5 -1
  113. package/components/form/NameNsDescription.vue +1 -1
  114. package/components/form/ResourceSelector.vue +26 -23
  115. package/components/form/ResourceTabs/index.vue +2 -1
  116. package/components/form/Select.vue +9 -2
  117. package/components/form/SimpleSecretSelector.vue +8 -2
  118. package/components/form/UnitInput.vue +13 -0
  119. package/components/form/ValueFromResource.vue +31 -19
  120. package/components/form/__tests__/ArrayList.test.ts +32 -0
  121. package/components/form/__tests__/KeyValue.test.ts +36 -0
  122. package/components/form/__tests__/LabeledSelect.test.ts +33 -0
  123. package/components/form/__tests__/Select.test.ts +34 -1
  124. package/components/form/__tests__/UnitInput.test.ts +23 -1
  125. package/components/formatter/ClusterLink.vue +5 -8
  126. package/components/formatter/Description.vue +30 -0
  127. package/components/formatter/FleetApplicationClustersReady.vue +77 -0
  128. package/components/formatter/FleetApplicationSource.vue +71 -0
  129. package/components/formatter/FleetSummaryGraph.vue +7 -0
  130. package/components/formatter/__tests__/ClusterLink.test.ts +2 -32
  131. package/components/nav/Header.vue +8 -7
  132. package/components/nav/NamespaceFilter.vue +1 -1
  133. package/components/nav/TopLevelMenu.helper.ts +55 -34
  134. package/components/nav/TopLevelMenu.vue +11 -0
  135. package/components/nav/Type.vue +4 -1
  136. package/components/nav/WindowManager/index.vue +1 -0
  137. package/composables/useI18n.ts +12 -11
  138. package/config/labels-annotations.js +14 -11
  139. package/config/product/auth.js +1 -0
  140. package/config/product/explorer.js +16 -13
  141. package/config/product/fleet.js +70 -17
  142. package/config/product/manager.js +1 -28
  143. package/config/query-params.js +3 -1
  144. package/config/roles.ts +1 -0
  145. package/config/router/routes.js +20 -2
  146. package/config/secret.ts +15 -0
  147. package/config/settings.ts +14 -15
  148. package/config/table-headers.js +59 -27
  149. package/config/types.js +2 -0
  150. package/core/plugin-helpers.ts +3 -2
  151. package/detail/catalog.cattle.io.app.vue +0 -1
  152. package/detail/fleet.cattle.io.cluster.vue +28 -15
  153. package/detail/fleet.cattle.io.gitrepo.vue +10 -1
  154. package/detail/fleet.cattle.io.helmop.vue +157 -0
  155. package/detail/provisioning.cattle.io.cluster.vue +13 -3
  156. package/detail/service.vue +0 -1
  157. package/detail/workload/index.vue +21 -34
  158. package/dialog/ExtensionCatalogUninstallDialog.vue +14 -8
  159. package/dialog/HelmOpForceUpdateDialog.vue +132 -0
  160. package/dialog/RedeployWorkloadDialog.vue +164 -0
  161. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +56 -67
  162. package/edit/__tests__/service.test.ts +2 -1
  163. package/edit/auth/oidc.vue +159 -93
  164. package/edit/fleet.cattle.io.gitrepo.vue +26 -33
  165. package/edit/fleet.cattle.io.helmop.vue +997 -0
  166. package/edit/management.cattle.io.fleetworkspace.vue +43 -10
  167. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -14
  168. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +57 -62
  169. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +3 -14
  170. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.test.ts +72 -41
  171. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +17 -1
  172. package/edit/networking.k8s.io.networkpolicy/index.vue +18 -30
  173. package/edit/provisioning.cattle.io.cluster/index.vue +21 -73
  174. package/edit/service.vue +13 -28
  175. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  176. package/list/fleet.cattle.io.helmop.vue +108 -0
  177. package/list/namespace.vue +5 -2
  178. package/list/workload.vue +6 -1
  179. package/mixins/auth-config.js +8 -1
  180. package/mixins/preset.js +100 -0
  181. package/mixins/resource-fetch-api-pagination.js +57 -43
  182. package/mixins/resource-fetch.js +15 -6
  183. package/mixins/resource-table-watch.js +45 -0
  184. package/models/__tests__/chart.test.ts +273 -0
  185. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
  186. package/models/__tests__/workload.test.ts +1 -0
  187. package/models/chart.js +144 -2
  188. package/models/cluster/node.js +1 -0
  189. package/models/cluster.js +32 -2
  190. package/models/fleet-application.js +385 -0
  191. package/models/fleet.cattle.io.bundle.js +9 -8
  192. package/models/fleet.cattle.io.gitrepo.js +41 -365
  193. package/models/fleet.cattle.io.helmop.js +228 -0
  194. package/models/management.cattle.io.authconfig.js +1 -0
  195. package/models/management.cattle.io.cluster.js +0 -20
  196. package/models/management.cattle.io.fleetworkspace.js +12 -0
  197. package/models/management.cattle.io.node.js +7 -22
  198. package/models/management.cattle.io.nodepool.js +12 -0
  199. package/models/namespace.js +5 -0
  200. package/models/provisioning.cattle.io.cluster.js +18 -64
  201. package/models/service.js +24 -9
  202. package/models/workload.js +84 -49
  203. package/package.json +2 -1
  204. package/pages/auth/verify.vue +13 -1
  205. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +37 -0
  206. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
  207. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +54 -0
  208. package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
  209. package/pages/c/_cluster/apps/charts/index.vue +302 -484
  210. package/pages/c/_cluster/apps/charts/install.vue +0 -1
  211. package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
  212. package/pages/c/_cluster/explorer/index.vue +11 -0
  213. package/pages/c/_cluster/fleet/__tests__/index.test.ts +426 -0
  214. package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
  215. package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
  216. package/pages/c/_cluster/fleet/application/create.vue +340 -0
  217. package/pages/c/_cluster/fleet/application/index.vue +139 -0
  218. package/pages/c/_cluster/fleet/graph/config.js +277 -0
  219. package/pages/c/_cluster/fleet/index.vue +772 -330
  220. package/pages/c/_cluster/longhorn/index.vue +2 -2
  221. package/pages/c/_cluster/settings/banners.vue +56 -2
  222. package/pages/c/_cluster/settings/performance.vue +7 -26
  223. package/pages/explorer/resource/detail/configmap.vue +19 -0
  224. package/pages/home.vue +11 -52
  225. package/plugins/clean-html.js +2 -0
  226. package/plugins/dashboard-store/__tests__/actions.test.ts +4 -1
  227. package/plugins/dashboard-store/actions.js +153 -30
  228. package/plugins/dashboard-store/getters.js +108 -24
  229. package/plugins/dashboard-store/mutations.js +61 -12
  230. package/plugins/dashboard-store/resource-class.js +36 -4
  231. package/plugins/steve/__tests__/getters.test.ts +18 -11
  232. package/plugins/steve/__tests__/steve-class.test.ts +1 -0
  233. package/plugins/steve/__tests__/subscribe.spec.ts +66 -1
  234. package/plugins/steve/actions.js +37 -12
  235. package/plugins/steve/getters.js +39 -10
  236. package/plugins/steve/steve-class.js +5 -0
  237. package/plugins/steve/steve-pagination-utils.ts +213 -50
  238. package/plugins/steve/subscribe.js +229 -42
  239. package/plugins/steve/worker/web-worker.advanced.js +3 -1
  240. package/rancher-components/BadgeState/BadgeState.vue +3 -1
  241. package/rancher-components/Banner/Banner.test.ts +51 -3
  242. package/rancher-components/Banner/Banner.vue +28 -6
  243. package/rancher-components/Form/Checkbox/Checkbox.vue +2 -2
  244. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +5 -1
  245. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +21 -1
  246. package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
  247. package/rancher-components/RcItemCard/RcItemCard.vue +425 -0
  248. package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
  249. package/rancher-components/RcItemCard/index.ts +2 -0
  250. package/store/auth.js +1 -0
  251. package/store/catalog.js +62 -24
  252. package/store/features.js +0 -1
  253. package/store/index.js +33 -14
  254. package/store/slideInPanel.ts +6 -0
  255. package/store/type-map.js +1 -0
  256. package/store/type-map.utils.ts +45 -2
  257. package/types/fleet.d.ts +36 -1
  258. package/types/kube/kube-api.ts +22 -0
  259. package/types/resources/settings.d.ts +19 -5
  260. package/types/shell/index.d.ts +595 -471
  261. package/types/store/dashboard-store.types.ts +41 -4
  262. package/types/store/pagination.types.ts +25 -3
  263. package/types/store/subscribe.types.ts +50 -0
  264. package/utils/auth.js +32 -3
  265. package/utils/cluster.js +24 -20
  266. package/utils/fleet-types.ts +0 -0
  267. package/utils/fleet.ts +200 -1
  268. package/utils/grafana.js +1 -0
  269. package/utils/object.js +0 -12
  270. package/utils/pagination-utils.ts +32 -3
  271. package/utils/pagination-wrapper.ts +132 -50
  272. package/utils/perf-setting.utils.ts +28 -0
  273. package/utils/selector-typed.ts +205 -0
  274. package/utils/selector.js +29 -6
  275. package/utils/settings.ts +4 -1
  276. package/utils/style.ts +39 -0
  277. package/utils/uiplugins.ts +10 -6
  278. package/utils/v-sphere.ts +5 -1
  279. package/utils/validators/formRules/__tests__/index.test.ts +36 -3
  280. package/utils/validators/formRules/index.ts +10 -3
  281. package/utils/window.js +11 -7
  282. package/components/__tests__/ApplicationCard.test.ts +0 -27
  283. package/components/cards/ApplicationCard.vue +0 -145
  284. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
  285. package/components/formatter/RKETemplateName.vue +0 -37
  286. package/config/secret.js +0 -14
  287. package/dialog/SaveAsRKETemplateDialog.vue +0 -139
  288. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
  289. /package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +0 -0
@@ -0,0 +1,77 @@
1
+ <script>
2
+
3
+ export default {
4
+ name: 'FleetApplicationClustersReady',
5
+
6
+ components: {},
7
+
8
+ props: {
9
+ value: {
10
+ type: Number,
11
+ default: 0
12
+ },
13
+
14
+ row: {
15
+ type: Object,
16
+ required: true
17
+ },
18
+
19
+ col: {
20
+ type: Object,
21
+ default: () => {}
22
+ },
23
+
24
+ rowKey: {
25
+ type: String,
26
+ default: '',
27
+ },
28
+
29
+ getCustomDetailLink: {
30
+ type: Function,
31
+ default: null
32
+ },
33
+ },
34
+
35
+ methods: {
36
+ parseTargetMode(row) {
37
+ return row.targetInfo?.mode === 'clusterGroup' ? this.t('fleet.application.warningTooltip.clusterGroup') : this.t('fleet.application.warningTooltip.cluster');
38
+ },
39
+ },
40
+ };
41
+ </script>
42
+
43
+ <template>
44
+ <span
45
+ v-if="!row.clusterInfo"
46
+ class="text-muted"
47
+ >&mdash;</span>
48
+ <span
49
+ v-else-if="row.clusterInfo.unready"
50
+ class="text-warning"
51
+ >{{ row.clusterInfo.ready }}/{{
52
+ row.clusterInfo.total }}</span>
53
+ <span
54
+ v-else
55
+ class="cluster-count-info"
56
+ >
57
+ {{ row.clusterInfo.ready }}/{{ row.clusterInfo.total }}
58
+ <i
59
+ v-if="!row.clusterInfo.total"
60
+ v-clean-tooltip.bottom="parseTargetMode(row)"
61
+ class="icon icon-warning"
62
+ />
63
+ </span>
64
+ </template>
65
+
66
+ <style lang="scss" scoped>
67
+ .cluster-count-info {
68
+ display: flex;
69
+ align-items: center;
70
+
71
+ i {
72
+ margin-left: 5px;
73
+ font-size: 22px;
74
+ color: var(--warning);
75
+ }
76
+ }
77
+ </style>
@@ -0,0 +1,71 @@
1
+ <script>
2
+ import Link from '@shell/components/formatter/Link';
3
+ import Shortened from '@shell/components/formatter/Shortened';
4
+
5
+ export default {
6
+ name: 'FleetApplicationSource',
7
+
8
+ components: {
9
+ Link,
10
+ Shortened,
11
+ },
12
+
13
+ props: {
14
+ value: {
15
+ type: String,
16
+ default: ''
17
+ },
18
+
19
+ row: {
20
+ type: Object,
21
+ required: true
22
+ },
23
+
24
+ col: {
25
+ type: Object,
26
+ default: () => {}
27
+ },
28
+
29
+ rowKey: {
30
+ type: String,
31
+ default: '',
32
+ },
33
+
34
+ getCustomDetailLink: {
35
+ type: Function,
36
+ default: null
37
+ }
38
+ },
39
+ };
40
+ </script>
41
+
42
+ <template>
43
+ <template v-if="row.source.showLink">
44
+ <Link
45
+ class="source-link"
46
+ label-key="source.display"
47
+ before-icon-key="source.icon"
48
+ url-key="source.value"
49
+ :row="row"
50
+ :value="row.source.value || ''"
51
+ />
52
+ <template v-if="row.source.value && row.sourceSub.value">
53
+ <div class="text-muted">
54
+ <Shortened
55
+ long-value-key="sourceSub.value"
56
+ :row="row"
57
+ :value="row.sourceSub.display"
58
+ />
59
+ </div>
60
+ </template>
61
+ </template>
62
+ <span v-else>
63
+ {{ row.source.value }}
64
+ </span>
65
+ </template>
66
+
67
+ <style lang="scss" scoped>
68
+ .source-link {
69
+ width: fit-content;
70
+ }
71
+ </style>
@@ -119,4 +119,11 @@ export default {
119
119
  padding: 0;
120
120
  line-height: initial;
121
121
  }
122
+
123
+ .hand {
124
+ .progress, .progress > .piece {
125
+ height: 6px;
126
+ border-right: 1px solid var(--body-bg);
127
+ }
128
+ }
122
129
  </style>
@@ -3,7 +3,6 @@ import ClusterLink from '@shell/components/formatter/ClusterLink.vue';
3
3
 
4
4
  describe('component: ClusterLink', () => {
5
5
  const UNAVAILABLE_MACHINES_ICON_SELECTOR = '[data-testid="unavailable-machines-alert-icon"]';
6
- const TEMPLATE_UPGRADE_ICON_SELECTOR = '[data-testid="rke-template-upgrade-alert-icon"]';
7
6
  const CONDITION_HAS_ERROR_ICON_SELECTOR = '[data-testid="conditions-has-error-icon"]';
8
7
 
9
8
  describe('unavailable machines alert icon', () => {
@@ -20,10 +19,9 @@ describe('component: ClusterLink', () => {
20
19
  const wrapper = mount(ClusterLink, {
21
20
  props: {
22
21
  row: {
23
- hasError: false,
24
- status: {},
22
+ hasError: false,
23
+ status: {},
25
24
  unavailableMachines,
26
- rkeTemplateUpgrade: undefined
27
25
  },
28
26
  reference: 'any',
29
27
  value: 'any'
@@ -36,34 +34,6 @@ describe('component: ClusterLink', () => {
36
34
  );
37
35
  });
38
36
 
39
- describe('template upgrade alert icon', () => {
40
- const testCases = [
41
- [undefined, false],
42
- ['any', true],
43
- ];
44
-
45
- it.each(testCases)(
46
- 'should show/hide properly based on rkeTemplateUpgrade',
47
- (rkeTemplateUpgrade, expected) => {
48
- const wrapper = mount(ClusterLink, {
49
- props: {
50
- row: {
51
- hasError: false,
52
- status: {},
53
- unavailableMachines: 0,
54
- rkeTemplateUpgrade
55
- },
56
- reference: 'any',
57
- value: 'any'
58
- }
59
- });
60
- const el = wrapper.find(TEMPLATE_UPGRADE_ICON_SELECTOR);
61
-
62
- expect(el.exists()).toBe(expected);
63
- }
64
- );
65
- });
66
-
67
37
  describe('conditions has error icon', () => {
68
38
  const MOCKED_CONDITIONS_1 = [{
69
39
  status: '', type: 'Ready', reason: 'Waiting', error: true // When the only existing error has a type "Ready" and reason "Waiting"
@@ -93,7 +93,8 @@ export default {
93
93
  'isSingleProduct',
94
94
  'isRancherInHarvester',
95
95
  'showTopLevelMenu',
96
- 'isMultiCluster'
96
+ 'isMultiCluster',
97
+ 'showWorkspaceSwitcher'
97
98
  ]),
98
99
 
99
100
  samlAuthProviderEnabled() {
@@ -238,16 +239,16 @@ export default {
238
239
  },
239
240
 
240
241
  watch: {
241
- currentCluster(nue, old) {
242
- if (nue && old && nue.id !== old.id) {
242
+ currentCluster(neu, old) {
243
+ if (neu && old && neu.id !== old.id) {
243
244
  this.checkClusterName();
244
245
  }
245
246
  },
246
247
  // since the Header is a "persistent component" we need to update it at every route change...
247
248
  $route: {
248
- handler(nue) {
249
- if (nue) {
250
- this.extensionHeaderActions = getApplicableExtensionEnhancements(this, ExtensionPoint.ACTION, ActionLocation.HEADER, nue);
249
+ handler(neu) {
250
+ if (neu) {
251
+ this.extensionHeaderActions = getApplicableExtensionEnhancements(this, ExtensionPoint.ACTION, ActionLocation.HEADER, neu);
251
252
 
252
253
  this.navHeaderRight = this.$plugin?.getDynamic('component', 'NavHeaderRight');
253
254
  }
@@ -533,7 +534,7 @@ export default {
533
534
  class="top"
534
535
  >
535
536
  <NamespaceFilter v-if="clusterReady && currentProduct && (currentProduct.showNamespaceFilter || isExplorer)" />
536
- <WorkspaceSwitcher v-else-if="clusterReady && currentProduct && currentProduct.showWorkspaceSwitcher" />
537
+ <WorkspaceSwitcher v-else-if="clusterReady && currentProduct && currentProduct.showWorkspaceSwitcher && showWorkspaceSwitcher" />
537
538
  </div>
538
539
  <div
539
540
  v-if="currentCluster && !simple"
@@ -702,7 +702,7 @@ export default {
702
702
  data-testid="namespaces-filter"
703
703
  tabindex="0"
704
704
  @mousedown.prevent
705
- @keydown.down.enter.space.prevent="open"
705
+ @keydown.self.down.enter.space.prevent="open"
706
706
  >
707
707
  <div
708
708
  v-if="isOpen"
@@ -1,10 +1,12 @@
1
1
  import { CAPI, MANAGEMENT } from '@shell/config/types';
2
+ import { STORE } from '@shell/store/store-types';
2
3
  import { PaginationParam, PaginationParamFilter, PaginationSort } from '@shell/types/store/pagination.types';
3
4
  import { VuexStore } from '@shell/types/store/vuex';
4
5
  import { filterHiddenLocalCluster, filterOnlyKubernetesClusters, paginationFilterClusters } from '@shell/utils/cluster';
5
6
  import PaginationWrapper from '@shell/utils/pagination-wrapper';
6
7
  import { allHash } from '@shell/utils/promise';
7
8
  import { sortBy } from '@shell/utils/sort';
9
+ import { reactive } from 'vue';
8
10
  import { LocationAsRelativeRaw } from 'vue-router';
9
11
 
10
12
  interface TopLevelMenuCluster {
@@ -86,7 +88,15 @@ export interface TopLevelMenuHelper {
86
88
  */
87
89
  clustersOthers: Array<TopLevelMenuCluster>;
88
90
 
89
- update: (args: UpdateArgs) => Promise<void>
91
+ /**
92
+ * Fetch all cluster resources
93
+ */
94
+ update: (args: UpdateArgs) => Promise<void>;
95
+
96
+ /**
97
+ * Cleanup on destroy of TopLevelMenu
98
+ */
99
+ destroy: () => Promise<void>;
90
100
  }
91
101
 
92
102
  export abstract class BaseTopLevelMenuHelper {
@@ -106,7 +116,7 @@ export abstract class BaseTopLevelMenuHelper {
106
116
  * 2. ready
107
117
  * 3. name
108
118
  */
109
- public clustersPinned: Array<TopLevelMenuCluster> = [];
119
+ public clustersPinned: Array<TopLevelMenuCluster> = reactive([]);
110
120
 
111
121
  /**
112
122
  * Filter mgmt clusters by
@@ -121,7 +131,7 @@ export abstract class BaseTopLevelMenuHelper {
121
131
  * 2. ready
122
132
  * 3. name
123
133
  */
124
- public clustersOthers: Array<TopLevelMenuCluster> = [];
134
+ public clustersOthers: Array<TopLevelMenuCluster> = reactive([]);
125
135
 
126
136
  constructor({ $store }: {
127
137
  $store: VuexStore,
@@ -141,7 +151,7 @@ export abstract class BaseTopLevelMenuHelper {
141
151
  return {
142
152
  id: mgmtCluster.id,
143
153
  label: mgmtCluster.nameDisplay,
144
- ready: mgmtCluster.isReady, // && !provCluster?.hasError,
154
+ ready: mgmtCluster.isReady,
145
155
  providerNavLogo: mgmtCluster.providerMenuLogo,
146
156
  badge: mgmtCluster.badge,
147
157
  iconColor: mgmtCluster.iconColor,
@@ -165,69 +175,64 @@ export abstract class BaseTopLevelMenuHelper {
165
175
  export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper implements TopLevelMenuHelper {
166
176
  private args?: UpdateArgs;
167
177
 
168
- private clustersPinnedWrapper: PaginationWrapper;
169
- private clustersOthersWrapper: PaginationWrapper;
170
- private provClusterWrapper: PaginationWrapper;
171
-
172
- private commonClusterFilters: PaginationParam[];
178
+ private clustersPinnedWrapper: PaginationWrapper<any>;
179
+ private clustersOthersWrapper: PaginationWrapper<any>;
180
+ private provClusterWrapper: PaginationWrapper<any>;
173
181
 
174
182
  constructor({ $store }: {
175
183
  $store: VuexStore,
176
184
  }) {
177
185
  super({ $store });
178
186
 
179
- this.commonClusterFilters = paginationFilterClusters({ getters: this.$store.getters });
180
-
187
+ // Fetch all PINNED clusters (see `clustersPinned` description for details)
188
+ // No need to monitor for changes, the UNPINNED request will handle it
181
189
  this.clustersPinnedWrapper = new PaginationWrapper({
182
190
  $store,
183
- onUpdate: () => {
184
- // trigger on websocket update (only need 1 trigger for this cluster type)
185
- // https://github.com/rancher/rancher/issues/40773 / https://github.com/rancher/dashboard/issues/12734
186
- if (this.args) {
187
- this.update(this.args);
188
- }
189
- },
191
+ id: 'tlm-pinned-clusters',
190
192
  enabledFor: {
191
- store: 'management',
193
+ store: STORE.MANAGEMENT,
192
194
  resource: {
193
195
  id: MANAGEMENT.CLUSTER,
194
196
  context: 'side-bar',
195
197
  }
196
- }
198
+ },
199
+ formatResponse: { classify: true }
197
200
  });
201
+ // Fetch all UNPINNED clusters capped at 10 (see `clustersOthers` description for details)
198
202
  this.clustersOthersWrapper = new PaginationWrapper({
199
203
  $store,
200
- onUpdate: (res) => {
201
- // trigger on websocket update (only need 1 trigger for this cluster type)
202
- // https://github.com/rancher/rancher/issues/40773 / https://github.com/rancher/dashboard/issues/12734
204
+ id: 'tlm-unpinned-clusters',
205
+ onChange: () => {
203
206
  if (this.args) {
204
207
  this.update(this.args);
205
208
  }
206
209
  },
207
210
  enabledFor: {
208
- store: 'management',
211
+ store: STORE.MANAGEMENT,
209
212
  resource: {
210
213
  id: MANAGEMENT.CLUSTER,
211
214
  context: 'side-bar',
212
215
  }
213
- }
216
+ },
217
+ formatResponse: { classify: true }
214
218
  });
219
+ // Fetch all prov clusters for the mgmt clusters we have
215
220
  this.provClusterWrapper = new PaginationWrapper({
216
221
  $store,
217
- onUpdate: (res) => {
218
- // trigger on websocket update (only need 1 trigger for this cluster type)
219
- // https://github.com/rancher/rancher/issues/40773 / https://github.com/rancher/dashboard/issues/12734
222
+ id: 'tlm-prov-clusters',
223
+ onChange: () => {
220
224
  if (this.args) {
221
225
  this.update(this.args);
222
226
  }
223
227
  },
224
228
  enabledFor: {
225
- store: 'management',
229
+ store: STORE.MANAGEMENT,
226
230
  resource: {
227
231
  id: CAPI.RANCHER_CLUSTER,
228
232
  context: 'side-bar',
229
233
  }
230
- }
234
+ },
235
+ formatResponse: { classify: true }
231
236
  });
232
237
  }
233
238
 
@@ -258,6 +263,7 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
258
263
  return res;
259
264
  }, {} as { [mgmtId: string]: ProvCluster});
260
265
 
266
+ // Filter out mgmt clusters that don't have matching prov cluster and convert remaining to required format
261
267
  const _clustersNotPinned = res.notPinned
262
268
  .filter((mgmtCluster) => !!provClustersByMgmtId[mgmtCluster.id])
263
269
  .map((mgmtCluster) => this.convertToCluster(mgmtCluster, provClustersByMgmtId[mgmtCluster.id]));
@@ -274,6 +280,19 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
274
280
  this.cacheClusters();
275
281
  }
276
282
 
283
+ async destroy() {
284
+ this.clustersPinnedWrapper.onDestroy();
285
+ this.clustersOthersWrapper.onDestroy();
286
+ this.provClusterWrapper.onDestroy();
287
+ }
288
+
289
+ /**
290
+ * Helper function
291
+ *
292
+ * This extracts all the functionality previously in TopLevelMenu
293
+ *
294
+ * Construct SSP filter params
295
+ */
277
296
  private constructParams({
278
297
  pinnedIds,
279
298
  searchTerm,
@@ -289,7 +308,8 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
289
308
  includePinned?: boolean,
290
309
  excludePinned?: boolean,
291
310
  }): PaginationParam[] {
292
- const filters: PaginationParam[] = [...this.commonClusterFilters];
311
+ const commonClusterFilters = paginationFilterClusters({ getters: this.$store.getters });
312
+ const filters: PaginationParam[] = [...commonClusterFilters];
293
313
 
294
314
  if (pinnedIds) {
295
315
  if (includePinned) {
@@ -341,7 +361,6 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
341
361
  sort: DEFAULT_SORT,
342
362
  projectsOrNamespaces: []
343
363
  },
344
- classify: true,
345
364
  }).then((r) => r.data);
346
365
  }
347
366
 
@@ -362,7 +381,6 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
362
381
  sort: DEFAULT_SORT,
363
382
  projectsOrNamespaces: []
364
383
  },
365
- classify: true,
366
384
  }).then((r) => r.data);
367
385
  }
368
386
 
@@ -386,7 +404,6 @@ export class TopLevelMenuHelperPagination extends BaseTopLevelMenuHelper impleme
386
404
  sort: [],
387
405
  projectsOrNamespaces: []
388
406
  },
389
- classify: true,
390
407
  }).then((r) => r.data);
391
408
  }
392
409
  }
@@ -419,6 +436,10 @@ export class TopLevelMenuHelperLegacy extends BaseTopLevelMenuHelper implements
419
436
  this.cacheClusters();
420
437
  }
421
438
 
439
+ async destroy() {
440
+ // No-op
441
+ }
442
+
422
443
  /**
423
444
  * Filter mgmt clusters by
424
445
  * 1. Harvester type 1 (filterOnlyKubernetesClusters)
@@ -257,6 +257,13 @@ export default {
257
257
  });
258
258
 
259
259
  return appBar;
260
+ },
261
+
262
+ hideLocalCluster() {
263
+ const hideLocalSetting = this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.HIDE_LOCAL_CLUSTER) || {};
264
+ const value = hideLocalSetting.value || hideLocalSetting.default || 'false';
265
+
266
+ return value === 'true';
260
267
  }
261
268
  },
262
269
 
@@ -309,6 +316,9 @@ export default {
309
316
  immediate: true,
310
317
  },
311
318
 
319
+ hideLocalCluster() {
320
+ this.updateClusters(this.pinnedIds, 'slow');
321
+ }
312
322
  },
313
323
 
314
324
  mounted() {
@@ -317,6 +327,7 @@ export default {
317
327
 
318
328
  beforeUnmount() {
319
329
  document.removeEventListener('keyup', this.handler);
330
+ this.helper?.destroy();
320
331
  },
321
332
 
322
333
  methods: {
@@ -64,7 +64,10 @@ export default {
64
64
  // If the route explicitly declares the nav path that should be highlighted, then use that
65
65
  if (routeMetaNav) {
66
66
  const cluster = this.$route.params?.cluster;
67
- const navPath = routeMetaNav.replace(':cluster', cluster);
67
+ const product = this.$route.params?.product;
68
+ const navPath = routeMetaNav
69
+ .replace(':cluster', cluster)
70
+ .replace(':product', product);
68
71
 
69
72
  if (navPath === typeFullPath) {
70
73
  return true;
@@ -326,6 +326,7 @@ export default {
326
326
 
327
327
  <template>
328
328
  <div
329
+ v-if="open"
329
330
  id="windowmanager"
330
331
  data-testid="windowmanager"
331
332
  class="windowmanager"
@@ -3,17 +3,6 @@ import { Store } from 'vuex';
3
3
  import { stringFor } from '@shell/plugins/i18n';
4
4
 
5
5
  let store: Store<any> | null = null;
6
-
7
- export const useI18n = (vuexStore: Store<any>): { t: typeof t } => {
8
- store = vuexStore;
9
-
10
- if (!store) {
11
- throw new Error('usI18n() must be called from setup()');
12
- }
13
-
14
- return { t };
15
- };
16
-
17
6
  /**
18
7
  * Allows for consuming i18n strings with the Vue composition API.
19
8
  * @param key - The key for the i18n string to translate.
@@ -24,3 +13,15 @@ export const useI18n = (vuexStore: Store<any>): { t: typeof t } => {
24
13
  const t = (key: string, args?: unknown, raw?: boolean): string => {
25
14
  return stringFor(store, key, args, raw);
26
15
  };
16
+
17
+ export type I18n = { t: typeof t };
18
+
19
+ export const useI18n = (vuexStore: Store<any>): I18n => {
20
+ store = vuexStore;
21
+
22
+ if (!store) {
23
+ throw new Error('usI18n() must be called from setup()');
24
+ }
25
+
26
+ return { t };
27
+ };
@@ -116,17 +116,20 @@ export const CATALOG = {
116
116
  };
117
117
 
118
118
  export const FLEET = {
119
- REPO_NAME: 'fleet.cattle.io/repo-name',
120
- CLUSTER_DISPLAY_NAME: 'management.cattle.io/cluster-display-name',
121
- CLUSTER_NAME: 'management.cattle.io/cluster-name',
122
- BUNDLE_ID: 'fleet.cattle.io/bundle-id',
123
- BUNDLE_NAME: 'fleet.cattle.io/bundle-name',
124
- BUNDLE_NAMESPACE: 'fleet.cattle.io/bundle-namespace',
125
- MANAGED: 'fleet.cattle.io/managed',
126
- CLUSTER_NAMESPACE: 'fleet.cattle.io/cluster-namespace',
127
- CLUSTER: 'fleet.cattle.io/cluster',
128
- CREATED_BY_USER_ID: 'fleet.cattle.io/created-by-user-id',
129
- CREATED_BY_USER_NAME: 'fleet.cattle.io/created-by-display-name',
119
+ REPO_NAME: 'fleet.cattle.io/repo-name',
120
+ HELM_NAME: 'fleet.cattle.io/fleet-helm-name',
121
+ CLUSTER_DISPLAY_NAME: 'management.cattle.io/cluster-display-name',
122
+ CLUSTER_NAME: 'management.cattle.io/cluster-name',
123
+ BUNDLE_ID: 'fleet.cattle.io/bundle-id',
124
+ BUNDLE_NAME: 'fleet.cattle.io/bundle-name',
125
+ BUNDLE_NAMESPACE: 'fleet.cattle.io/bundle-namespace',
126
+ MANAGED: 'fleet.cattle.io/managed',
127
+ CLUSTER_NAMESPACE: 'fleet.cattle.io/cluster-namespace',
128
+ CLUSTER: 'fleet.cattle.io/cluster',
129
+ CREATED_BY_USER_ID: 'fleet.cattle.io/created-by-user-id',
130
+ CREATED_BY_USER_NAME: 'fleet.cattle.io/created-by-display-name',
131
+ OCI_STORAGE_SECRET_DEFAULT: 'ui-default-oci-registry',
132
+ OCI_STORAGE_SECRET_GENERATED: 'fleet.cattle.io/bundle-internal-secret',
130
133
  };
131
134
 
132
135
  export const RBAC = { PRODUCT: 'management.cattle.io/ui-product' };
@@ -175,6 +175,7 @@ export function init(store) {
175
175
  componentForType(`${ MANAGEMENT.AUTH_CONFIG }/azuread`, 'auth/azuread');
176
176
  componentForType(`${ MANAGEMENT.AUTH_CONFIG }/keycloakoidc`, 'auth/oidc');
177
177
  componentForType(`${ MANAGEMENT.AUTH_CONFIG }/genericoidc`, 'auth/oidc');
178
+ componentForType(`${ MANAGEMENT.AUTH_CONFIG }/cognito`, 'auth/oidc');
178
179
 
179
180
  basicType([
180
181
  'config',