@rancher/shell 3.0.12-rc.3 → 3.0.12-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 (315) hide show
  1. package/assets/styles/global/_button.scss +1 -1
  2. package/assets/styles/global/_layout.scss +4 -0
  3. package/assets/translations/en-us.yaml +183 -51
  4. package/assets/translations/zh-hans.yaml +1 -7
  5. package/chart/monitoring/ClusterSelector.vue +0 -21
  6. package/chart/monitoring/prometheus/index.vue +6 -3
  7. package/components/ActionDropdownShell.vue +5 -3
  8. package/components/ButtonGroup.vue +26 -1
  9. package/components/CruResource.vue +212 -16
  10. package/components/ExplorerMembers.vue +8 -4
  11. package/components/ExplorerProjectsNamespaces.vue +10 -6
  12. package/components/GrowlManager.vue +4 -0
  13. package/components/MgmtNodeList.vue +184 -0
  14. package/components/PromptRestore.vue +93 -32
  15. package/components/Questions/index.vue +1 -0
  16. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  17. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  18. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  19. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  20. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
  21. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  22. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  23. package/components/ResourceDetail/index.vue +1 -1
  24. package/components/ResourceList/Masthead.vue +7 -1
  25. package/components/ResourceList/index.vue +82 -1
  26. package/components/ResourceTable.vue +1 -0
  27. package/components/RichTranslation.vue +5 -2
  28. package/components/Setting.vue +1 -0
  29. package/components/SortableTable/index.vue +4 -3
  30. package/components/SubtleLink.vue +31 -6
  31. package/components/Tabbed/Tab.vue +29 -3
  32. package/components/Tabbed/index.vue +25 -3
  33. package/components/TableOfContents/TableOfContents.vue +109 -0
  34. package/components/TableOfContents/composables.ts +258 -0
  35. package/components/Window/ContainerShell.vue +21 -11
  36. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  37. package/components/Wizard.vue +23 -5
  38. package/components/__tests__/ButtonGroup.test.ts +56 -0
  39. package/components/__tests__/PromptRestore.test.ts +169 -19
  40. package/components/fleet/AppCoChartGrid.vue +401 -0
  41. package/components/fleet/AppCoEmptyState.vue +127 -0
  42. package/components/fleet/AppCoPageHeader.vue +119 -0
  43. package/components/fleet/AppCoVersionSelect.vue +70 -0
  44. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  45. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  46. package/components/fleet/FleetClusterTargets/index.vue +189 -146
  47. package/components/fleet/FleetIntro.vue +7 -3
  48. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  49. package/components/fleet/FleetSecretSelector.vue +5 -3
  50. package/components/fleet/FleetValuesFrom.vue +8 -2
  51. package/components/fleet/GitRepoAdvancedTab.vue +1 -0
  52. package/components/fleet/GitRepoMetadataTab.vue +5 -0
  53. package/components/fleet/GitRepoTargetTab.vue +0 -2
  54. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  55. package/components/fleet/HelmOpAppCoConfigTab.vue +597 -0
  56. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  57. package/components/fleet/HelmOpMetadataTab.vue +5 -0
  58. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  59. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  60. package/components/fleet/HelmOpTargetTab.vue +64 -60
  61. package/components/fleet/HelmOpValuesTab.vue +129 -105
  62. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  63. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  64. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  65. package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
  66. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  67. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  68. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  69. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  70. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  71. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  72. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  73. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  74. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  75. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  76. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  77. package/components/fleet/dashboard/Empty.vue +8 -4
  78. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  79. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  80. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  81. package/components/form/ArrayList.vue +61 -4
  82. package/components/form/FileSelector.vue +39 -1
  83. package/components/form/KeyValue.vue +23 -2
  84. package/components/form/LabeledSelect.vue +39 -1
  85. package/components/form/Labels.vue +22 -3
  86. package/components/form/NameNsDescription.vue +13 -5
  87. package/components/form/PrivateRegistry.constants.ts +7 -0
  88. package/components/form/PrivateRegistry.vue +253 -18
  89. package/components/form/ResourceTabs/index.vue +1 -0
  90. package/components/form/SelectOrCreateAuthSecret.vue +140 -17
  91. package/components/form/__tests__/FileSelector.test.ts +23 -0
  92. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  93. package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
  94. package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
  95. package/components/formatter/EtcdSnapshotName.vue +73 -0
  96. package/components/formatter/InternalExternalIP.vue +10 -4
  97. package/components/formatter/ServiceTargets.vue +26 -7
  98. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  99. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  100. package/components/nav/Header.vue +12 -1
  101. package/components/nav/TopLevelMenu.vue +7 -2
  102. package/components/nav/__tests__/Header.test.ts +15 -0
  103. package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
  104. package/components/templates/default.vue +16 -4
  105. package/components/templates/home.vue +9 -4
  106. package/components/templates/plain.vue +9 -4
  107. package/composables/useHelmOpResources.test.ts +56 -0
  108. package/composables/useHelmOpResources.ts +32 -0
  109. package/composables/useStateColor.test.ts +325 -0
  110. package/composables/useStateColor.ts +128 -0
  111. package/config/features.js +1 -0
  112. package/config/home-links.js +1 -1
  113. package/config/labels-annotations.js +3 -0
  114. package/config/product/explorer.js +17 -4
  115. package/config/product/manager.js +8 -0
  116. package/config/router/index.js +16 -0
  117. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  118. package/config/router/navigation-guards/authentication.js +10 -4
  119. package/config/router/routes.js +20 -6
  120. package/config/secret.ts +10 -0
  121. package/config/settings.ts +6 -4
  122. package/config/table-headers.js +3 -4
  123. package/config/types.js +16 -0
  124. package/core/plugin-products-base.ts +3 -3
  125. package/core/plugin-types.ts +83 -30
  126. package/core/plugin.ts +3 -0
  127. package/core/types-provisioning.ts +34 -1
  128. package/core/types.ts +15 -2
  129. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  130. package/detail/__tests__/workload.test.ts +3 -152
  131. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  132. package/detail/provisioning.cattle.io.cluster.vue +109 -7
  133. package/detail/workload/index.vue +12 -55
  134. package/dialog/RotateEncryptionKeyDialog.vue +33 -9
  135. package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
  136. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  137. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
  138. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +206 -0
  139. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  140. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  141. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  142. package/edit/auth/__tests__/azuread.test.ts +34 -9
  143. package/edit/auth/__tests__/github.test.ts +234 -0
  144. package/edit/auth/__tests__/oidc.test.ts +26 -6
  145. package/edit/auth/__tests__/saml.test.ts +196 -0
  146. package/edit/auth/azuread.vue +128 -95
  147. package/edit/auth/github.vue +72 -13
  148. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  149. package/edit/auth/ldap/config.vue +8 -0
  150. package/edit/auth/ldap/index.vue +75 -1
  151. package/edit/auth/oidc.vue +119 -73
  152. package/edit/auth/saml.vue +76 -12
  153. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  154. package/edit/compliance.cattle.io.clusterscanprofile.vue +39 -41
  155. package/edit/fleet.cattle.io.gitrepo.vue +70 -16
  156. package/edit/fleet.cattle.io.helmop.vue +542 -141
  157. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  158. package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
  159. package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
  160. package/edit/management.cattle.io.user.vue +5 -2
  161. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
  162. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
  163. package/edit/provisioning.cattle.io.cluster/rke2.vue +89 -11
  164. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  165. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
  166. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
  167. package/list/group.principal.vue +5 -4
  168. package/list/harvesterhci.io.management.cluster.vue +8 -9
  169. package/list/management.cattle.io.user.vue +12 -9
  170. package/list/provisioning.cattle.io.cluster.vue +16 -10
  171. package/mixins/__tests__/auth-config.test.ts +90 -0
  172. package/mixins/__tests__/chart.test.ts +94 -0
  173. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  174. package/mixins/auth-config.js +7 -0
  175. package/mixins/chart.js +11 -2
  176. package/mixins/child-hook.js +12 -6
  177. package/mixins/create-edit-view/impl.js +5 -3
  178. package/mixins/resource-fetch-api-pagination.js +21 -1
  179. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  180. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  181. package/models/__tests__/fleet-application.test.ts +175 -0
  182. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  183. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  184. package/models/__tests__/management.cattle.io.node.ts +22 -0
  185. package/models/__tests__/namespace.test.ts +36 -0
  186. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +205 -0
  187. package/models/__tests__/secret.test.ts +68 -1
  188. package/models/__tests__/workload.test.ts +401 -26
  189. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  190. package/models/compliance.cattle.io.clusterscan.js +39 -4
  191. package/models/fleet-application.js +4 -0
  192. package/models/fleet.cattle.io.helmop.js +20 -1
  193. package/models/management.cattle.io.cluster.js +39 -5
  194. package/models/management.cattle.io.node.js +44 -3
  195. package/models/namespace.js +1 -1
  196. package/models/pod.js +46 -3
  197. package/models/provisioning.cattle.io.cluster.js +64 -14
  198. package/models/rke.cattle.io.etcdsnapshot.js +17 -9
  199. package/models/secret.js +19 -0
  200. package/models/workload.js +120 -20
  201. package/models/workload.service.js +5 -0
  202. package/package.json +14 -13
  203. package/pages/about.vue +5 -6
  204. package/pages/auth/login.vue +0 -35
  205. package/pages/auth/setup.vue +11 -0
  206. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  207. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  208. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  209. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +485 -107
  210. package/pages/c/_cluster/apps/charts/chart.vue +2 -1
  211. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  212. package/pages/c/_cluster/apps/charts/install.vue +236 -144
  213. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  214. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  215. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  216. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  217. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  218. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  219. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  220. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  221. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  222. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  223. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  224. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  225. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  226. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  227. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  228. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  229. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  230. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  231. package/pages/c/_cluster/fleet/index.vue +2 -2
  232. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
  233. package/pages/c/_cluster/uiplugins/index.vue +15 -0
  234. package/pages/fail-whale.vue +16 -11
  235. package/pages/home.vue +16 -46
  236. package/pkg/require-asset.lib.js +25 -0
  237. package/pkg/vue.config.js +7 -0
  238. package/plugins/clean-html.d.ts +9 -0
  239. package/plugins/dashboard-store/__tests__/resource-class.test.ts +177 -0
  240. package/plugins/dashboard-store/getters.js +0 -1
  241. package/plugins/dashboard-store/resource-class.js +114 -19
  242. package/plugins/steve/__tests__/actions.test.ts +212 -0
  243. package/plugins/steve/actions.js +96 -0
  244. package/plugins/steve/steve-pagination-utils.ts +1 -1
  245. package/rancher-components/Accordion/Accordion.vue +53 -9
  246. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  247. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  248. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  249. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
  250. package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
  251. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  252. package/rancher-components/RcButton/RcButton.test.ts +103 -0
  253. package/rancher-components/RcButton/RcButton.vue +94 -15
  254. package/rancher-components/RcButton/index.ts +1 -1
  255. package/rancher-components/RcButton/types.ts +3 -0
  256. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
  257. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  258. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  259. package/rancher-components/RcSection/RcSection.vue +28 -3
  260. package/scripts/extension/helm/package/Dockerfile +1 -1
  261. package/scripts/test-plugins-build.sh +2 -1
  262. package/store/__tests__/features.test.ts +131 -0
  263. package/store/__tests__/growl.test.ts +374 -0
  264. package/store/__tests__/modal.test.ts +131 -0
  265. package/store/__tests__/notifications.test.ts +434 -0
  266. package/store/__tests__/slideInPanel.test.ts +88 -0
  267. package/store/__tests__/type-map.utils.test.ts +433 -0
  268. package/store/catalog.js +57 -0
  269. package/store/features.js +4 -0
  270. package/store/plugins.js +7 -4
  271. package/types/components/buttonGroup.ts +5 -0
  272. package/types/shell/index.d.ts +166 -70
  273. package/utils/__tests__/auth.test.ts +273 -0
  274. package/utils/__tests__/computed.test.ts +193 -0
  275. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  276. package/utils/__tests__/dom.test.ts +81 -0
  277. package/utils/__tests__/duration.test.ts +37 -1
  278. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  279. package/utils/__tests__/fleet-appco.test.ts +312 -0
  280. package/utils/__tests__/monitoring.test.ts +130 -0
  281. package/utils/__tests__/object.test.ts +22 -0
  282. package/utils/__tests__/operation-cr.test.ts +34 -0
  283. package/utils/__tests__/platform.test.ts +91 -0
  284. package/utils/__tests__/position.test.ts +237 -0
  285. package/utils/__tests__/provider.test.ts +51 -1
  286. package/utils/__tests__/queue.test.ts +232 -0
  287. package/utils/__tests__/release-notes.test.ts +221 -0
  288. package/utils/__tests__/router.test.js +254 -1
  289. package/utils/__tests__/select.test.ts +208 -0
  290. package/utils/__tests__/time.test.ts +265 -1
  291. package/utils/__tests__/title.test.ts +47 -0
  292. package/utils/__tests__/width.test.ts +53 -0
  293. package/utils/__tests__/window.test.ts +158 -0
  294. package/utils/__tests__/xccdf.test.ts +126 -6
  295. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  296. package/utils/crypto/__tests__/index.test.ts +144 -0
  297. package/utils/duration.ts +104 -0
  298. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  299. package/utils/dynamic-content/info.ts +2 -1
  300. package/utils/error.js +13 -0
  301. package/utils/fleet-appco.ts +323 -0
  302. package/utils/object.js +22 -2
  303. package/utils/operation-cr.js +19 -0
  304. package/utils/provider.ts +12 -0
  305. package/utils/require-asset.ts +7 -0
  306. package/utils/validators/__tests__/container-images.test.ts +104 -0
  307. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  308. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  309. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  310. package/utils/validators/__tests__/private-registry.test.ts +27 -15
  311. package/utils/validators/private-registry.ts +15 -4
  312. package/utils/xccdf.ts +39 -42
  313. package/vue.config.js +1 -1
  314. package/pages/support/index.vue +0 -264
  315. package/utils/duration.js +0 -43
@@ -1,15 +1,16 @@
1
1
  import { findBy, insertAt } from '@shell/utils/array';
2
2
  import { CATTLE_PUBLIC_ENDPOINTS } from '@shell/config/labels-annotations';
3
- import { WORKLOAD_TYPES, SERVICE, POD } from '@shell/config/types';
3
+ import { WORKLOAD_TYPES, SERVICE, INGRESS, POD } from '@shell/config/types';
4
4
  import { set } from '@shell/utils/object';
5
5
  import day from 'dayjs';
6
- import { convertSelectorObj, parse, matches } from '@shell/utils/selector';
6
+ import { convertSelectorObj, parse, matches, convert } from '@shell/utils/selector';
7
7
  import { SEPARATOR } from '@shell/config/workload';
8
8
  import WorkloadService from '@shell/models/workload.service';
9
9
  import { matching } from '@shell/utils/selector-typed';
10
10
  import { defineAsyncComponent, markRaw } from 'vue';
11
11
  import { useResourceCardRow } from '@shell/components/Resource/Detail/Card/StateCard/composables';
12
12
  import { colorForState as colorForStateFn, stateDisplay as stateDisplayFn } from '@shell/plugins/dashboard-store/resource-class';
13
+ import { POD_SHELL } from '@shell/store/features';
13
14
 
14
15
  export const defaultContainer = {
15
16
  imagePullPolicy: 'Always',
@@ -28,6 +29,7 @@ export default class Workload extends WorkloadService {
28
29
  get _availableActions() {
29
30
  let out = super._availableActions;
30
31
  const type = this._type ? this._type : this.type;
32
+ const podShellFeatureEnabled = !!this.$rootGetters['features/get'](POD_SHELL);
31
33
 
32
34
  const editYaml = findBy(out, 'action', 'goToEditYaml');
33
35
  const index = editYaml ? out.indexOf(editYaml) : 0;
@@ -76,13 +78,16 @@ export default class Workload extends WorkloadService {
76
78
 
77
79
  insertAt(out, 0, { divider: true }) ;
78
80
 
79
- insertAt(out, 0, {
80
- action: 'openShell',
81
- enabled: !!this.links.view,
82
- icon: 'icon icon-chevron-right',
83
- label: this.t('action.openShell'),
84
- total: 1,
85
- });
81
+ // Only add the menu item for the pod shell if the feature flag is enabled
82
+ if (podShellFeatureEnabled) {
83
+ insertAt(out, 0, {
84
+ action: 'openShell',
85
+ enabled: !!this.links.view,
86
+ icon: 'icon icon-chevron-right',
87
+ label: this.t('action.openShell'),
88
+ total: 1,
89
+ });
90
+ }
86
91
 
87
92
  const toFilter = ['cloneYaml'];
88
93
 
@@ -586,6 +591,29 @@ export default class Workload extends WorkloadService {
586
591
  return undefined;
587
592
  }
588
593
 
594
+ async fetchSummaries() {
595
+ const summaries = { pods: null };
596
+
597
+ try {
598
+ if (this.podMatchExpression) {
599
+ summaries.pods = await this.$dispatch('fetchResourceSummary', {
600
+ type: POD,
601
+ opt: {
602
+ summaryField: 'metadata.state.name',
603
+ namespace: this.metadata.namespace,
604
+ labelSelector: { matchExpressions: this.podMatchExpression },
605
+ }
606
+ });
607
+ }
608
+ } catch (e) {
609
+ console.warn('fetchSummaries: failed to fetch pod summary', e); // eslint-disable-line no-console
610
+ }
611
+
612
+ set(this, '_summaries', summaries);
613
+
614
+ return summaries;
615
+ }
616
+
589
617
  async unWatchPods() {
590
618
  return await this.$dispatch('unwatch', { type: POD, all: true });
591
619
  }
@@ -747,16 +775,70 @@ export default class Workload extends WorkloadService {
747
775
  }
748
776
 
749
777
  get relatedServices() {
750
- // Find Services that have selectors that match this workload's Pod(s).
778
+ if (this.type === WORKLOAD_TYPES.JOB || this.type === WORKLOAD_TYPES.CRON_JOB) {
779
+ return [];
780
+ }
781
+
782
+ const podTemplateLabels = this.spec?.template?.metadata?.labels;
783
+
784
+ if (!podTemplateLabels || Object.keys(podTemplateLabels).length === 0) {
785
+ return [];
786
+ }
787
+
788
+ const templateAsObj = { metadata: { labels: podTemplateLabels } };
789
+
751
790
  return this.servicesInNamespace.filter((service) => {
752
791
  const selector = service.spec.selector;
753
792
 
754
- for (let i = 0; i < this.pods.length; i++) {
755
- const pod = this.pods[i];
793
+ if (!selector || typeof selector !== 'object') {
794
+ return false;
795
+ }
756
796
 
757
- if (service.metadata?.namespace === this.metadata?.namespace && matches(pod, selector)) {
758
- return true;
797
+ return matches(templateAsObj, convert(selector));
798
+ });
799
+ }
800
+
801
+ get matchingIngresses() {
802
+ const allIngresses = this.$rootGetters['cluster/all'](INGRESS);
803
+ const services = this.relatedServices;
804
+
805
+ if (!services.length) {
806
+ return [];
807
+ }
808
+
809
+ return allIngresses.filter((ingress) => {
810
+ try {
811
+ const rules = ingress.spec?.rules;
812
+
813
+ if (!rules || !Array.isArray(rules)) {
814
+ return false;
759
815
  }
816
+
817
+ for (const rule of rules) {
818
+ const paths = rule?.http?.paths;
819
+
820
+ if (!paths || !Array.isArray(paths)) {
821
+ continue;
822
+ }
823
+
824
+ for (const pathData of paths) {
825
+ const targetServiceName = pathData?.backend?.service?.name;
826
+
827
+ if (!targetServiceName) {
828
+ continue;
829
+ }
830
+
831
+ for (const service of services) {
832
+ if (ingress.metadata?.namespace === this.metadata?.namespace && service?.metadata?.name === targetServiceName) {
833
+ return true;
834
+ }
835
+ }
836
+ }
837
+ }
838
+ } catch (err) {
839
+ console.warn(`matchingIngresses: failed to match ingress "${ ingress.id }"`, err); // eslint-disable-line no-console
840
+
841
+ return false;
760
842
  }
761
843
 
762
844
  return false;
@@ -764,10 +846,23 @@ export default class Workload extends WorkloadService {
764
846
  }
765
847
 
766
848
  get resourcesCardRows() {
767
- return [
768
- useResourceCardRow(this.t('component.resource.detail.card.resourcesCard.rows.services'), this.relatedServices, undefined, undefined, '#services'),
769
- ...this._resourcesCardRows,
770
- ];
849
+ const rows = [...this._resourcesCardRows];
850
+ const showsIngressesAndServices = this.type !== WORKLOAD_TYPES.JOB && this.type !== WORKLOAD_TYPES.CRON_JOB;
851
+
852
+ if (showsIngressesAndServices) {
853
+ const services = this.relatedServices || [];
854
+ const ingresses = this.matchingIngresses || [];
855
+
856
+ if (ingresses.length) {
857
+ rows.unshift(useResourceCardRow(this.t('component.resource.detail.card.resourcesCard.rows.ingresses'), ingresses, undefined, undefined, '#ingresses'));
858
+ }
859
+
860
+ if (services.length) {
861
+ rows.unshift(useResourceCardRow(this.t('component.resource.detail.card.resourcesCard.rows.services'), services, undefined, undefined, '#services'));
862
+ }
863
+ }
864
+
865
+ return rows;
771
866
  }
772
867
 
773
868
  get podsCard() {
@@ -779,8 +874,11 @@ export default class Workload extends WorkloadService {
779
874
 
780
875
  const scalingTypes = [WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.STATEFUL_SET];
781
876
  const canScale = this.canUpdate && scalingTypes.includes(this.type);
877
+ const summaryData = this._summaries?.pods || null;
878
+ const hasPods = this.pods?.length > 0;
879
+ const hasSummary = summaryData?.count > 0;
782
880
 
783
- if (!this.pods || (this.pods.length === 0 && !canScale)) {
881
+ if (!hasPods && !hasSummary && !canScale) {
784
882
  return null;
785
883
  }
786
884
 
@@ -789,6 +887,7 @@ export default class Workload extends WorkloadService {
789
887
  props: {
790
888
  title: this.t('component.resource.detail.card.podsCard.title'),
791
889
  resources: this.pods,
890
+ summaryData,
792
891
  showScaling: canScale,
793
892
  onIncrease: () => this.scale(true),
794
893
  onDecrease: () => this.scale(false),
@@ -818,8 +917,9 @@ export default class Workload extends WorkloadService {
818
917
  return [
819
918
  this.podsCard,
820
919
  this.jobsCard,
920
+ this.resourcesCard,
821
921
  this.insightCard,
822
922
  ...this._cards
823
- ];
923
+ ].filter((c) => c);
824
924
  }
825
925
  }
@@ -5,8 +5,13 @@ import { WORKLOAD_TYPES, SERVICE } from '@shell/config/types';
5
5
  import { clone, get } from '@shell/utils/object';
6
6
  import SteveModel from '@shell/plugins/steve/steve-class';
7
7
  import { shortenedImage } from '@shell/utils/string';
8
+ import { stateDisplay } from '@shell/plugins/dashboard-store/resource-class';
8
9
 
9
10
  export default class WorkloadService extends SteveModel {
11
+ get stateDisplay() {
12
+ return stateDisplay(this.state, true);
13
+ }
14
+
10
15
  async getPortsWithServiceType() {
11
16
  const ports = [];
12
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "3.0.12-rc.3",
3
+ "version": "3.0.12-rc.5",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancher/dashboard",
6
6
  "license": "Apache-2.0",
@@ -33,13 +33,14 @@
33
33
  "@babel/preset-typescript": "7.16.7",
34
34
  "@novnc/novnc": "1.2.0",
35
35
  "@popperjs/core": "2.11.8",
36
- "@rancher/icons": "2.0.60",
36
+ "@rancher/icons": "2.0.62",
37
37
  "@smithy/fetch-http-handler": "5.1.1",
38
38
  "@types/is-url": "1.2.30",
39
39
  "@types/node": "25.3.3",
40
40
  "@types/semver": "^7.5.8",
41
41
  "@typescript-eslint/eslint-plugin": "5.62.0",
42
42
  "@typescript-eslint/parser": "5.62.0",
43
+ "@vee-validate/zod": "4.15.0",
43
44
  "@vue/cli-plugin-babel": "~5.0.0",
44
45
  "@vue/cli-plugin-typescript": "~5.0.0",
45
46
  "@vue/cli-service": "5.0.8",
@@ -47,7 +48,7 @@
47
48
  "@vue/vue3-jest": "27.0.0",
48
49
  "add": "2.0.6",
49
50
  "ansi_up": "5.0.0",
50
- "axios": "1.15.2",
51
+ "axios": "1.16.0",
51
52
  "axios-retry": "3.1.9",
52
53
  "babel-eslint": "10.1.0",
53
54
  "babel-preset-vue": "2.0.2",
@@ -80,14 +81,13 @@
80
81
  "eslint-plugin-n": "15.2.0",
81
82
  "eslint-plugin-vue": "9.32.0",
82
83
  "event-target-shim": "5.0.1",
83
- "express": "4.17.1",
84
- "file-saver": "2.0.2",
84
+ "express": "4.22.2",
85
+ "file-saver": "2.0.5",
85
86
  "floating-vue": "5.2.2",
86
87
  "focus-trap": "7.6.5",
87
88
  "frontmatter-markdown-loader": "3.7.0",
88
89
  "identicon.js": "2.3.3",
89
90
  "intl-messageformat": "7.8.4",
90
- "ip": "2.0.1",
91
91
  "is-url": "1.2.4",
92
92
  "jest": "27.5.1",
93
93
  "jest-serializer-vue": "2.0.2",
@@ -124,12 +124,13 @@
124
124
  "webpack-virtual-modules": "0.6.2",
125
125
  "worker-loader": "3.0.8",
126
126
  "xmlbuilder2": "4.0.1",
127
- "xterm": "5.2.1",
128
- "xterm-addon-canvas": "0.5.0",
129
- "xterm-addon-fit": "0.8.0",
130
- "xterm-addon-search": "0.13.0",
131
- "xterm-addon-web-links": "0.9.0",
132
- "xterm-addon-webgl": "0.16.0",
127
+ "zod": "3.24.3",
128
+ "@xterm/xterm": "6.0.0",
129
+ "@xterm/addon-fit": "0.11.0",
130
+ "@xterm/addon-search": "0.16.0",
131
+ "@xterm/addon-web-links": "0.12.0",
132
+ "@xterm/addon-webgl": "0.19.0",
133
+ "@xterm/addon-canvas": "0.7.0",
133
134
  "yarn": "1.22.22"
134
135
  },
135
136
  "resolutions": {
@@ -142,7 +143,7 @@
142
143
  "merge": "2.1.1",
143
144
  "node-forge": "1.3.1",
144
145
  "nth-check": "2.1.1",
145
- "qs": "6.11.1",
146
+ "qs": "6.15.2",
146
147
  "roarr": "7.0.4",
147
148
  "semver": "7.5.4",
148
149
  "@types/lodash": "4.17.5",
package/pages/about.vue CHANGED
@@ -10,10 +10,11 @@ import TabTitle from '@shell/components/TabTitle';
10
10
  import { PanelLocation, ExtensionPoint } from '@shell/core/types';
11
11
  import ExtensionPanel from '@shell/components/ExtensionPanel';
12
12
  import { getVersionInfo } from '@shell/utils/version';
13
+ import { RcButton } from '@components/RcButton';
13
14
 
14
15
  export default {
15
16
  components: {
16
- BackLink, ExtensionPanel, Loading, TabTitle
17
+ BackLink, ExtensionPanel, Loading, TabTitle, RcButton
17
18
  },
18
19
  mixins: [BackRoute],
19
20
  async fetch() {
@@ -85,16 +86,14 @@ export default {
85
86
  {{ t('about.title') }}
86
87
  </TabTitle>
87
88
  </h1>
88
- <router-link
89
+ <rc-button
90
+ size="large"
89
91
  :to="{ name: 'diagnostic' }"
90
- class="btn role-primary"
91
92
  data-testid="about__diagnostics_button"
92
- role="button"
93
93
  :aria-label="t('about.diagnostic.title')"
94
- @keyup.space="$router.push({ name: 'diagnostic' })"
95
94
  >
96
95
  {{ t('about.diagnostic.title') }}
97
- </router-link>
96
+ </rc-button>
98
97
  </div>
99
98
  <!-- Extensions area -->
100
99
  <ExtensionPanel
@@ -410,41 +410,6 @@ export default {
410
410
  k="setup.defaultPassword.intro"
411
411
  :raw="true"
412
412
  />
413
-
414
- <div>
415
- <t
416
- k="setup.defaultPassword.dockerPrefix"
417
- :raw="true"
418
- />
419
- </div>
420
- <ul>
421
- <li>
422
- <t
423
- k="setup.defaultPassword.dockerPs"
424
- :raw="true"
425
- />
426
- </li>
427
- <li>
428
- <CopyCode>
429
- docker logs <u>container-id</u> 2&gt;&amp;1 | grep "Bootstrap Password:"
430
- </CopyCode>
431
- </li>
432
- </ul>
433
- <div>
434
- <t
435
- k="setup.defaultPassword.dockerSuffix"
436
- :raw="true"
437
- />
438
- </div>
439
-
440
- <br>
441
- <div>
442
- <t
443
- k="setup.defaultPassword.helmPrefix"
444
- :raw="true"
445
- />
446
- </div>
447
- <br>
448
413
  <CopyCode>
449
414
  {{ kubectlCmd }}
450
415
  </CopyCode>
@@ -20,6 +20,7 @@ import FormValidation from '@shell/mixins/form-validation';
20
20
  import { isLocalhost, isValidUrl } from '@shell/utils/validators/setting';
21
21
  import Loading from '@shell/components/Loading';
22
22
  import { getBrandMeta } from '@shell/utils/brand';
23
+ import { findMe } from '@shell/utils/auth';
23
24
 
24
25
  const calcIsFirstLogin = (store) => {
25
26
  const firstLoginSetting = store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.FIRST_LOGIN);
@@ -77,6 +78,16 @@ export default {
77
78
  // Always show setup if this is the first log in
78
79
  return;
79
80
  } else if (mustChangePassword) {
81
+ // Skip password change for non-local sessions
82
+ try {
83
+ const me = await findMe(this.$store);
84
+
85
+ if (me && me.provider !== 'local') {
86
+ return this.$router.replace('/');
87
+ }
88
+ } catch (e) {
89
+ }
90
+
80
91
  // If the password needs changing and this isn't the first log in ensure we have the password
81
92
  if (!!this.$store.getters['auth/initialPass']) {
82
93
  // Got it... show setup
@@ -3,7 +3,7 @@ import { reactive } from 'vue';
3
3
  import { RcItemCardAction } from '@components/RcItemCard';
4
4
  import { RcButton } from '@components/RcButton';
5
5
  import { isTruncated } from '@shell/utils/style';
6
- import RcIcon from '@components/RcIcon/RcIcon.vue';
6
+ import { RcIcon } from '@components/RcIcon';
7
7
  import type { RcIconType } from '@components/RcIcon/types';
8
8
 
9
9
  interface FooterItem {
@@ -195,7 +195,7 @@ function getTooltip(key: string, fallback?: string): string | undefined {
195
195
  }
196
196
  }
197
197
 
198
- button.variant-ghost.app-chart-card-footer-button {
198
+ button.rc-button.variant-ghost.app-chart-card-footer-button {
199
199
  padding: 0;
200
200
  gap: 0;
201
201
  min-height: 20px;
@@ -9,12 +9,16 @@ interface SubHeaderItem {
9
9
 
10
10
  defineProps<{
11
11
  items: SubHeaderItem[];
12
+ removeMarginBottom?: boolean;
12
13
  }>();
13
14
 
14
15
  </script>
15
16
 
16
17
  <template>
17
- <div class="app-chart-card-sub-header">
18
+ <div
19
+ class="app-chart-card-sub-header"
20
+ :class="{ 'no-margin-bottom': removeMarginBottom }"
21
+ >
18
22
  <div
19
23
  v-for="(subHeaderItem, i) in items"
20
24
  :key="i"
@@ -38,8 +42,13 @@ defineProps<{
38
42
  flex-wrap: wrap;
39
43
  gap: var(--gap) var(--gap-md);
40
44
  color: var(--link-text-secondary);
45
+ height: 22px;
41
46
  margin-bottom: 8px;
42
47
 
48
+ &.no-margin-bottom {
49
+ margin-bottom: 0;
50
+ }
51
+
43
52
  &-item {
44
53
  display: flex;
45
54
  align-items: center;
@@ -52,4 +52,97 @@ describe('page: Charts Index', () => {
52
52
  expect(hasExtensionCategory).toBe(false);
53
53
  });
54
54
  });
55
+
56
+ describe('method: loadMore', () => {
57
+ const createContext = (overrides: Record<string, any> = {}) => ({
58
+ isLoadingMore: false,
59
+ visibleChartsCount: 30,
60
+ initialVisibleChartsCount: 30,
61
+ filteredCharts: new Array(100),
62
+ _loadMoreTimer: null,
63
+ $nextTick: (cb: () => void) => cb(),
64
+ ...overrides,
65
+ });
66
+
67
+ beforeEach(() => {
68
+ jest.useFakeTimers();
69
+ });
70
+
71
+ afterEach(() => {
72
+ jest.useRealTimers();
73
+ });
74
+
75
+ it('should set isLoadingMore, then increment visibleChartsCount and clear the flag after the delay', () => {
76
+ const ctx = createContext();
77
+
78
+ (Charts.methods!.loadMore as () => void).call(ctx);
79
+
80
+ expect(ctx.isLoadingMore).toBe(true);
81
+ expect(ctx.visibleChartsCount).toBe(30);
82
+ expect(ctx._loadMoreTimer).not.toBeNull();
83
+
84
+ jest.runAllTimers();
85
+
86
+ expect(ctx.visibleChartsCount).toBe(60);
87
+ expect(ctx.isLoadingMore).toBe(false);
88
+ expect(ctx._loadMoreTimer).toBeNull();
89
+ });
90
+
91
+ it('should do nothing when already loading', () => {
92
+ const ctx = createContext({ isLoadingMore: true });
93
+
94
+ (Charts.methods!.loadMore as () => void).call(ctx);
95
+
96
+ expect(ctx._loadMoreTimer).toBeNull();
97
+ expect(ctx.visibleChartsCount).toBe(30);
98
+ });
99
+
100
+ it('should do nothing when all charts are already visible', () => {
101
+ const ctx = createContext({ visibleChartsCount: 100 });
102
+
103
+ (Charts.methods!.loadMore as () => void).call(ctx);
104
+
105
+ expect(ctx.isLoadingMore).toBe(false);
106
+ expect(ctx._loadMoreTimer).toBeNull();
107
+ });
108
+ });
109
+
110
+ describe('method: resetLazyLoadState', () => {
111
+ beforeEach(() => {
112
+ jest.useFakeTimers();
113
+ });
114
+
115
+ afterEach(() => {
116
+ jest.useRealTimers();
117
+ });
118
+
119
+ it('should reset state and cancel a pending loadMore so visibleChartsCount is not incremented after reset', () => {
120
+ const ctx: Record<string, any> = {
121
+ isLoadingMore: false,
122
+ visibleChartsCount: 30,
123
+ initialVisibleChartsCount: 30,
124
+ observerInitialized: true,
125
+ hasOverflow: true,
126
+ filteredCharts: new Array(100),
127
+ _loadMoreTimer: null,
128
+ $nextTick: (cb: () => void) => cb(),
129
+ };
130
+
131
+ (Charts.methods!.loadMore as () => void).call(ctx);
132
+ expect(ctx._loadMoreTimer).not.toBeNull();
133
+
134
+ (Charts.methods!.resetLazyLoadState as () => void).call(ctx);
135
+
136
+ expect(ctx.visibleChartsCount).toBe(30);
137
+ expect(ctx.observerInitialized).toBe(false);
138
+ expect(ctx.hasOverflow).toBe(false);
139
+ expect(ctx.isLoadingMore).toBe(false);
140
+ expect(ctx._loadMoreTimer).toBeNull();
141
+
142
+ jest.runAllTimers();
143
+
144
+ // The cancelled timer must not have fired — count stays at the reset value.
145
+ expect(ctx.visibleChartsCount).toBe(30);
146
+ });
147
+ });
55
148
  });