@rancher/shell 3.0.7 → 3.0.8-rc.10

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 (375) hide show
  1. package/assets/brand/suse/banner.svg +1 -0
  2. package/assets/brand/suse/dark/banner.svg +1 -0
  3. package/assets/brand/suse/dark/login-landscape.svg +1 -0
  4. package/assets/brand/suse/dark/rancher-logo.svg +1 -1
  5. package/assets/brand/suse/favicon.png +0 -0
  6. package/assets/brand/suse/login-landscape.svg +1 -0
  7. package/assets/brand/suse/metadata.json +11 -1
  8. package/assets/brand/suse/rancher-logo.svg +1 -1
  9. package/assets/fonts/suse/suse-v2-latin-300.woff +0 -0
  10. package/assets/fonts/suse/suse-v2-latin-300.woff2 +0 -0
  11. package/assets/fonts/suse/suse-v2-latin-600.woff +0 -0
  12. package/assets/fonts/suse/suse-v2-latin-600.woff2 +0 -0
  13. package/assets/fonts/suse/suse-v2-latin-700.woff +0 -0
  14. package/assets/fonts/suse/suse-v2-latin-700.woff2 +0 -0
  15. package/assets/fonts/suse/suse-v2-latin-800.woff +0 -0
  16. package/assets/fonts/suse/suse-v2-latin-800.woff2 +0 -0
  17. package/assets/fonts/suse/suse-v2-latin-regular.woff +0 -0
  18. package/assets/fonts/suse/suse-v2-latin-regular.woff2 +0 -0
  19. package/assets/images/content/README.md +5 -0
  20. package/assets/images/content/cloud-native.svg +84 -0
  21. package/assets/images/content/dark/cloud-native.svg +21 -0
  22. package/assets/images/content/dark/shield.svg +59 -0
  23. package/assets/images/content/dark/suse.svg +10 -0
  24. package/assets/images/content/shield.svg +59 -0
  25. package/assets/images/content/suse.svg +10 -0
  26. package/assets/images/vendor/githubapp.svg +13 -0
  27. package/assets/styles/base/_typography.scss +2 -1
  28. package/assets/styles/fonts/_fontstack.scss +53 -1
  29. package/assets/styles/global/_cards.scss +0 -3
  30. package/assets/styles/global/_layout.scss +21 -35
  31. package/assets/styles/themes/_dark.scss +1 -1
  32. package/assets/styles/themes/_light.scss +1 -1
  33. package/assets/styles/themes/_modern.scss +16 -8
  34. package/assets/styles/themes/_suse.scss +116 -24
  35. package/assets/translations/en-us.yaml +185 -21
  36. package/assets/translations/zh-hans.yaml +0 -4
  37. package/components/AutoscalerCard.vue +113 -0
  38. package/components/AutoscalerTab.vue +94 -0
  39. package/components/BackLink.vue +8 -0
  40. package/components/BannerGraphic.vue +36 -21
  41. package/components/BrandImage.vue +17 -6
  42. package/components/ClusterIconMenu.vue +1 -1
  43. package/components/ClusterProviderIcon.vue +1 -1
  44. package/components/Cron/CronExpressionEditor.vue +1 -1
  45. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  46. package/components/Drawer/Chrome.vue +2 -6
  47. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
  48. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
  49. package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
  50. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
  51. package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
  52. package/components/Drawer/types.ts +3 -0
  53. package/components/DynamicContent/DynamicContentBanner.vue +102 -0
  54. package/components/DynamicContent/DynamicContentCloseButton.vue +42 -0
  55. package/components/DynamicContent/DynamicContentIcon.vue +132 -0
  56. package/components/DynamicContent/DynamicContentPanel.vue +112 -0
  57. package/components/DynamicContent/content.ts +78 -0
  58. package/components/EmberPage.vue +1 -1
  59. package/components/IconOrSvg.vue +2 -2
  60. package/components/Inactivity.vue +222 -106
  61. package/components/InstallHelmCharts.vue +2 -2
  62. package/components/PaginatedResourceTable.vue +2 -6
  63. package/components/PopoverCard.vue +192 -0
  64. package/components/Questions/__tests__/index.test.ts +159 -0
  65. package/components/Resource/Detail/CopyToClipboard.vue +4 -1
  66. package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
  67. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  68. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
  69. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
  70. package/components/Resource/Detail/Metadata/KeyValueRow.vue +1 -1
  71. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  72. package/components/Resource/Detail/Metadata/composables.ts +9 -9
  73. package/components/Resource/Detail/Metadata/index.vue +3 -3
  74. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
  75. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
  76. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
  77. package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
  78. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
  79. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  80. package/components/Resource/Detail/TitleBar/index.vue +10 -6
  81. package/components/Resource/Detail/composables.ts +12 -0
  82. package/components/ResourceDetail/Masthead/latest.vue +29 -0
  83. package/components/ResourceDetail/index.vue +5 -2
  84. package/components/ResourceList/Masthead.vue +1 -1
  85. package/components/SortableTable/index.vue +18 -2
  86. package/components/Tabbed/__tests__/index.test.ts +86 -0
  87. package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
  88. package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
  89. package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
  90. package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
  91. package/components/__tests__/AutoscalerCard.test.ts +154 -0
  92. package/components/__tests__/AutoscalerTab.test.ts +125 -0
  93. package/components/__tests__/PopoverCard.test.ts +204 -0
  94. package/components/auth/SelectPrincipal.vue +24 -6
  95. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  96. package/components/fleet/FleetConfigMapSelector.vue +117 -0
  97. package/components/fleet/FleetSecretSelector.vue +127 -0
  98. package/components/fleet/__tests__/FleetConfigMapSelector.test.ts +125 -0
  99. package/components/fleet/__tests__/FleetSecretSelector.test.ts +82 -0
  100. package/components/form/FileImageSelector.vue +13 -4
  101. package/components/form/FileSelector.vue +11 -2
  102. package/components/form/ResourceLabeledSelect.vue +1 -0
  103. package/components/form/__tests__/ResourceLabeledSelect.test.ts +90 -0
  104. package/components/formatter/Autoscaler.vue +97 -0
  105. package/components/formatter/InternalExternalIP.vue +198 -24
  106. package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
  107. package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
  108. package/components/google/util/__tests__/formatter.test.ts +47 -0
  109. package/components/google/util/formatter.ts +5 -2
  110. package/components/nav/Group.vue +12 -3
  111. package/components/nav/Header.vue +37 -16
  112. package/components/nav/NamespaceFilter.vue +13 -1
  113. package/components/nav/NotificationCenter/index.vue +2 -1
  114. package/components/nav/TopLevelMenu.helper.ts +16 -6
  115. package/components/nav/TopLevelMenu.vue +4 -2
  116. package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
  117. package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
  118. package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
  119. package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
  120. package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
  121. package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
  122. package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
  123. package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
  124. package/components/nav/WindowManager/constants.ts +23 -0
  125. package/components/nav/WindowManager/index.vue +61 -575
  126. package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
  127. package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
  128. package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
  129. package/components/templates/default.vue +4 -40
  130. package/components/templates/home.vue +31 -5
  131. package/components/templates/plain.vue +30 -4
  132. package/components/templates/standalone.vue +1 -1
  133. package/composables/useI18n.ts +10 -1
  134. package/composables/useInterval.ts +15 -0
  135. package/config/__test__/uiplugins.test.ts +309 -0
  136. package/config/labels-annotations.js +9 -1
  137. package/config/product/auth.js +1 -0
  138. package/config/product/explorer.js +3 -1
  139. package/config/product/manager.js +20 -9
  140. package/config/query-params.js +1 -0
  141. package/config/router/routes.js +10 -2
  142. package/config/settings.ts +10 -2
  143. package/config/store.js +4 -2
  144. package/config/table-headers.js +8 -0
  145. package/config/types.js +11 -0
  146. package/config/uiplugins.js +46 -2
  147. package/config/version.js +1 -1
  148. package/core/__test__/extension-manager-impl.test.js +236 -0
  149. package/core/extension-manager-impl.js +23 -6
  150. package/core/plugin-helpers.ts +2 -0
  151. package/core/types-provisioning.ts +4 -1
  152. package/detail/pod.vue +1 -0
  153. package/detail/provisioning.cattle.io.cluster.vue +13 -1
  154. package/dialog/AddonConfigConfirmationDialog.vue +45 -1
  155. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  156. package/dialog/RollbackWorkloadDialog.vue +2 -5
  157. package/directives/ui-context.ts +103 -0
  158. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +52 -11
  159. package/edit/auth/AuthProviderWarningBanners.vue +14 -1
  160. package/edit/auth/__tests__/oidc.test.ts +26 -0
  161. package/edit/auth/github-app-steps.vue +97 -0
  162. package/edit/auth/github-steps.vue +75 -0
  163. package/edit/auth/github.vue +99 -65
  164. package/edit/auth/oidc.vue +5 -1
  165. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  166. package/edit/cloudcredential.vue +1 -1
  167. package/edit/configmap.vue +1 -0
  168. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  169. package/edit/fleet.cattle.io.gitrepo.vue +0 -10
  170. package/edit/fleet.cattle.io.helmop.vue +51 -2
  171. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  172. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  173. package/edit/logging-flow/index.vue +1 -0
  174. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  175. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  176. package/edit/management.cattle.io.project.vue +1 -0
  177. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  178. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  179. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  180. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  181. package/edit/monitoring.coreos.com.route.vue +1 -1
  182. package/edit/namespace.vue +1 -0
  183. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  184. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  185. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +15 -5
  186. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  187. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  188. package/edit/node.vue +1 -0
  189. package/edit/persistentvolume/index.vue +27 -22
  190. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  191. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  192. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  193. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  194. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  195. package/edit/persistentvolume/plugins/csi.vue +18 -16
  196. package/edit/persistentvolume/plugins/fc.vue +13 -14
  197. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  198. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  199. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  200. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  201. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  202. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  203. package/edit/persistentvolume/plugins/local.vue +1 -3
  204. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  205. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  206. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  207. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  208. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  209. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  210. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  211. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  212. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  213. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
  214. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
  215. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +155 -0
  216. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +11 -9
  217. package/edit/provisioning.cattle.io.cluster/index.vue +25 -15
  218. package/edit/provisioning.cattle.io.cluster/rke2.vue +98 -17
  219. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +28 -2
  220. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
  221. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +92 -4
  222. package/edit/secret/index.vue +1 -1
  223. package/edit/service.vue +9 -4
  224. package/edit/serviceaccount.vue +1 -0
  225. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  226. package/edit/workload/index.vue +2 -1
  227. package/edit/workload/mixins/workload.js +1 -1
  228. package/initialize/App.vue +4 -4
  229. package/initialize/install-directives.js +2 -0
  230. package/initialize/install-plugins.js +19 -2
  231. package/list/projectsecret.vue +1 -1
  232. package/list/provisioning.cattle.io.cluster.vue +15 -2
  233. package/machine-config/amazonec2.vue +42 -135
  234. package/machine-config/azure.vue +1 -1
  235. package/machine-config/components/EC2Networking.vue +490 -0
  236. package/machine-config/components/__tests__/EC2Networking.test.ts +148 -0
  237. package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
  238. package/machine-config/digitalocean.vue +11 -0
  239. package/machine-config/google.vue +1 -1
  240. package/mixins/__tests__/brand.spec.ts +2 -2
  241. package/mixins/__tests__/chart.test.ts +21 -0
  242. package/mixins/brand.js +1 -7
  243. package/mixins/chart.js +8 -2
  244. package/mixins/create-edit-view/index.js +5 -0
  245. package/models/__tests__/chart.test.ts +49 -12
  246. package/models/__tests__/compliance.cattle.io.clusterscanprofile.spec.js +30 -0
  247. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  248. package/models/catalog.cattle.io.app.js +1 -1
  249. package/models/chart.js +28 -14
  250. package/models/cluster/node.js +13 -6
  251. package/models/cluster.x-k8s.io.machine.js +10 -20
  252. package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
  253. package/models/compliance.cattle.io.clusterscanprofile.js +1 -1
  254. package/models/management.cattle.io.authconfig.js +1 -0
  255. package/models/management.cattle.io.cluster.js +21 -3
  256. package/models/management.cattle.io.kontainerdriver.js +1 -0
  257. package/models/provisioning.cattle.io.cluster.js +249 -33
  258. package/package.json +6 -5
  259. package/pages/auth/login.vue +43 -4
  260. package/pages/auth/verify.vue +1 -1
  261. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +3 -2
  262. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  263. package/pages/c/_cluster/apps/charts/chart.vue +35 -17
  264. package/pages/c/_cluster/apps/charts/index.vue +11 -13
  265. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  266. package/pages/c/_cluster/explorer/EventsTable.vue +89 -3
  267. package/pages/c/_cluster/explorer/index.vue +8 -6
  268. package/pages/c/_cluster/explorer/tools/index.vue +3 -3
  269. package/pages/c/_cluster/manager/hostedprovider/index.vue +220 -0
  270. package/pages/c/_cluster/settings/brand.vue +1 -1
  271. package/pages/c/_cluster/settings/performance.vue +12 -25
  272. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  273. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  274. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  275. package/pages/home.vue +327 -16
  276. package/pkg/dynamic-importer.lib.js +4 -0
  277. package/plugins/axios.js +2 -1
  278. package/plugins/dashboard-client-init.js +3 -0
  279. package/plugins/dashboard-store/actions.js +1 -1
  280. package/plugins/dashboard-store/getters.js +18 -1
  281. package/plugins/dashboard-store/resource-class.js +21 -6
  282. package/plugins/dynamic-content.js +13 -0
  283. package/plugins/i18n.js +8 -0
  284. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  285. package/plugins/steve/steve-pagination-utils.ts +41 -22
  286. package/plugins/steve/subscribe.js +17 -9
  287. package/plugins/subscribe-events.ts +4 -2
  288. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  289. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -34
  290. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  291. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  292. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  293. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  294. package/rancher-components/Pill/types.ts +0 -1
  295. package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -0
  296. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
  297. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  298. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  299. package/rancher-components/RcIcon/index.ts +1 -0
  300. package/rancher-components/RcIcon/types.ts +160 -0
  301. package/rancher-components/utils/status.test.ts +67 -0
  302. package/rancher-components/utils/status.ts +77 -0
  303. package/scripts/extension/publish +1 -1
  304. package/scripts/typegen.sh +1 -0
  305. package/store/action-menu.js +8 -0
  306. package/store/auth.js +11 -6
  307. package/store/aws.js +8 -6
  308. package/store/catalog.js +6 -0
  309. package/store/features.js +2 -0
  310. package/store/index.js +45 -20
  311. package/store/notifications.ts +51 -4
  312. package/store/plugins.js +7 -3
  313. package/store/prefs.js +12 -6
  314. package/store/type-map.js +3 -3
  315. package/store/ui-context.ts +86 -0
  316. package/store/wm.ts +244 -0
  317. package/types/kube/kube-api.ts +2 -1
  318. package/types/notifications/index.ts +27 -3
  319. package/types/rancher/index.d.ts +1 -0
  320. package/types/resources/settings.d.ts +29 -7
  321. package/types/shell/index.d.ts +138 -4
  322. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  323. package/types/store/pagination.types.ts +157 -9
  324. package/types/store/subscribe-events.types.ts +8 -1
  325. package/types/store/subscribe.types.ts +1 -0
  326. package/types/window-manager.ts +24 -0
  327. package/utils/__tests__/cluster.test.ts +379 -1
  328. package/utils/__tests__/object.test.ts +19 -0
  329. package/utils/__tests__/provider.test.ts +98 -0
  330. package/utils/__tests__/selector-typed.test.ts +263 -0
  331. package/utils/__tests__/version.test.ts +19 -1
  332. package/utils/autoscaler-utils.ts +7 -0
  333. package/utils/back-off.ts +3 -3
  334. package/utils/brand.ts +29 -0
  335. package/utils/chart.js +18 -0
  336. package/utils/cluster.js +157 -3
  337. package/utils/color.js +1 -1
  338. package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
  339. package/utils/dynamic-content/__tests__/config.test.ts +187 -0
  340. package/utils/dynamic-content/__tests__/index.test.ts +390 -0
  341. package/utils/dynamic-content/__tests__/info.test.ts +275 -0
  342. package/utils/dynamic-content/__tests__/new-release.test.ts +216 -0
  343. package/utils/dynamic-content/__tests__/support-notice.test.ts +262 -0
  344. package/utils/dynamic-content/__tests__/util.test.ts +235 -0
  345. package/utils/dynamic-content/announcement.ts +142 -0
  346. package/utils/dynamic-content/config.ts +55 -0
  347. package/utils/dynamic-content/example.json +40 -0
  348. package/utils/dynamic-content/index.ts +277 -0
  349. package/utils/dynamic-content/info.ts +261 -0
  350. package/utils/dynamic-content/new-release.ts +126 -0
  351. package/utils/dynamic-content/notification-handler.ts +48 -0
  352. package/utils/dynamic-content/support-notice.ts +169 -0
  353. package/utils/dynamic-content/types.d.ts +153 -0
  354. package/utils/dynamic-content/util.ts +122 -0
  355. package/utils/dynamic-importer.js +2 -2
  356. package/utils/favicon.js +4 -4
  357. package/utils/inactivity.ts +104 -0
  358. package/utils/object.js +20 -2
  359. package/utils/pagination-utils.ts +19 -4
  360. package/utils/pagination-wrapper.ts +12 -8
  361. package/utils/provider.ts +14 -0
  362. package/utils/release-notes.ts +1 -1
  363. package/utils/scroll.js +7 -0
  364. package/utils/selector-typed.ts +6 -2
  365. package/utils/settings.ts +15 -0
  366. package/utils/validators/machine-pool.ts +13 -3
  367. package/utils/version.js +15 -0
  368. package/assets/images/icons/document.svg +0 -3
  369. package/plugins/nuxt-client-init.js +0 -3
  370. package/store/wm.js +0 -95
  371. /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
  372. /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
  373. /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
  374. /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
  375. /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
package/pages/home.vue CHANGED
@@ -7,10 +7,12 @@ import PaginatedResourceTable from '@shell/components/PaginatedResourceTable.vue
7
7
  import { BadgeState } from '@components/BadgeState';
8
8
  import CommunityLinks from '@shell/components/CommunityLinks.vue';
9
9
  import SingleClusterInfo from '@shell/components/SingleClusterInfo.vue';
10
+ import DynamicContentBanner from '@shell/components/DynamicContent/DynamicContentBanner.vue';
11
+ import DynamicContentPanel from '@shell/components/DynamicContent/DynamicContentPanel.vue';
10
12
  import { mapGetters, mapState } from 'vuex';
11
- import { MANAGEMENT, CAPI } from '@shell/config/types';
13
+ import { MANAGEMENT, CAPI, COUNT } from '@shell/config/types';
12
14
  import { NAME as MANAGER } from '@shell/config/product/manager';
13
- import { STATE } from '@shell/config/table-headers';
15
+ import { AGE, STATE } from '@shell/config/table-headers';
14
16
  import { MODE, _IMPORT } from '@shell/config/query-params';
15
17
  import { createMemoryFormat, formatSi, parseSi, createMemoryValues } from '@shell/utils/units';
16
18
  import { markSeenReleaseNotes } from '@shell/utils/version';
@@ -28,8 +30,12 @@ import { PaginationParamFilter, FilterArgs, PaginationFilterField, PaginationArg
28
30
  import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
29
31
  import { sameContents } from '@shell/utils/array';
30
32
  import { PagTableFetchPageSecondaryResourcesOpts, PagTableFetchSecondaryResourcesOpts, PagTableFetchSecondaryResourcesReturns } from '@shell/types/components/paginatedResourceTable';
31
- import { CURRENT_RANCHER_VERSION } from '@shell/config/version';
33
+ import { CURRENT_RANCHER_VERSION, getVersionData } from '@shell/config/version';
32
34
  import { CAPI as CAPI_LAB_AND_ANO } from '@shell/config/labels-annotations';
35
+ import paginationUtils from '@shell/utils/pagination-utils';
36
+ import ResourceTable from '@shell/components/ResourceTable.vue';
37
+ import Preset from '@shell/mixins/preset';
38
+ import { PaginationFeatureHomePageClusterConfig } from '@shell/types/resources/settings';
33
39
 
34
40
  export default defineComponent({
35
41
  name: 'Home',
@@ -42,9 +48,12 @@ export default defineComponent({
42
48
  CommunityLinks,
43
49
  SingleClusterInfo,
44
50
  TabTitle,
51
+ ResourceTable,
52
+ DynamicContentBanner,
53
+ DynamicContentPanel,
45
54
  },
46
55
 
47
- mixins: [PageHeaderActions],
56
+ mixins: [PageHeaderActions, Preset],
48
57
 
49
58
  data() {
50
59
  const options = this.$store.getters[`type-map/optionsFor`](CAPI.RANCHER_CLUSTER)?.custom || {};
@@ -200,15 +209,41 @@ export default defineComponent({
200
209
 
201
210
  clusterCount: 0,
202
211
 
203
- CURRENT_RANCHER_VERSION
212
+ CURRENT_RANCHER_VERSION,
213
+
214
+ /**
215
+ * User has decided to disable the alt list
216
+ */
217
+ altClusterListDisabled: false,
218
+ /**
219
+ * There are too many clusters to show in the home page list.
220
+ *
221
+ * If not disabled, show alt table
222
+ */
223
+ tooManyClusters: undefined as boolean | undefined,
224
+ altClusterListRows: undefined as any[] | undefined,
225
+ altClusterListFeature: paginationUtils.getFeature<PaginationFeatureHomePageClusterConfig>({ rootGetters: this.$store.getters }, 'homePageCluster'),
226
+
227
+ presetVersion: getVersionData()?.Version,
204
228
  };
205
229
  },
206
230
 
231
+ mounted() {
232
+ this.preset('altClusterListDisabled', 'boolean');
233
+ },
234
+
207
235
  computed: {
208
236
  ...mapState(['managementReady']),
209
237
  ...mapGetters(['currentCluster', 'defaultClusterId']),
210
238
  mcm: mapFeature(MULTI_CLUSTER),
211
239
 
240
+ vaiOnSettingsHeaders() {
241
+ return [
242
+ ...this.headers, // include age as we're sorting by it
243
+ AGE
244
+ ];
245
+ },
246
+
212
247
  canCreateCluster() {
213
248
  return !!this.provClusterSchema?.collectionMethods.find((x: string) => x.toLowerCase() === 'post');
214
249
  },
@@ -216,6 +251,21 @@ export default defineComponent({
216
251
  afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
217
252
  homePageCards: mapPref(HIDE_HOME_PAGE_CARDS),
218
253
 
254
+ /**
255
+ * Show the alt table
256
+ */
257
+ altClusterList() {
258
+ return this.tooManyClusters && !this.altClusterListDisabled;
259
+ }
260
+
261
+ },
262
+
263
+ watch: {
264
+ async altClusterList(neu) {
265
+ if (neu) {
266
+ await this.initAltClusters();
267
+ }
268
+ },
219
269
  },
220
270
 
221
271
  async created() {
@@ -227,6 +277,12 @@ export default defineComponent({
227
277
  // If we do not, then if they set the landing page, that won't work unless the release notes are marked read
228
278
  // otherwise we always take them to the home page to see the release notes
229
279
  markSeenReleaseNotes(this.$store);
280
+
281
+ this.tooManyClusters = this.isTooManyClusters();
282
+
283
+ if (this.altClusterList) {
284
+ await this.initAltClusters();
285
+ }
230
286
  },
231
287
 
232
288
  // Forget the types when we leave the page
@@ -246,8 +302,11 @@ export default defineComponent({
246
302
  return Promise.resolve({});
247
303
  }
248
304
 
305
+ const promises = [];
306
+
249
307
  if ( this.canViewMgmtClusters ) {
250
- this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
308
+ // This is the only one we need to block on (needed for the initial sort on mgmt name)
309
+ promises.push(this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER }));
251
310
  }
252
311
 
253
312
  if ( this.canViewMachine ) {
@@ -267,7 +326,7 @@ export default defineComponent({
267
326
  this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE_TEMPLATE });
268
327
  }
269
328
 
270
- return Promise.resolve({});
329
+ return Promise.all(promises);
271
330
  },
272
331
 
273
332
  async fetchPageSecondaryResources({
@@ -458,7 +517,83 @@ export default defineComponent({
458
517
  }
459
518
 
460
519
  return pagination;
461
- }
520
+ },
521
+
522
+ async toggleAltClusterListDisabled(disabled: boolean) {
523
+ // Clear the cache so the table doesn't show the previous mode's results
524
+ await this.$store.dispatch('management/forgetType', CAPI.RANCHER_CLUSTER);
525
+
526
+ this.altClusterListDisabled = disabled;
527
+ },
528
+
529
+ /**
530
+ * Determine if we should use an alternative cluster list which contains most recently created clusters
531
+ *
532
+ * Checks
533
+ * - can view clusters
534
+ * - if vai is on
535
+ * - if alt list feature is on
536
+ * - if cluster count exceeds threshold
537
+ */
538
+ isTooManyClusters(): boolean {
539
+ if (!this.provClusterSchema || !this.canViewMgmtClusters) {
540
+ return false;
541
+ }
542
+
543
+ const featureConfig = this.altClusterListFeature;
544
+
545
+ if (!featureConfig || !featureConfig.enabled) { // vai is off, or feature is explicitly disabled
546
+ return false;
547
+ }
548
+
549
+ const threshold = featureConfig.configuration?.threshold;
550
+
551
+ if (threshold === undefined) { // invalid config
552
+ return false;
553
+ }
554
+
555
+ const counts = this.$store.getters[`management/all`](COUNT)?.[0]?.counts || {};
556
+
557
+ this.clusterCount = counts[CAPI.RANCHER_CLUSTER]?.summary.count;
558
+
559
+ return this.clusterCount > threshold;
560
+ },
561
+
562
+ /**
563
+ * Fetch clusters used to populate alt table
564
+ */
565
+ async initAltClusters() {
566
+ const featureConfig = this.altClusterListFeature;
567
+ const results = featureConfig?.configuration?.results || 50;
568
+
569
+ // Fetch a limited number of provisioning clusters
570
+ const opt1: ActionFindPageArgs = {
571
+ pagination: {
572
+ projectsOrNamespaces: [],
573
+ filters: paginationFilterClusters(this.$store, false),
574
+ page: 1,
575
+ pageSize: results, // We're fetching the total results... then paging locally
576
+ sort: [{ field: 'metadata.creationTimestamp', asc: false }]
577
+ },
578
+ watch: false,
579
+ };
580
+ const provClusters = await this.$store.dispatch('management/findPage', { type: CAPI.RANCHER_CLUSTER, opt: opt1 });
581
+
582
+ // Also fetch the management clusters associated with the provisioning clusters
583
+ const opt2: ActionFindPageArgs = {
584
+ pagination: new FilterArgs({
585
+ filters: PaginationParamFilter.createMultipleFields(provClusters.map((r: any) => new PaginationFilterField({
586
+ field: 'id',
587
+ value: r.mgmtClusterId
588
+ }))),
589
+ }),
590
+ watch: false,
591
+ };
592
+
593
+ await this.$store.dispatch(`management/findPage`, { type: MANAGEMENT.CLUSTER, opt: opt2 });
594
+
595
+ this.altClusterListRows = provClusters;
596
+ },
462
597
  }
463
598
  });
464
599
 
@@ -476,18 +611,173 @@ export default defineComponent({
476
611
  {{ `${vendor} - ${t('landing.homepage')}` }}
477
612
  </TabTitle>
478
613
  <BannerGraphic
479
- :small="true"
480
614
  :title="t('landing.welcomeToRancher', {vendor})"
481
615
  :pref="HIDE_HOME_PAGE_CARDS"
482
616
  pref-key="welcomeBanner"
483
617
  data-testid="home-banner-graphic"
484
618
  />
619
+ <DynamicContentBanner location="banner" />
485
620
  <IndentedPanel class="mt-20 mb-20">
486
621
  <div class="row home-panels">
487
622
  <div class="col main-panel">
488
- <div class="row panel">
623
+ <div
624
+ v-if="altClusterList !== undefined"
625
+ class="row panel"
626
+ >
627
+ <div
628
+ v-if="mcm && altClusterList"
629
+ class="col span-12"
630
+ >
631
+ <ResourceTable
632
+ :schema="provClusterSchema"
633
+ :table-actions="false"
634
+ :row-actions="false"
635
+ key-field="id"
636
+
637
+ :headers="vaiOnSettingsHeaders"
638
+ defaultSortBy="age"
639
+
640
+ :loading="!altClusterListRows"
641
+
642
+ :rows="altClusterListRows || []"
643
+ :rowsPerPage="altClusterListFeature?.configuration.pagesPerRow || 10"
644
+
645
+ :namespaced="false"
646
+ :groupable="false"
647
+ >
648
+ <template #header-left>
649
+ <div class="row table-heading">
650
+ <h1 class="mb-0">
651
+ {{ t('landing.clusters.title') }}
652
+ </h1>
653
+ </div>
654
+ </template>
655
+ <template #sub-header-row>
656
+ <h2 class="too-many-clusters">
657
+ {{ t('landing.clusters.tooMany.showingSome', { rows: altClusterListRows?.length || '...', total: clusterCount}) }}
658
+ <a @click="toggleAltClusterListDisabled(true)">{{ t('landing.clusters.tooMany.showAll') }}</a>
659
+ </h2>
660
+ </template>
661
+ <!--
662
+ Below is a big copy & paste from PaginatedResourceTable, however should be temporary (altClusterList removed in 2.14 once full SSP support for clusters if available)
663
+ -->
664
+ <template
665
+ v-if="canCreateCluster || !!provClusterSchema"
666
+ #header-middle
667
+ >
668
+ <div class="table-heading">
669
+ <router-link
670
+ v-if="!!provClusterSchema"
671
+ :to="manageLocation"
672
+ class="btn btn-sm role-secondary"
673
+ data-testid="cluster-management-manage-button"
674
+ role="button"
675
+ :aria-label="t('cluster.manageAction')"
676
+ @keyup.space="$router.push(manageLocation)"
677
+ >
678
+ {{ t('cluster.manageAction') }}
679
+ </router-link>
680
+ <router-link
681
+ v-if="canCreateCluster"
682
+ :to="importLocation"
683
+ class="btn btn-sm role-primary"
684
+ data-testid="cluster-create-import-button"
685
+ role="button"
686
+ :aria-label="t('cluster.importAction')"
687
+ @keyup.space="$router.push(importLocation)"
688
+ >
689
+ {{ t('cluster.importAction') }}
690
+ </router-link>
691
+ <router-link
692
+ v-if="canCreateCluster"
693
+ :to="createLocation"
694
+ class="btn btn-sm role-primary"
695
+ data-testid="cluster-create-button"
696
+ role="button"
697
+ :aria-label="t('generic.create')"
698
+ @keyup.space="$router.push(createLocation)"
699
+ >
700
+ {{ t('generic.create') }}
701
+ </router-link>
702
+ </div>
703
+ </template>
704
+ <template #col:name="{row}">
705
+ <td class="col-name">
706
+ <div class="list-cluster-name">
707
+ <p
708
+ v-if="row.mgmt"
709
+ class="cluster-name"
710
+ >
711
+ <router-link
712
+ v-if="row.mgmt.isReady && !row.hasError"
713
+ :to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}"
714
+ role="link"
715
+ :aria-label="row.nameDisplay"
716
+ >
717
+ {{ row.nameDisplay }}
718
+ </router-link>
719
+ <span v-else>{{ row.nameDisplay }}</span>
720
+ <i
721
+ v-if="row.unavailableMachines"
722
+ v-clean-tooltip="row.unavailableMachines"
723
+ class="conditions-alert-icon icon-alert icon"
724
+ />
725
+ <i
726
+ v-if="row.isRke1"
727
+ v-clean-tooltip="t('cluster.rke1Unsupported')"
728
+ class="rke1-unsupported-icon icon-warning icon"
729
+ />
730
+ </p>
731
+ <p
732
+ v-if="row.description"
733
+ class="cluster-description"
734
+ >
735
+ {{ row.description }}
736
+ </p>
737
+ </div>
738
+ </td>
739
+ </template>
740
+ <template #col:kubernetesVersion="{row}">
741
+ <td class="col-name">
742
+ <span>
743
+ {{ row.kubernetesVersion }}
744
+ </span>
745
+ <div
746
+ v-clean-tooltip="{content: row.architecture.tooltip, placement: 'left'}"
747
+ class="text-muted"
748
+ >
749
+ {{ row.architecture.label }}
750
+ </div>
751
+ </td>
752
+ </template>
753
+ <template #col:cpu="{row}">
754
+ <td v-if="row.mgmt && cpuAllocatable(row.mgmt)">
755
+ {{ `${cpuAllocatable(row.mgmt)} ${t('landing.clusters.cores', {count:cpuAllocatable(row.mgmt) })}` }}
756
+ </td>
757
+ <td v-else>
758
+ &mdash;
759
+ </td>
760
+ </template>
761
+ <template #col:memory="{row}">
762
+ <td v-if="row.mgmt && memoryAllocatable(row.mgmt) && !memoryAllocatable(row.mgmt).match(/^0 [a-zA-z]/)">
763
+ {{ memoryAllocatable(row.mgmt) }}
764
+ </td>
765
+ <td v-else>
766
+ &mdash;
767
+ </td>
768
+ </template>
769
+ <!-- <template #cell:explorer="{row}">
770
+ <router-link v-if="row && row.isReady" class="btn btn-sm role-primary" :to="{name: 'c-cluster', params: {cluster: row.id}}">
771
+ {{ t('landing.clusters.explore') }}
772
+ </router-link>
773
+ <button v-else :disabled="true" class="btn btn-sm role-primary">
774
+ {{ t('landing.clusters.explore') }}
775
+ </button>
776
+ </template> -->
777
+ </ResourceTable>
778
+ </div>
489
779
  <div
490
- v-if="mcm"
780
+ v-else-if="mcm"
491
781
  class="col span-12"
492
782
  >
493
783
  <PaginatedResourceTable
@@ -511,16 +801,25 @@ export default defineComponent({
511
801
  >
512
802
  <template #header-left>
513
803
  <div class="row table-heading">
514
- <h2 class="mb-0">
804
+ <h1 class="mb-0">
515
805
  {{ t('landing.clusters.title') }}
516
- </h2>
806
+ </h1>
517
807
  <BadgeState
518
- v-if="clusterCount"
808
+ v-if="clusterCount && !tooManyClusters"
519
809
  :label="clusterCount.toString()"
520
- color="role-tertiary ml-20 mr-20"
810
+ color="bg-info ml-20 mr-20"
521
811
  />
522
812
  </div>
523
813
  </template>
814
+ <template
815
+ v-if="tooManyClusters"
816
+ #sub-header-row
817
+ >
818
+ <h2 class="too-many-clusters">
819
+ {{ t('landing.clusters.tooMany.showingAll', { rows: altClusterListRows?.length || '...', total: clusterCount}) }}
820
+ <a @click="toggleAltClusterListDisabled(false)">{{ t('landing.clusters.tooMany.showSome') }}</a>
821
+ </h2>
822
+ </template>
524
823
  <template
525
824
  v-if="canCreateCluster || !!provClusterSchema"
526
825
  #header-middle
@@ -644,7 +943,10 @@ export default defineComponent({
644
943
  </div>
645
944
  </div>
646
945
  </div>
647
- <CommunityLinks class="col span-3 side-panel" />
946
+ <div class="col span-3 side-panel">
947
+ <CommunityLinks />
948
+ <DynamicContentPanel location="rhs" />
949
+ </div>
648
950
  </div>
649
951
  </IndentedPanel>
650
952
  </div>
@@ -663,6 +965,14 @@ export default defineComponent({
663
965
  }
664
966
  .main-panel {
665
967
  flex: auto;
968
+
969
+ .too-many-clusters {
970
+ margin-bottom: 5px;
971
+
972
+ a {
973
+ cursor: pointer;
974
+ }
975
+ }
666
976
  }
667
977
 
668
978
  .side-panel {
@@ -744,6 +1054,7 @@ export default defineComponent({
744
1054
  .search {
745
1055
  align-items: center;
746
1056
  display: flex;
1057
+ height: 39px;
747
1058
 
748
1059
  > INPUT {
749
1060
  background-color: transparent;
@@ -25,6 +25,10 @@ export function importDetail(name) {
25
25
  return () => undefined;
26
26
  }
27
27
 
28
+ export function importDrawer(name) {
29
+ return () => undefined;
30
+ }
31
+
28
32
  export function importEdit(name) {
29
33
  return () => undefined;
30
34
  }
package/plugins/axios.js CHANGED
@@ -11,7 +11,8 @@ export default function({
11
11
  const options = { parseJSON: false };
12
12
  const csrf = store.getters['cookies/get']({ key: CSRF, options });
13
13
 
14
- if ( csrf ) {
14
+ // Request can ask not to send the CSRF header
15
+ if (csrf && !config.noApiCsrf) {
15
16
  config.headers['x-api-csrf'] = csrf;
16
17
  }
17
18
  });
@@ -0,0 +1,3 @@
1
+ export default async(context) => {
2
+ await context.store.dispatch('dashboardClientInit', context);
3
+ };
@@ -698,7 +698,7 @@ export default {
698
698
 
699
699
  const res = await dispatch('request', { opt, type });
700
700
 
701
- await dispatch('load', { data: res });
701
+ await dispatch('load', { data: res, invalidatePageCache: opt.invalidatePageCache });
702
702
 
703
703
  if ( opt.watch !== false ) {
704
704
  dispatch('watch', createFindWatchArg({
@@ -1,5 +1,8 @@
1
1
 
2
- import { SCHEMA, COUNT, POD } from '@shell/config/types';
2
+ import {
3
+ SCHEMA, COUNT, POD, MANAGEMENT, BRAND
4
+ } from '@shell/config/types';
5
+ import { SETTING } from '@shell/config/settings';
3
6
 
4
7
  import { matches } from '@shell/utils/selector';
5
8
  import { typeMunge, typeRef, SIMPLE_TYPES } from '@shell/utils/create-yaml';
@@ -204,6 +207,20 @@ export default {
204
207
  }
205
208
  },
206
209
 
210
+ brand: (state, getters) => {
211
+ const brand = getters['byId'](MANAGEMENT.SETTING, SETTING.BRAND);
212
+
213
+ if (!brand?.value) {
214
+ return undefined;
215
+ }
216
+
217
+ if ([BRAND.CSP, BRAND.FEDERAL, BRAND.RGS].includes(brand.value)) {
218
+ return BRAND.SUSE;
219
+ }
220
+
221
+ return brand.value;
222
+ },
223
+
207
224
  /**
208
225
  * Checks a schema for the given path
209
226
  *
@@ -39,7 +39,6 @@ import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
39
39
  import { ExtensionPoint, ActionLocation } from '@shell/core/types';
40
40
  import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
41
41
  import { parse } from '@shell/utils/selector';
42
- import { importDrawer } from '@shell/utils/dynamic-importer';
43
42
 
44
43
  export const DNS_LIKE_TYPES = ['dnsLabel', 'dnsLabelRestricted', 'hostname'];
45
44
 
@@ -906,11 +905,11 @@ export default class Resource {
906
905
  return out;
907
906
  }
908
907
 
909
- showConfiguration(returnFocusSelector) {
908
+ showConfiguration(returnFocusSelector, defaultTab) {
910
909
  const onClose = () => this.$ctx.commit('slideInPanel/close', undefined, { root: true });
911
910
 
912
911
  this.$ctx.commit('slideInPanel/open', {
913
- component: importDrawer('ResourceDetailDrawer'),
912
+ component: require(`@shell/components/Drawer/ResourceDetailDrawer/index.vue`).default,
914
913
  componentProps: {
915
914
  resource: this,
916
915
  onClose,
@@ -921,7 +920,8 @@ export default class Resource {
921
920
  'z-index': 101, // We want this to be above the main side menu
922
921
  closeOnRouteChange: ['name', 'params', 'query'], // We want to ignore hash changes, tables in extensions can trigger the drawer to close while opening
923
922
  triggerFocusTrap: true,
924
- returnFocusSelector
923
+ returnFocusSelector,
924
+ defaultTab
925
925
  }
926
926
  }, { root: true });
927
927
  }
@@ -1264,6 +1264,12 @@ export default class Resource {
1264
1264
  delete opt.replace;
1265
1265
  }
1266
1266
 
1267
+ // Will loading this resource invalidate the resources in the cache that represent a page (resource is not from page)
1268
+ // By default we set this to no, it won't pollute the cache. Most likely either
1269
+ // 1. The resource came from a list already (loaded resource is already in the page that is in the cache)
1270
+ // 2. UI is not on a page with a list (cache doesn't represent a list)
1271
+ const invalidatePageCache = opt.invalidatePageCache || false;
1272
+
1267
1273
  try {
1268
1274
  const res = await this.$dispatch('request', { opt, type: this.type } );
1269
1275
 
@@ -1272,7 +1278,9 @@ export default class Resource {
1272
1278
 
1273
1279
  // Steve sometimes returns Table responses instead of the resource you just saved.. ignore
1274
1280
  if ( res && res.kind !== 'Table') {
1275
- await this.$dispatch('load', { data: res, existing: (forNew ? this : undefined ) });
1281
+ await this.$dispatch('load', {
1282
+ data: res, existing: (forNew ? this : undefined ), invalidatePageCache
1283
+ });
1276
1284
  }
1277
1285
  } catch (e) {
1278
1286
  if ( this.type && this.id && e?._status === 409) {
@@ -1280,7 +1288,14 @@ export default class Resource {
1280
1288
  await this.$dispatch('find', {
1281
1289
  type: this.type,
1282
1290
  id: this.id,
1283
- opt: { force: true }
1291
+ opt: {
1292
+ // We want to update the value in cache, so force the request
1293
+ force: true,
1294
+ // We're not interested in opening a watch for this specific resource
1295
+ watch: false,
1296
+ // Unless overridden, this will be false, we're probably from a list and we don't want to clear it's state
1297
+ invalidatePageCache
1298
+ }
1284
1299
  });
1285
1300
  }
1286
1301
 
@@ -0,0 +1,13 @@
1
+ import { createHandler, DynamicContentAnnouncementHandlerName } from '@shell/utils/dynamic-content/notification-handler';
2
+ import { NotificationHandlerExtensionName } from '@shell/types/notifications';
3
+
4
+ /**
5
+ * Register the notification handler for dynamic content
6
+ */
7
+ export default function(context) {
8
+ const { store, $extension } = context;
9
+
10
+ const handler = createHandler(store);
11
+
12
+ $extension.register(NotificationHandlerExtensionName, DynamicContentAnnouncementHandlerName, handler);
13
+ }
package/plugins/i18n.js CHANGED
@@ -3,6 +3,14 @@ import { escapeHtml } from '../utils/string';
3
3
  import { watchEffect, ref, h } from 'vue';
4
4
  import { useStore } from 'vuex';
5
5
 
6
+ /**
7
+ * @param {import('vuex').Store<any>} store
8
+ * @param {string} key
9
+ * @param {Record<string, any>} [args]
10
+ * @param {boolean} [raw]
11
+ * @param {boolean} [escapehtml]
12
+ * @returns {string}
13
+ */
6
14
  export function stringFor(store, key, args, raw = false, escapehtml = true) {
7
15
  const translation = store.getters['i18n/t'](key, args);
8
16