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

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 (424) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/images/icons/document.svg +3 -0
  3. package/assets/images/key.svg +17 -0
  4. package/assets/images/vendor/cognito.svg +1 -0
  5. package/assets/styles/app.scss +1 -0
  6. package/assets/styles/base/_basic.scss +10 -0
  7. package/assets/styles/base/_spacing.scss +29 -0
  8. package/assets/styles/global/_form.scss +1 -1
  9. package/assets/styles/global/_labeled-input.scss +1 -1
  10. package/assets/styles/global/_layout.scss +1 -1
  11. package/assets/styles/themes/_dark.scss +28 -0
  12. package/assets/styles/themes/_light.scss +68 -0
  13. package/assets/styles/vendor/vue-select.scss +1 -1
  14. package/assets/translations/en-us.yaml +721 -83
  15. package/assets/translations/zh-hans.yaml +11 -9
  16. package/cloud-credential/gcp.vue +9 -1
  17. package/components/AppModal.vue +2 -0
  18. package/components/Certificates.vue +5 -0
  19. package/components/CodeMirror.vue +1 -1
  20. package/components/ConfigMapSettings/Settings.vue +377 -0
  21. package/components/ConfigMapSettings/index.vue +354 -0
  22. package/components/CruResource.vue +1 -2
  23. package/components/DetailText.vue +61 -11
  24. package/components/Drawer/Chrome.vue +116 -0
  25. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  26. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  27. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  28. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  29. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +82 -0
  30. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  31. package/components/Drawer/ResourceDetailDrawer/composables.ts +50 -0
  32. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  33. package/components/Drawer/ResourceDetailDrawer/index.vue +110 -0
  34. package/components/FilterPanel.vue +156 -0
  35. package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
  36. package/components/GrowlManager.vue +16 -15
  37. package/components/IconOrSvg.vue +19 -35
  38. package/components/KeyValueView.vue +1 -1
  39. package/components/LocaleSelector.vue +9 -1
  40. package/components/ProgressBarMulti.vue +1 -0
  41. package/components/PromptModal.vue +6 -1
  42. package/components/PromptRemove.vue +5 -1
  43. package/components/RelatedResources.vue +4 -12
  44. package/components/Resource/Detail/Additional.vue +46 -0
  45. package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
  46. package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
  47. package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
  48. package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
  49. package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
  50. package/components/Resource/Detail/Card/Scaler.vue +89 -0
  51. package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
  52. package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
  53. package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
  54. package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
  55. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
  56. package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
  57. package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
  58. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
  59. package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
  60. package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
  61. package/components/Resource/Detail/Card/index.vue +56 -0
  62. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
  63. package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
  64. package/components/Resource/Detail/Metadata/Annotations/index.vue +31 -0
  65. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  66. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
  67. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +64 -0
  68. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +298 -0
  69. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +133 -0
  70. package/components/Resource/Detail/Metadata/KeyValue.vue +138 -0
  71. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
  72. package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
  73. package/components/Resource/Detail/Metadata/Labels/index.vue +31 -0
  74. package/components/Resource/Detail/Metadata/Rectangle.vue +32 -0
  75. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
  76. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
  77. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  78. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
  79. package/components/Resource/Detail/Metadata/composables.ts +78 -0
  80. package/components/Resource/Detail/Metadata/index.vue +73 -0
  81. package/components/Resource/Detail/Page.vue +37 -0
  82. package/components/Resource/Detail/PercentageBar.vue +40 -0
  83. package/components/Resource/Detail/ResourceRow.vue +138 -0
  84. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  85. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  86. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  87. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  88. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  89. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  90. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  91. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  92. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  93. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  94. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  95. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  96. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  97. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  98. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  99. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  100. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  101. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  102. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  103. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  104. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  105. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  106. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  107. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  108. package/components/Resource/Detail/SpacedRow.vue +14 -0
  109. package/components/Resource/Detail/StatusBar.vue +59 -0
  110. package/components/Resource/Detail/StatusRow.vue +61 -0
  111. package/components/Resource/Detail/TitleBar/Title.vue +14 -0
  112. package/components/Resource/Detail/TitleBar/Top.vue +14 -0
  113. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
  114. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
  115. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  116. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
  117. package/components/Resource/Detail/TitleBar/composables.ts +44 -0
  118. package/components/Resource/Detail/TitleBar/index.vue +196 -0
  119. package/components/Resource/Detail/Top/index.vue +34 -0
  120. package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
  121. package/components/Resource/Detail/composables.ts +45 -0
  122. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  123. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  124. package/components/ResourceDetail/Masthead/index.vue +65 -0
  125. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  126. package/components/ResourceDetail/__tests__/index.test.ts +135 -0
  127. package/components/ResourceDetail/index.vue +73 -557
  128. package/components/ResourceDetail/legacy.vue +562 -0
  129. package/components/ResourceList/Masthead.vue +6 -0
  130. package/components/ResourceTable.vue +41 -7
  131. package/components/ResourceYaml.vue +14 -1
  132. package/components/SlideInPanelManager.vue +117 -10
  133. package/components/SortableTable/index.vue +13 -2
  134. package/components/SortableTable/selection.js +21 -8
  135. package/components/StateDot/index.vue +28 -0
  136. package/components/StatusBadge.vue +6 -4
  137. package/components/SubtleLink.vue +25 -0
  138. package/components/Tabbed/index.vue +11 -15
  139. package/components/Wizard.vue +16 -3
  140. package/components/YamlEditor.vue +1 -1
  141. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  142. package/components/__tests__/FilterPanel.test.ts +81 -0
  143. package/components/__tests__/GrowlManager.test.ts +0 -25
  144. package/components/auth/AuthBanner.vue +2 -3
  145. package/components/auth/RoleDetailEdit.vue +45 -3
  146. package/components/auth/login/ldap.vue +1 -1
  147. package/components/auth/login/oidc.vue +6 -1
  148. package/components/fleet/FleetApplications.vue +174 -0
  149. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  150. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  151. package/components/fleet/FleetClusters.vue +25 -6
  152. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  153. package/components/fleet/FleetHelmOps.vue +123 -0
  154. package/components/fleet/FleetIntro.vue +58 -28
  155. package/components/fleet/FleetNoWorkspaces.vue +5 -1
  156. package/components/fleet/FleetOCIStorageSecret.vue +171 -0
  157. package/components/fleet/FleetRepos.vue +37 -80
  158. package/components/fleet/FleetResources.vue +53 -26
  159. package/components/fleet/FleetSummary.vue +26 -51
  160. package/components/fleet/FleetValuesFrom.vue +295 -0
  161. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  162. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  163. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
  164. package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
  165. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  166. package/components/fleet/dashboard/Empty.vue +73 -0
  167. package/components/fleet/dashboard/ResourceCard.vue +184 -0
  168. package/components/fleet/dashboard/ResourceCardSummary.vue +195 -0
  169. package/components/fleet/dashboard/ResourceDetails.vue +194 -0
  170. package/components/fleet/dashboard/ResourcePanel.vue +383 -0
  171. package/components/form/ArrayList.vue +19 -2
  172. package/components/form/ChangePassword.vue +3 -1
  173. package/components/form/Footer.vue +10 -4
  174. package/components/form/KeyValue.vue +81 -43
  175. package/components/form/LabeledSelect.vue +56 -16
  176. package/components/form/Labels.vue +90 -17
  177. package/components/form/MatchExpressions.vue +46 -5
  178. package/components/form/NameNsDescription.vue +1 -1
  179. package/components/form/ResourceSelector.vue +1 -0
  180. package/components/form/ResourceTabs/index.vue +5 -0
  181. package/components/form/SecretSelector.vue +9 -2
  182. package/components/form/Select.vue +57 -19
  183. package/components/form/SimpleSecretSelector.vue +17 -4
  184. package/components/form/Taints.vue +21 -2
  185. package/components/form/UnitInput.vue +8 -0
  186. package/components/form/ValueFromResource.vue +31 -19
  187. package/components/form/__tests__/LabeledSelect.test.ts +8 -4
  188. package/components/form/__tests__/Labels.test.ts +360 -0
  189. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  190. package/components/form/__tests__/Select.test.ts +5 -2
  191. package/components/formatter/FleetApplicationClustersReady.vue +77 -0
  192. package/components/formatter/FleetApplicationSource.vue +71 -0
  193. package/components/formatter/FleetSummaryGraph.vue +7 -0
  194. package/components/formatter/WorkloadHealthScale.vue +1 -1
  195. package/components/google/AccountAccess.vue +211 -0
  196. package/components/google/types/gcp.d.ts +136 -0
  197. package/components/google/types/index.d.ts +101 -0
  198. package/components/google/util/__mocks__/gcp.ts +465 -0
  199. package/components/google/util/formatter.ts +82 -0
  200. package/components/google/util/gcp.ts +134 -0
  201. package/components/google/util/index.d.ts +11 -0
  202. package/components/nav/Favorite.vue +1 -1
  203. package/components/nav/Group.vue +70 -47
  204. package/components/nav/Header.vue +13 -8
  205. package/components/nav/NamespaceFilter.vue +13 -1
  206. package/components/nav/NotificationCenter/Notification.vue +510 -0
  207. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  208. package/components/nav/NotificationCenter/index.vue +148 -0
  209. package/components/nav/TopLevelMenu.helper.ts +55 -34
  210. package/components/nav/TopLevelMenu.vue +11 -0
  211. package/components/nav/Type.vue +4 -1
  212. package/composables/drawer.ts +26 -0
  213. package/composables/resources.test.ts +63 -0
  214. package/composables/resources.ts +38 -0
  215. package/composables/useI18n.ts +12 -11
  216. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  217. package/config/labels-annotations.js +20 -11
  218. package/config/product/auth.js +17 -1
  219. package/config/product/{cis.js → compliance.js} +23 -26
  220. package/config/product/explorer.js +5 -1
  221. package/config/product/fleet.js +77 -17
  222. package/config/product/settings.js +22 -11
  223. package/config/query-params.js +6 -1
  224. package/config/roles.ts +2 -1
  225. package/config/router/navigation-guards/authentication.js +51 -2
  226. package/config/router/routes.js +45 -31
  227. package/config/secret.ts +15 -0
  228. package/config/settings.ts +24 -5
  229. package/config/store.js +2 -0
  230. package/config/system-namespaces.js +1 -1
  231. package/config/table-headers.js +53 -23
  232. package/config/types.js +17 -6
  233. package/core/plugin-helpers.ts +3 -2
  234. package/core/plugin.ts +32 -7
  235. package/core/types.ts +18 -1
  236. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  237. package/detail/fleet.cattle.io.cluster.vue +28 -15
  238. package/detail/fleet.cattle.io.gitrepo.vue +10 -1
  239. package/detail/fleet.cattle.io.helmop.vue +157 -0
  240. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  241. package/detail/management.cattle.io.oidcclient.vue +369 -0
  242. package/detail/node.vue +2 -2
  243. package/detail/pod.vue +2 -2
  244. package/detail/service.vue +10 -1
  245. package/detail/workload/index.vue +8 -2
  246. package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
  247. package/dialog/GenericPrompt.vue +1 -1
  248. package/dialog/HelmOpForceUpdateDialog.vue +132 -0
  249. package/dialog/ImportDialog.vue +8 -8
  250. package/dialog/OidcClientSecretDialog.vue +117 -0
  251. package/dialog/RedeployWorkloadDialog.vue +164 -0
  252. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  253. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +60 -68
  254. package/edit/auth/oidc.vue +159 -93
  255. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  256. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  257. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  258. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  259. package/edit/configmap.vue +4 -1
  260. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  261. package/edit/fleet.cattle.io.gitrepo.vue +70 -255
  262. package/edit/fleet.cattle.io.helmop.vue +772 -0
  263. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  264. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  265. package/edit/logging-flow/index.vue +1 -0
  266. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  267. package/edit/management.cattle.io.fleetworkspace.vue +44 -10
  268. package/edit/management.cattle.io.oidcclient.vue +162 -0
  269. package/edit/management.cattle.io.project.vue +4 -1
  270. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  271. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  272. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  273. package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
  274. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  275. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  276. package/edit/monitoring.coreos.com.route.vue +1 -0
  277. package/edit/namespace.vue +1 -0
  278. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  279. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  280. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
  281. package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
  282. package/edit/node.vue +1 -0
  283. package/edit/persistentvolume/index.vue +4 -1
  284. package/edit/provisioning.cattle.io.cluster/rke2.vue +418 -382
  285. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +27 -27
  286. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  287. package/edit/resources.cattle.io.restore.vue +1 -1
  288. package/edit/secret/index.vue +1 -0
  289. package/edit/service.vue +4 -1
  290. package/edit/serviceaccount.vue +4 -1
  291. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  292. package/edit/workload/index.vue +5 -0
  293. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  294. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  295. package/list/fleet.cattle.io.helmop.vue +108 -0
  296. package/list/management.cattle.io.oidcclient.vue +108 -0
  297. package/list/namespace.vue +5 -2
  298. package/list/node.vue +2 -0
  299. package/machine-config/amazonec2.vue +3 -24
  300. package/machine-config/components/GCEImage.vue +374 -0
  301. package/machine-config/google.vue +617 -0
  302. package/mixins/__tests__/brand.spec.ts +170 -0
  303. package/mixins/auth-config.js +8 -1
  304. package/mixins/brand.js +16 -17
  305. package/mixins/create-edit-view/index.js +5 -0
  306. package/mixins/preset.js +100 -0
  307. package/mixins/resource-fetch-api-pagination.js +18 -0
  308. package/mixins/resource-fetch.js +1 -1
  309. package/mixins/resource-table-watch.js +45 -0
  310. package/mixins/vue-select-overrides.js +1 -0
  311. package/models/__tests__/chart.test.ts +273 -0
  312. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
  313. package/models/chart.js +144 -2
  314. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  315. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  316. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  317. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  318. package/models/fleet-application.js +314 -0
  319. package/models/fleet.cattle.io.bundle.js +9 -8
  320. package/models/fleet.cattle.io.cluster.js +11 -0
  321. package/models/fleet.cattle.io.gitrepo.js +41 -365
  322. package/models/fleet.cattle.io.helmop.js +198 -0
  323. package/models/management.cattle.io.authconfig.js +1 -0
  324. package/models/management.cattle.io.fleetworkspace.js +14 -1
  325. package/models/management.cattle.io.oidcclient.js +18 -0
  326. package/models/management.cattle.io.registration.js +3 -0
  327. package/models/provisioning.cattle.io.cluster.js +5 -5
  328. package/models/service.js +4 -0
  329. package/models/workload.js +19 -18
  330. package/package.json +2 -1
  331. package/pages/about.vue +4 -58
  332. package/pages/auth/login.vue +1 -1
  333. package/pages/auth/verify.vue +13 -1
  334. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +36 -0
  335. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
  336. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +54 -0
  337. package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
  338. package/pages/c/_cluster/apps/charts/index.vue +487 -465
  339. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  340. package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
  341. package/pages/c/_cluster/explorer/index.vue +3 -3
  342. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  343. package/pages/c/_cluster/fleet/__tests__/index.test.ts +426 -0
  344. package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
  345. package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
  346. package/pages/c/_cluster/fleet/application/create.vue +341 -0
  347. package/pages/c/_cluster/fleet/application/index.vue +139 -0
  348. package/pages/c/_cluster/fleet/graph/config.js +277 -0
  349. package/pages/c/_cluster/fleet/index.vue +809 -329
  350. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  351. package/pages/c/_cluster/longhorn/index.vue +5 -2
  352. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  353. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  354. package/pages/explorer/resource/detail/configmap.vue +42 -0
  355. package/pages/explorer/resource/detail/secret.vue +50 -0
  356. package/pages/home.vue +9 -55
  357. package/pages/support/index.vue +4 -6
  358. package/plugins/dashboard-store/actions.js +50 -14
  359. package/plugins/dashboard-store/getters.js +38 -21
  360. package/plugins/dashboard-store/mutations.js +51 -7
  361. package/plugins/dashboard-store/resource-class.js +30 -4
  362. package/plugins/steve/__tests__/subscribe.spec.ts +66 -1
  363. package/plugins/steve/actions.js +3 -0
  364. package/plugins/steve/steve-pagination-utils.ts +17 -8
  365. package/plugins/steve/subscribe.js +235 -43
  366. package/rancher-components/BadgeState/BadgeState.vue +3 -1
  367. package/rancher-components/Banner/Banner.vue +13 -0
  368. package/rancher-components/Form/Checkbox/Checkbox.vue +11 -6
  369. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  370. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  371. package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
  372. package/rancher-components/RcItemCard/RcItemCard.vue +430 -0
  373. package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
  374. package/rancher-components/RcItemCard/index.ts +2 -0
  375. package/store/auth.js +3 -0
  376. package/store/catalog.js +85 -25
  377. package/store/growl.js +97 -8
  378. package/store/index.js +39 -14
  379. package/store/notifications.ts +426 -0
  380. package/store/prefs.js +0 -1
  381. package/store/slideInPanel.ts +6 -0
  382. package/store/type-map.js +19 -15
  383. package/store/uiplugins.ts +15 -1
  384. package/types/fleet.d.ts +59 -0
  385. package/types/notifications/index.ts +74 -0
  386. package/types/resources/settings.d.ts +19 -1
  387. package/types/shell/index.d.ts +388 -307
  388. package/types/store/dashboard-store.types.ts +33 -3
  389. package/types/store/pagination.types.ts +6 -1
  390. package/types/store/subscribe.types.ts +50 -0
  391. package/utils/__tests__/fleet.test.ts +148 -0
  392. package/utils/__tests__/object.test.ts +54 -1
  393. package/utils/__tests__/string.test.ts +273 -1
  394. package/utils/__tests__/time.test.ts +31 -0
  395. package/utils/auth.js +41 -5
  396. package/utils/crypto/encryption.ts +103 -0
  397. package/utils/cspAdaptor.ts +51 -0
  398. package/utils/fleet-types.ts +0 -0
  399. package/utils/fleet.ts +190 -2
  400. package/utils/object.js +36 -0
  401. package/utils/pagination-utils.ts +27 -2
  402. package/utils/pagination-wrapper.ts +132 -50
  403. package/utils/release-notes.ts +48 -0
  404. package/utils/selector-typed.ts +7 -2
  405. package/utils/settings.ts +4 -1
  406. package/utils/string.js +24 -0
  407. package/utils/style.ts +39 -0
  408. package/utils/{time.js → time.ts} +25 -6
  409. package/utils/uiplugins.ts +22 -0
  410. package/utils/validators/formRules/__tests__/index.test.ts +36 -3
  411. package/utils/validators/formRules/index.ts +13 -3
  412. package/utils/window.js +11 -7
  413. package/components/__tests__/ApplicationCard.test.ts +0 -27
  414. package/components/cards/ApplicationCard.vue +0 -145
  415. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
  416. package/config/product/legacy.js +0 -62
  417. package/config/secret.js +0 -14
  418. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
  419. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  420. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  421. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  422. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
  423. /package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -0
  424. /package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +0 -0
@@ -9,6 +9,7 @@ import garbageCollect from '@shell/utils/gc/gc';
9
9
  import { addSchemaIndexFields } from '@shell/plugins/steve/schema.utils';
10
10
  import { addParam, parse } from '@shell/utils/url';
11
11
  import { conditionalDepaginate } from '@shell/store/type-map.utils';
12
+ import { STEVE_WATCH_MODE } from '@shell/types/store/subscribe.types';
12
13
  import { FilterArgs } from '@shell/types/store/pagination.types';
13
14
  import { isLabelSelectorEmpty, labelSelectorToSelector } from '@shell/utils/selector-typed';
14
15
 
@@ -183,7 +184,6 @@ export default {
183
184
 
184
185
  opt = opt || {};
185
186
  type = getters.normalizeType(type);
186
-
187
187
  if ( !getters.typeRegistered(type) ) {
188
188
  commit('registerType', type);
189
189
  }
@@ -408,10 +408,12 @@ export default {
408
408
  *
409
409
  * @param {*} ctx
410
410
  * @param { {type: string, opt: ActionFindPageArgs} } opt
411
+ * @returns @ActionFindPageResponse
411
412
  */
412
413
  async findPage(ctx, { type, opt }) {
413
414
  const { getters, commit, dispatch } = ctx;
414
415
 
416
+ // of type @ActionFindPageArgs
415
417
  opt = opt || {};
416
418
 
417
419
  if (!opt.pagination) {
@@ -426,12 +428,24 @@ export default {
426
428
  commit('registerType', type);
427
429
  }
428
430
 
431
+ // of type @STEVE_WATCH_PARAMS
432
+ const watchArgs = {
433
+ type,
434
+ namespace: opt.watchNamespace || opt.namespaced, // it could be either apparently
435
+ force: opt.forceWatch === true,
436
+ mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
437
+ };
438
+
429
439
  // No need to request the resources if we have them already
430
440
  if (!opt.transient && !opt.force && getters['havePaginatedPage'](type, opt)) {
441
+ if (opt.watch !== false ) {
442
+ dispatch('watch', watchArgs);
443
+ }
444
+
431
445
  return findAllGetter(getters, type, opt);
432
446
  }
433
447
 
434
- console.log(`Find Page: [${ ctx.state.config.namespace }] ${ type }. Page: ${ opt.pagination.page }. Size: ${ opt.pagination.pageSize }`); // eslint-disable-line no-console
448
+ console.log(`Find Page: [${ ctx.state.config.namespace }] ${ type }. Page: ${ opt.pagination.page }. Size: ${ opt.pagination.pageSize }. Sort: ${ opt.pagination.sort.map((s) => s.field).join(', ') }`); // eslint-disable-line no-console
435
449
  opt = opt || {};
436
450
  opt.url = getters.urlFor(type, null, opt);
437
451
 
@@ -451,11 +465,7 @@ export default {
451
465
  return Promise.reject(e);
452
466
  }
453
467
 
454
- await dispatch('unwatch', {
455
- type,
456
- all: true,
457
- });
458
-
468
+ // Of type @StorePagination
459
469
  const pagination = opt.pagination ? {
460
470
  request: {
461
471
  namespace: opt.namespaced,
@@ -472,11 +482,16 @@ export default {
472
482
  commit('loadPage', {
473
483
  ctx,
474
484
  type,
475
- data: out.data,
485
+ data: out.data,
476
486
  pagination,
487
+ revision: out.revision,
477
488
  });
478
489
  }
479
490
 
491
+ if ( !opt.transient && opt.watch !== false ) {
492
+ dispatch('watch', watchArgs);
493
+ }
494
+
480
495
  if (opt.hasManualRefresh) {
481
496
  dispatch('resource-fetch/updateManualRefreshIsLoading', false, { root: true });
482
497
  }
@@ -499,6 +514,9 @@ export default {
499
514
  * b) Pagination Disabled - use the old 'native kube api' - findMatching
500
515
  *
501
516
  * Filter is defined via the kube labelSelector object (see KubeLabelSelector)
517
+ *
518
+ * opt: @ActionFindLabelSelectorArgs
519
+ * @returns @ActionFindMatchingResponse (resources[], or if transient { data: resources[], pagination: StorePagination })
502
520
  */
503
521
  async findLabelSelector(ctx, {
504
522
  type,
@@ -515,6 +533,8 @@ export default {
515
533
  context,
516
534
  };
517
535
 
536
+ opt = opt || {};
537
+
518
538
  if (getters[`paginationEnabled`]?.(args)) {
519
539
  if (isLabelSelectorEmpty(labelSelector)) {
520
540
  throw new Error(`labelSelector must not be empty when using findLabelSelector (avoid fetching all resources)`);
@@ -524,21 +544,28 @@ export default {
524
544
  return dispatch('findPage', {
525
545
  type,
526
546
  opt: {
527
- ...(opt || {}),
547
+ ...opt,
528
548
  namespaced: namespace,
529
549
  pagination: new FilterArgs({ labelSelector }),
550
+ transient: opt?.transient !== undefined ? opt.transient : false // Call this out explicitly here, as by default findX methods ar eusually be cached AND watched
530
551
  }
531
552
  });
532
553
  }
533
554
 
534
- return dispatch('findMatching', {
555
+ // opt of type ActionFindPageArgs
556
+ const findMatching = await dispatch('findMatching', {
535
557
  type,
536
558
  selector: labelSelectorToSelector(labelSelector),
537
559
  opt,
538
560
  namespace,
539
561
  });
562
+
563
+ return opt.transient ? { data: findMatching } : findMatching;
540
564
  },
541
565
 
566
+ /**
567
+ * opt: @ActionFindMatchingArgs
568
+ */
542
569
  async findMatching(ctx, {
543
570
  type,
544
571
  selector,
@@ -671,7 +698,15 @@ export default {
671
698
  return out;
672
699
  },
673
700
 
674
- load(ctx, { data, existing }) {
701
+ /**
702
+ * Add or update the given resource in the store
703
+ *
704
+ * invalidatePageCache
705
+ * - if something calls `load` then the cache no longer has a page so we invalidate it
706
+ * - however on resource create or remove this can lead to lists showing nothing... before the new page is fetched
707
+ * - for those cases avoid invaliding the page cache
708
+ */
709
+ load(ctx, { data, existing, invalidatePageCache }) {
675
710
  const { getters, commit } = ctx;
676
711
 
677
712
  let type = normalizeType(data.type);
@@ -704,7 +739,8 @@ export default {
704
739
  commit('load', {
705
740
  ctx,
706
741
  data,
707
- existing
742
+ existing,
743
+ invalidatePageCache // Avoid havePage invalidation
708
744
  });
709
745
 
710
746
  if ( type === SCHEMA ) {
@@ -774,9 +810,9 @@ export default {
774
810
 
775
811
  // Forget a type in the store
776
812
  // Remove all entries for that type and stop watching it
777
- forgetType({ commit, dispatch, state }, type) {
813
+ forgetType({ commit, dispatch, state }, type, compareWatches) {
778
814
  state.started
779
- .filter((entry) => entry.type === type)
815
+ .filter((entry) => compareWatches ? compareWatches(entry) : entry.type === type)
780
816
  .forEach((entry) => dispatch('unwatch', entry));
781
817
 
782
818
  commit('forgetType', type);
@@ -50,6 +50,33 @@ export const urlFor = (state, getters) => (type, id, opt) => {
50
50
  return url;
51
51
  };
52
52
 
53
+ function resourceCount(rootGetters, getters, typeObj) {
54
+ let _typeObj = typeObj;
55
+ const { name: type, count } = _typeObj;
56
+
57
+ if (!type) {
58
+ throw new Error(`Resource type required to calc count: ${ JSON.stringify(typeObj) }`);
59
+ }
60
+
61
+ if (!count) {
62
+ const schema = getters.schemaFor(type);
63
+ const counts = getters.all(COUNT)?.[0]?.counts || {};
64
+ const count = counts[type];
65
+
66
+ // This object aligns with `Type.vue` `type`
67
+ _typeObj = {
68
+ count: count ? count.summary.count || 0 : null,
69
+ byNamespace: count ? count.namespaces : {},
70
+ revision: count ? count.revision : null,
71
+ namespaced: schema?.attributes?.namespaced
72
+ };
73
+ }
74
+
75
+ const namespaces = _typeObj?.namespaced && !rootGetters.isAllNamespaces ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
76
+
77
+ return matchingCounts(_typeObj, namespaces.length ? namespaces : null);
78
+ }
79
+
53
80
  /**
54
81
  * Find the number of resources given
55
82
  * - if the type is namespaced
@@ -125,6 +152,10 @@ export default {
125
152
  return getters.all(type);
126
153
  }
127
154
 
155
+ if (getters['havePage'](type)) {
156
+ return getters.all(type);
157
+ }
158
+
128
159
  // Does the store have all and we can pretend like it contains a result of a labelSelector?
129
160
  if (getters['haveAll'](type)) {
130
161
  return getters.matching( type, selector, namespace );
@@ -374,6 +405,9 @@ export default {
374
405
  return state.types[type]?.haveNamespace || null;
375
406
  },
376
407
 
408
+ /**
409
+ * Returns (type: string ) => StorePagination
410
+ */
377
411
  havePage: (state, getters) => (type) => {
378
412
  type = getters.normalizeType(type);
379
413
 
@@ -455,30 +489,13 @@ export default {
455
489
  *
456
490
  */
457
491
  count: (state, getters, rootState, rootGetters) => (typeObj) => {
458
- let _typeObj = typeObj;
459
- const { name: type, count } = _typeObj;
492
+ const subTypes = rootGetters['type-map/optionsFor'](typeObj.name).subTypes || [];
460
493
 
461
- if (!type) {
462
- throw new Error(`Resource type required to calc count: ${ JSON.stringify(typeObj) }`);
494
+ if (subTypes.length) {
495
+ return subTypes.reduce((acc, type) => acc + resourceCount(rootGetters, getters, { name: type }), 0);
463
496
  }
464
497
 
465
- if (!count) {
466
- const schema = getters.schemaFor(type);
467
- const counts = getters.all(COUNT)?.[0]?.counts || {};
468
- const count = counts[type];
469
-
470
- // This object aligns with `Type.vue` `type`
471
- _typeObj = {
472
- count: count ? count.summary.count || 0 : null,
473
- byNamespace: count ? count.namespaces : {},
474
- revision: count ? count.revision : null,
475
- namespaced: schema?.attributes?.namespaced
476
- };
477
- }
478
-
479
- const namespaces = _typeObj?.namespaced && !rootGetters.isAllNamespaces ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
480
-
481
- return matchingCounts(_typeObj, namespaces.length ? namespaces : null);
498
+ return resourceCount(rootGetters, getters, typeObj);
482
499
  },
483
500
 
484
501
  generation: (state, getters) => (type) => {
@@ -86,8 +86,16 @@ export function createLoadArgs(ctx, dataType) {
86
86
  };
87
87
  }
88
88
 
89
+ /**
90
+ * Add or update the given resource in the store
91
+ *
92
+ * invalidatePageCache
93
+ * - if something calls `load` then the cache no longer has a page so we invalidate it
94
+ * - however on resource create or remove this can lead to lists showing nothing... before the new page is fetched
95
+ * - for those cases avoid invaliding the page cache
96
+ */
89
97
  export function load(state, {
90
- data, ctx, existing, cachedArgs
98
+ data, ctx, existing, cachedArgs, invalidatePageCache = true,
91
99
  }) {
92
100
  const { getters } = ctx;
93
101
  // Optimisation. This can run once per resource loaded.., so pass in from parent
@@ -130,8 +138,12 @@ export function load(state, {
130
138
  }
131
139
  } else {
132
140
  if (inMap) {
141
+ // In theory cached `entry` should match provided `existing`, so changes merged from `data` into `entry` should be reflected in `existing`.
142
+ // However.. there's a disconnect happening somewhere so merge data into `existing` before merging into `entry`
143
+ const latestEntry = existing && entry !== existing ? replaceResource(existing, data, getters) : data;
144
+
133
145
  // There's already an entry in the store, so merge changes into it. The list entry is a reference to the map (and vice versa)
134
- entry = replaceResource(entry, data, getters);
146
+ entry = replaceResource(entry, latestEntry, getters);
135
147
  } else {
136
148
  // There's no entry, make a new proxy
137
149
  entry = reactive(classify(ctx, data));
@@ -164,7 +176,8 @@ export function load(state, {
164
176
  }
165
177
  }
166
178
 
167
- cache.havePage = false;
179
+ // see `invalidatePageCache` description above
180
+ cache.havePage = invalidatePageCache ? false : cache.havePage;
168
181
 
169
182
  return entry;
170
183
  }
@@ -476,29 +489,60 @@ export default {
476
489
  data,
477
490
  ctx,
478
491
  pagination,
492
+ revision
479
493
  }) {
480
494
  if (!data) {
481
495
  return;
482
496
  }
497
+ // We loop over data three times in this mutator, which is bad
498
+ // However we're only dealing with pageSize worth of data and splitting out into three loops improves legibility
483
499
 
484
500
  const keyField = ctx.getters.keyFieldForType(type);
485
- const proxies = reactive(data.map((x) => classify(ctx, x)));
501
+
502
+ // Why don't we just replace the map? Because we
503
+ // 1. nav to list, subscribe to changes
504
+ // 2. nav to resource in list
505
+ // 3. update to page comes over
506
+ // 4. need to update the reference the detail list uses
507
+ const proxiesMap = {};
508
+ const proxies = reactive(data.map((x) => {
509
+ proxiesMap[x[keyField]] = true;
510
+
511
+ return classify(ctx, x);
512
+ }));
486
513
  const cache = registerType(state, type);
487
514
 
488
- clear(cache.list);
489
- cache.map.clear();
490
515
  cache.generation++;
491
516
 
517
+ // Update list
518
+ clear(cache.list);
492
519
  addObjects(cache.list, proxies);
493
520
 
521
+ // Update Map (remove stale)
522
+ cache.map.forEach((value, key) => {
523
+ if (!proxiesMap[value[keyField]]) {
524
+ cache.map.delete(key);
525
+ }
526
+ });
527
+
528
+ // Update Map (update existing / add latest)
494
529
  for ( let i = 0 ; i < proxies.length ; i++ ) {
495
- cache.map.set(proxies[i][keyField], proxies[i]);
530
+ // This could probably be merged with the first loop above
531
+ const existing = cache.map.get(proxies[i][keyField]);
532
+ const latest = proxies[i];
533
+
534
+ if (existing) {
535
+ replaceResource(existing, latest, ctx.getters);
536
+ } else {
537
+ cache.map.set(latest[keyField], latest);
538
+ }
496
539
  }
497
540
 
498
541
  // havePage is of type `StorePagination`
499
542
  cache.havePage = pagination;
500
543
  cache.haveNamespace = undefined;
501
544
  cache.haveAll = undefined;
545
+ cache.revision = revision;
502
546
 
503
547
  return proxies;
504
548
  },
@@ -736,6 +736,17 @@ export default class Resource {
736
736
  );
737
737
  }
738
738
 
739
+ get stateColorPair() {
740
+ return {
741
+ state: this.stateDisplay,
742
+ color: this.stateSimpleColor
743
+ };
744
+ }
745
+
746
+ get stateSimpleColor() {
747
+ return this.stateColor.replace('text-', '');
748
+ }
749
+
739
750
  get stateBackground() {
740
751
  return this.stateColor.replace('text-', 'bg-');
741
752
  }
@@ -1180,7 +1191,8 @@ export default class Resource {
1180
1191
  }
1181
1192
 
1182
1193
  // @TODO remove this once the API maps steve _type <-> k8s type in both directions
1183
- // Completely disconnect the object we're going to save (and mangle in cleanForSave) and `this`
1194
+ // `JSON.parse(JSON.stringify` - Completely disconnect the object we're going to send and `this`. This ensures that properties
1195
+ // removed from opt.data before sending (as part of cleanForSave) are not stripped from where they're still needed (`this`)
1184
1196
  opt.data = this.toSave() || JSON.parse(JSON.stringify(this));
1185
1197
 
1186
1198
  if (opt.data._type) {
@@ -1248,7 +1260,18 @@ export default class Resource {
1248
1260
 
1249
1261
  const res = await this.$dispatch('request', { opt, type: this.type } );
1250
1262
 
1251
- if ( res?._status === 204 ) {
1263
+ // In theory...
1264
+ // 200 - resource could have finalizer (could hang around, keep resource to show deleting state)
1265
+ // 204 - resource should be gone gone (so remove immediately)
1266
+ // However...
1267
+ // 200 - this is the only status code returned
1268
+ if ( res?._status === 200 ) {
1269
+ // Show state (probably terminating) immediately, don't wait for resource.change or debounced resource.changes update
1270
+ // It would be neater to only do this in the debounced resource.changes world, but there's no neat / complete way to do this (paginationUtils will cause dep issues if imported)
1271
+ await this.$dispatch('load', {
1272
+ data: res, existing: this, invalidatePageCache: false
1273
+ });
1274
+ } else if ( res?._status === 204 ) {
1252
1275
  // If there's no body, assume the resource was immediately deleted
1253
1276
  // and drop it from the store as if a remove event happened.
1254
1277
  await this.$dispatch('ws.resource.remove', { data: this });
@@ -1856,10 +1879,13 @@ export default class Resource {
1856
1879
  namespace,
1857
1880
  labelSelector: { matchExpressions: parse(selector) }
1858
1881
  },
1859
- opts: opt
1882
+ opts: {
1883
+ transient: true,
1884
+ ...opt,
1885
+ },
1860
1886
  });
1861
1887
 
1862
- addObjects(out, matching);
1888
+ addObjects(out, matching.data);
1863
1889
  }
1864
1890
 
1865
1891
  // Find all the resources that match the required id's
@@ -1,4 +1,4 @@
1
- import { actions } from '../subscribe';
1
+ import { actions, getters } from '../subscribe';
2
2
 
3
3
  describe('steve: subscribe', () => {
4
4
  describe('actions', () => {
@@ -106,4 +106,69 @@ describe('steve: subscribe', () => {
106
106
  });
107
107
  });
108
108
  });
109
+
110
+ describe('getters', () => {
111
+ describe('nextResourceVersion', () => {
112
+ const myType = 'myType';
113
+ const myId = `myId`;
114
+
115
+ type Revision = string | number | null | undefined
116
+
117
+ const createState = (revision?: Revision, cachedList?: any[] ) => {
118
+ const typeState: any = {};
119
+
120
+ if (revision !== undefined) {
121
+ typeState.revision = revision;
122
+ }
123
+ if (cachedList !== undefined) {
124
+ typeState.list = cachedList;
125
+ } else {
126
+ typeState.list = [];
127
+ }
128
+
129
+ return { types: { [myType.toLocaleLowerCase()]: typeState } };
130
+ };
131
+
132
+ const createGetters = (revision?: Revision) => {
133
+ return {
134
+ byId: (type: any, id: any) => {
135
+ expect(type).toBe(myType.toLowerCase());
136
+ expect(id).toBe(myId);
137
+
138
+ return { metadata: { resourceVersion: revision } };
139
+ }
140
+ };
141
+ };
142
+
143
+ it.each([
144
+ ['Is String, Return String', createGetters('abc'), myId, 'abc'],
145
+ // This catches old parseInt errors
146
+ ['Is String, Return String (integer prefix)', createGetters('123-abc'), myId, '123-abc'],
147
+ // This catches old parseInt errors
148
+ ['Is String, Return String (integer postfix)', createGetters('abc-123'), myId, 'abc-123'],
149
+ ['Is 0, Return Null', createGetters(0), myId, null],
150
+ ['Is Number, Return Number', createGetters(123), myId, 123],
151
+ ['Is Missing (null), Return Null', createGetters(null), myId, null],
152
+ ['Is Missing (undefined), Return Null', createGetters(undefined), myId, null],
153
+ ])('test revision from a single resource - %s', (_, storeGetters, id, expected) => {
154
+ expect(getters.nextResourceVersion(createState(), storeGetters)(myType, id)).toBe(expected);
155
+ });
156
+
157
+ const createResource = (revision: Revision) => ({ metadata: { resourceVersion: revision } });
158
+
159
+ it.each([
160
+ ['Is String, Return String', createState('abc'), 'abc'],
161
+ ['Is String, Return String (integer prefix)', createState('123-abc'), '123-abc'],
162
+ ['Is String, Return String (integer postfix)', createState('abc-123'), 'abc-123'],
163
+ ['Is 0, Return Null (nothing in cache)', createState(0), null],
164
+ ['Is 0, Return Number (numbers in cache)', createState(0, [createResource(1), createResource(2), createResource(3)]), 3],
165
+ ['Is 0, Return Number (numbers and strings in cache)', createState(0, [createResource(1), createResource('abc-2'), createResource('3-abc')]), 1],
166
+ ['Is 0, Return Null (only strings in cache)', createState(0, [createResource('abc'), createResource('abc-2'), createResource('3-abc')]), null],
167
+ ['Is missing (undefined), Return Null ', createState(undefined), null],
168
+ ['Is missing (null), Return Null', createState(null), null],
169
+ ])('test revision from a collection - %s', (_, state, expected) => {
170
+ expect(getters.nextResourceVersion(state, {})(myType)).toBe(expected);
171
+ });
172
+ });
173
+ });
109
174
  });
@@ -58,6 +58,9 @@ export default {
58
58
  waiting = state.deferredRequests[key];
59
59
 
60
60
  if ( waiting ) {
61
+ // A matching request has already been made and is currently waiting to complete
62
+ // Avoid making another request, just wait for the original one to complete
63
+ // and return the result of the first call (see `waiting` being processed far below)
61
64
  const later = deferred();
62
65
 
63
66
  waiting.push(later);
@@ -454,7 +454,6 @@ class StevePaginationUtils extends NamespaceProjectFilters {
454
454
 
455
455
  // First check in our hardcoded list of supported filters
456
456
  if (
457
- process.env.NODE_ENV === 'dev' &&
458
457
  !!schema &&
459
458
  [
460
459
  StevePaginationUtils.VALID_FIELDS[''], // Global
@@ -500,16 +499,25 @@ class StevePaginationUtils extends NamespaceProjectFilters {
500
499
  // Check if the API supports filtering by this field
501
500
  this.validateField(validateFields, schema, field.field);
502
501
 
503
- const value = encodeURIComponent(field.value);
502
+ const encodedValue = encodeURIComponent(field.value);
504
503
 
505
504
  // = exact match (equals + exact)
506
505
  // ~ partial match (equals + !exact)
507
506
  // != not exact match (!equals + exact)
508
507
  // !~ not partial match (!equals + !exact)
509
508
  const operator = `${ field.equals ? '' : '!' }${ field.exact ? '=' : '~' }`;
510
- const quotedValue = StevePaginationUtils.VALID_FIELD_VALUE_REGEX.test(value) ? value : `"${ value }"`;
511
-
512
- return `${ this.convertArrayPath(field.field) }${ operator }${ quotedValue }`;
509
+ let safeValue;
510
+
511
+ if (StevePaginationUtils.VALID_FIELD_VALUE_REGEX.test(field.value)) {
512
+ // Does not contain any protected characters, send as is
513
+ safeValue = encodedValue;
514
+ } else {
515
+ // Contains protected characters, wrap in quotes to ensure backend doesn't fail
516
+ // - replace reserver `"`/`%22` with empty string - see https://github.com/rancher/dashboard/issues/14549 for improvement
517
+ safeValue = `"${ encodedValue.replaceAll('%22', '') }"`;
518
+ }
519
+
520
+ return `${ this.convertArrayPath(field.field) }${ operator }${ safeValue }`;
513
521
  }
514
522
 
515
523
  return field.value;
@@ -649,7 +657,7 @@ export const PAGINATION_SETTINGS_STORE_DEFAULTS: PaginationSettingsStore = {
649
657
  enabled: [
650
658
  NODE, EVENT,
651
659
  WORKLOAD_TYPES.CRON_JOB, WORKLOAD_TYPES.DAEMON_SET, WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.JOB, WORKLOAD_TYPES.STATEFUL_SET, POD,
652
- CATALOG.APP, CATALOG.CLUSTER_REPO, CATALOG.OPERATION,
660
+ CATALOG.APP, CATALOG.OPERATION,
653
661
  HPA, INGRESS, SERVICE,
654
662
  PV, CONFIG_MAP, STORAGE_CLASS, PVC, SECRET,
655
663
  WORKLOAD_TYPES.REPLICA_SET, WORKLOAD_TYPES.REPLICATION_CONTROLLER
@@ -663,8 +671,9 @@ export const PAGINATION_SETTINGS_STORE_DEFAULTS: PaginationSettingsStore = {
663
671
  enableAll: false,
664
672
  enableSome: {
665
673
  enabled: [
666
- { resource: CAPI.RANCHER_CLUSTER, context: ['home', 'side-bar'] },
667
- { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] },
674
+ // { resource: CAPI.RANCHER_CLUSTER, context: ['home', 'side-bar'] }, // Disabled due to https://github.com/rancher/dashboard/issues/14493
675
+ // { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] }, // Disabled due to https://github.com/rancher/dashboard/issues/14493
676
+ { resource: CATALOG.APP, context: ['branding'] },
668
677
  ],
669
678
  generic: false,
670
679
  }