@rancher/shell 1.2.0 → 2.0.0

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 (689) hide show
  1. package/assets/data/aws-regions.json +9 -0
  2. package/assets/images/vendor/openid.svg +18 -0
  3. package/assets/styles/app.scss +1 -2
  4. package/assets/styles/fonts/_icons.scss +3 -3
  5. package/assets/styles/global/_columns.scss +1 -1
  6. package/assets/styles/global/_labeled-input.scss +1 -0
  7. package/assets/styles/global/_layout.scss +99 -0
  8. package/assets/styles/themes/_csp.scss +2 -2
  9. package/assets/styles/themes/_dark.scss +8 -2
  10. package/assets/styles/themes/_light.scss +2 -1
  11. package/assets/styles/themes/_suse.scss +1 -1
  12. package/assets/styles/vendor/vue-select.scss +5 -0
  13. package/assets/translations/en-us.yaml +299 -63
  14. package/assets/translations/zh-hans.yaml +7 -31
  15. package/babel.config.js +8 -2
  16. package/chart/__tests__/S3.test.ts +9 -2
  17. package/chart/gatekeeper.vue +2 -11
  18. package/chart/istio.vue +1 -10
  19. package/chart/logging/index.vue +2 -11
  20. package/chart/monitoring/alerting/index.vue +7 -21
  21. package/chart/monitoring/grafana/index.vue +61 -2
  22. package/chart/monitoring/index.vue +52 -26
  23. package/chart/monitoring/prometheus/index.vue +39 -45
  24. package/chart/rancher-backup/S3.vue +11 -9
  25. package/chart/rancher-backup/index.vue +18 -15
  26. package/cloud-credential/__tests__/harvester.test.ts +18 -0
  27. package/cloud-credential/azure.vue +4 -17
  28. package/cloud-credential/generic.vue +18 -9
  29. package/cloud-credential/harvester.vue +11 -3
  30. package/components/AppModal.vue +167 -0
  31. package/components/AssignTo.vue +7 -4
  32. package/components/AsyncButton.vue +27 -5
  33. package/components/BackLink.vue +4 -4
  34. package/components/BannerGraphic.vue +1 -0
  35. package/components/BrandImage.vue +47 -1
  36. package/components/Carousel.vue +15 -8
  37. package/components/Certificates.vue +161 -0
  38. package/components/ClusterBadge.vue +12 -3
  39. package/components/ClusterIconMenu.vue +55 -12
  40. package/components/ClusterProviderIcon.vue +14 -3
  41. package/components/CodeMirror.vue +111 -17
  42. package/components/CommunityLinks.vue +12 -8
  43. package/components/CopyCode.vue +6 -2
  44. package/components/CopyToClipboard.vue +2 -1
  45. package/components/CopyToClipboardText.vue +14 -9
  46. package/components/CreateDriver.vue +81 -0
  47. package/components/CruResource.vue +52 -27
  48. package/components/DetailTop.vue +2 -2
  49. package/components/Dialog.vue +6 -5
  50. package/components/DisableAuthProviderModal.vue +14 -8
  51. package/components/DraggableZone.vue +2 -2
  52. package/components/EtcdInfoBanner.vue +5 -5
  53. package/components/ExplorerMembers.vue +3 -3
  54. package/components/ExplorerProjectsNamespaces.vue +31 -7
  55. package/components/FixedBanner.vue +48 -36
  56. package/components/GlobalRoleBindings.vue +26 -0
  57. package/components/IconOrSvg.vue +1 -1
  58. package/components/Import.vue +10 -6
  59. package/components/Inactivity.vue +1 -5
  60. package/components/KeyValueView.vue +14 -10
  61. package/components/Markdown.vue +16 -12
  62. package/components/MessageLink.vue +2 -2
  63. package/components/ModalWithCard.vue +5 -8
  64. package/components/MoveModal.vue +35 -33
  65. package/components/PodSecurityAdmission.vue +3 -3
  66. package/components/PromptChangePassword.vue +33 -33
  67. package/components/PromptModal.vue +11 -21
  68. package/components/PromptRemove.vue +11 -17
  69. package/components/PromptRestore.vue +18 -16
  70. package/components/Questions/__tests__/Boolean.test.ts +9 -19
  71. package/components/Questions/__tests__/Float.test.ts +9 -19
  72. package/components/Questions/__tests__/Int.test.ts +9 -19
  73. package/components/Questions/__tests__/String.test.ts +9 -19
  74. package/components/Questions/__tests__/Yaml.test.ts +9 -20
  75. package/components/Questions/__tests__/utils/questions-defaults.ts +20 -0
  76. package/components/Questions/index.vue +19 -3
  77. package/components/ResourceCancelModal.vue +34 -29
  78. package/components/ResourceDetail/Masthead.vue +48 -16
  79. package/components/ResourceDetail/index.vue +6 -4
  80. package/components/ResourceList/Masthead.vue +10 -9
  81. package/components/ResourceList/index.vue +65 -14
  82. package/components/ResourceTable.vue +87 -21
  83. package/components/ResourceYaml.vue +35 -5
  84. package/components/SelectIconGrid.vue +3 -3
  85. package/components/SideNav.vue +50 -94
  86. package/components/SingleClusterInfo.vue +4 -4
  87. package/components/SortableTable/THead.vue +33 -21
  88. package/components/SortableTable/filtering.js +9 -1
  89. package/components/SortableTable/grouping.js +8 -1
  90. package/components/SortableTable/index.vue +143 -44
  91. package/components/SortableTable/paging.js +36 -7
  92. package/components/SortableTable/selection.js +2 -1
  93. package/components/SortableTable/sorting.js +24 -7
  94. package/components/StatusTable.vue +5 -1
  95. package/components/Tabbed/index.vue +18 -1
  96. package/components/TableDataUserIcon.vue +47 -0
  97. package/components/TypeDescription.vue +1 -0
  98. package/components/Wizard.vue +1 -0
  99. package/components/YamlEditor.vue +1 -0
  100. package/components/__tests__/AppModal.test.ts +98 -0
  101. package/components/__tests__/AsyncButton.test.ts +1 -3
  102. package/components/__tests__/BackLink.test.ts +1 -1
  103. package/components/__tests__/ButtonGroup.test.ts +3 -6
  104. package/components/__tests__/Carousel.test.ts +43 -0
  105. package/components/__tests__/Certificates.test.ts +29 -0
  106. package/components/__tests__/CodeMirror.test.ts +87 -0
  107. package/components/__tests__/CopyCode.test.ts +5 -4
  108. package/components/__tests__/CruResource.test.ts +10 -9
  109. package/components/__tests__/EtcdInfoBanner.test.ts +37 -0
  110. package/components/__tests__/FixedBanner.test.ts +5 -20
  111. package/components/__tests__/NamespaceFilter.test.ts +9 -18
  112. package/components/__tests__/TabTitle.test.ts +129 -0
  113. package/components/auth/AzureWarning.vue +2 -2
  114. package/components/auth/RoleDetailEdit.vue +10 -0
  115. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  116. package/components/auth/login/oidc.vue +7 -1
  117. package/components/fleet/FleetBundles.vue +5 -11
  118. package/components/fleet/FleetClusters.vue +9 -9
  119. package/components/fleet/FleetIntro.vue +11 -17
  120. package/components/fleet/FleetNoWorkspaces.vue +2 -2
  121. package/components/fleet/FleetRepos.vue +63 -27
  122. package/components/fleet/FleetResources.vue +6 -1
  123. package/components/fleet/FleetStatus.vue +3 -3
  124. package/components/fleet/FleetSummary.vue +35 -30
  125. package/components/fleet/ForceDirectedTreeChart/index.vue +9 -3
  126. package/components/fleet/__tests__/FleetSummary.test.ts +316 -0
  127. package/components/form/ArrayList.vue +22 -18
  128. package/components/form/ArrayListSelect.vue +5 -0
  129. package/components/form/BannerSettings.vue +3 -0
  130. package/components/form/ClusterAppearance.vue +132 -0
  131. package/components/form/ColorInput.vue +1 -0
  132. package/components/form/Error.vue +3 -3
  133. package/components/form/FileSelector.vue +1 -0
  134. package/components/form/Footer.vue +2 -2
  135. package/components/form/GitPicker.vue +83 -38
  136. package/components/form/KeyValue.vue +69 -48
  137. package/components/form/LabeledSelect.vue +145 -41
  138. package/components/form/Labels.vue +3 -1
  139. package/components/form/NameNsDescription.vue +26 -9
  140. package/components/form/Password.vue +3 -1
  141. package/components/form/ResourceLabeledSelect.vue +187 -0
  142. package/components/form/ResourceTabs/index.vue +31 -15
  143. package/components/form/SecretSelector.vue +93 -18
  144. package/components/form/SelectOrCreateAuthSecret.vue +132 -59
  145. package/components/form/SimpleSecretSelector.vue +88 -28
  146. package/components/form/__tests__/BannerSettings.test.ts +53 -0
  147. package/components/form/__tests__/KeyValue.test.ts +120 -11
  148. package/components/form/__tests__/LabeledSelect.test.ts +0 -18
  149. package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +25 -15
  150. package/components/form/labeled-select-utils/labeled-select-pagination.ts +151 -0
  151. package/components/form/labeled-select-utils/labeled-select.utils.ts +122 -0
  152. package/components/formatter/AppSummaryGraph.vue +2 -2
  153. package/components/formatter/Checked.vue +11 -3
  154. package/components/formatter/CloudCredPublicData.vue +30 -0
  155. package/components/formatter/ClusterLink.vue +2 -2
  156. package/components/formatter/ClusterProvider.vue +1 -18
  157. package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
  158. package/components/formatter/FleetSummaryGraph.vue +25 -12
  159. package/components/formatter/ImagePercentageBar.vue +0 -4
  160. package/components/formatter/IngressTarget.vue +18 -7
  161. package/components/formatter/Link.vue +2 -2
  162. package/components/formatter/LinkDetail.vue +2 -2
  163. package/components/formatter/LinkDetailImage.vue +2 -2
  164. package/components/formatter/LinkName.vue +2 -2
  165. package/components/formatter/LiveDuration.vue +1 -1
  166. package/components/formatter/PercentageBar.vue +1 -1
  167. package/components/formatter/PrincipalGroupBindings.vue +2 -2
  168. package/components/formatter/SecretType.vue +2 -2
  169. package/components/formatter/VirtualServiceGateways.vue +2 -2
  170. package/components/formatter/WorkloadDetailEndpoints.vue +12 -22
  171. package/components/formatter/__tests__/Checked.test.ts +19 -0
  172. package/components/formatter/__tests__/LinkDetail.test.ts +5 -5
  173. package/components/formatter/__tests__/WorkloadDetailEndpoints.test.ts +81 -0
  174. package/components/nav/Group.vue +9 -7
  175. package/components/nav/Header.vue +84 -45
  176. package/components/nav/Jump.vue +19 -9
  177. package/components/nav/NamespaceFilter.vue +8 -1
  178. package/components/nav/TopLevelMenu.vue +391 -132
  179. package/components/nav/Type.vue +71 -106
  180. package/components/nav/WindowManager/ContainerLogs.vue +120 -19
  181. package/components/nav/WindowManager/ContainerShell.vue +6 -1
  182. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
  183. package/components/nav/WindowManager/index.vue +11 -10
  184. package/components/nav/__tests__/TopLevelMenu.test.ts +400 -6
  185. package/components/nav/__tests__/Type.test.ts +322 -97
  186. package/components/nuxt/nuxt-child.js +9 -78
  187. package/components/nuxt/nuxt-error.vue +1 -1
  188. package/components/nuxt/nuxt-link.client.js +13 -95
  189. package/{layouts → components/templates}/blank.vue +1 -1
  190. package/{layouts → components/templates}/default.vue +11 -101
  191. package/{layouts → components/templates}/error.vue +13 -26
  192. package/{layouts → components/templates}/home.vue +4 -1
  193. package/{layouts → components/templates}/plain.vue +4 -1
  194. package/{layouts → components/templates}/standalone.vue +1 -5
  195. package/{layouts → components/templates}/unauthenticated.vue +2 -3
  196. package/composables/useCompactInput.test.ts +36 -0
  197. package/composables/useCompactInput.ts +20 -0
  198. package/composables/useLabeledFormElement.test.ts +135 -0
  199. package/composables/useLabeledFormElement.ts +138 -0
  200. package/config/harvester-manager-types.js +2 -0
  201. package/config/home-links.js +2 -1
  202. package/config/labels-annotations.js +2 -1
  203. package/config/middleware.js +0 -6
  204. package/config/pagination-table-headers.js +57 -0
  205. package/config/pod-security-admission.ts +1 -1
  206. package/config/private-label.js +21 -1
  207. package/config/product/auth.js +1 -0
  208. package/config/product/explorer.js +166 -45
  209. package/config/product/fleet.js +6 -1
  210. package/config/product/legacy.js +2 -11
  211. package/config/product/manager.js +51 -25
  212. package/config/query-params.js +2 -0
  213. package/config/roles.ts +23 -0
  214. package/config/router/index.js +23 -0
  215. package/config/router/navigation-guards/attempt-first-login.js +73 -0
  216. package/config/router/navigation-guards/authentication.js +63 -0
  217. package/config/router/navigation-guards/index.js +15 -0
  218. package/config/router/navigation-guards/load-initial-settings.js +15 -0
  219. package/config/router/routes.js +487 -0
  220. package/config/settings.ts +31 -2
  221. package/config/store.js +8 -4
  222. package/config/system-namespaces.js +3 -0
  223. package/config/table-headers.js +66 -1
  224. package/config/types.js +35 -20
  225. package/config/uiplugins.js +10 -5
  226. package/core/plugin-helpers.js +4 -6
  227. package/core/plugin-routes.ts +56 -114
  228. package/core/plugin.ts +18 -11
  229. package/core/plugins-loader.js +7 -9
  230. package/core/plugins.js +289 -285
  231. package/core/types-provisioning.ts +7 -0
  232. package/creators/app/files/.eslintignore +0 -2
  233. package/creators/app/files/.gitlab-ci.yml +14 -0
  234. package/creators/app/files/.vscode/settings.json +0 -1
  235. package/creators/app/init +19 -0
  236. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +2 -6
  237. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +2 -6
  238. package/creators/pkg/init +32 -0
  239. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +77 -0
  240. package/detail/__tests__/service.test.ts +62 -0
  241. package/detail/catalog.cattle.io.app.vue +1 -1
  242. package/detail/cis.cattle.io.clusterscan.vue +14 -3
  243. package/detail/fleet.cattle.io.bundle.vue +1 -1
  244. package/detail/fleet.cattle.io.cluster.vue +11 -1
  245. package/detail/fleet.cattle.io.gitrepo.vue +15 -9
  246. package/detail/namespace.vue +2 -2
  247. package/detail/networking.k8s.io.ingress.vue +52 -19
  248. package/detail/node.vue +22 -3
  249. package/detail/provisioning.cattle.io.cluster.vue +27 -9
  250. package/detail/service.vue +1 -1
  251. package/detail/workload/index.vue +1 -0
  252. package/dialog/AddCustomBadgeDialog.vue +318 -161
  253. package/dialog/DeactivateDriverDialog.vue +118 -0
  254. package/dialog/RollbackWorkloadDialog.vue +2 -2
  255. package/dialog/RotateCertificatesDialog.vue +0 -21
  256. package/dialog/ScaleMachineDownDialog.vue +34 -17
  257. package/directives/clean-html.js +15 -0
  258. package/directives/clean-tooltip.js +32 -0
  259. package/directives/focus.js +41 -0
  260. package/directives/int-number.js +21 -0
  261. package/directives/positive-int-number.js +19 -0
  262. package/directives/trim-whitespace.js +19 -0
  263. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +3 -2
  264. package/edit/__tests__/kontainerDriver.test.ts +107 -0
  265. package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +12 -1
  266. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  267. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +2 -3
  268. package/edit/__tests__/nodeDriver.test.ts +107 -0
  269. package/edit/__tests__/service.test.ts +85 -0
  270. package/edit/__tests__/ui.cattle.io.navlink.test.ts +3 -1
  271. package/edit/auth/AuthProviderWarningBanners.vue +34 -0
  272. package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +19 -0
  273. package/edit/auth/__tests__/azuread.test.ts +241 -0
  274. package/edit/auth/__tests__/oidc.test.ts +137 -0
  275. package/edit/auth/azuread.vue +133 -31
  276. package/edit/auth/github.vue +5 -17
  277. package/edit/auth/googleoauth.vue +6 -23
  278. package/edit/auth/ldap/index.vue +5 -17
  279. package/edit/auth/oidc.vue +143 -42
  280. package/edit/auth/saml.vue +5 -14
  281. package/edit/catalog.cattle.io.clusterrepo.vue +177 -9
  282. package/edit/cis.cattle.io.clusterscan.vue +5 -2
  283. package/edit/cis.cattle.io.clusterscanbenchmark.vue +41 -9
  284. package/edit/cloudcredential.vue +28 -4
  285. package/edit/configmap.vue +10 -4
  286. package/edit/fleet.cattle.io.gitrepo.vue +3 -1
  287. package/edit/helm.cattle.io.projecthelmchart.vue +29 -19
  288. package/edit/kontainerDriver.vue +65 -0
  289. package/edit/logging-flow/Match.vue +10 -9
  290. package/edit/logging-flow/index.vue +4 -19
  291. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +232 -2
  292. package/edit/logging.banzaicloud.io.output/index.vue +43 -26
  293. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -3
  294. package/edit/management.cattle.io.project.vue +3 -53
  295. package/edit/management.cattle.io.setting.vue +52 -2
  296. package/edit/management.cattle.io.user.vue +2 -1
  297. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +10 -7
  298. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +21 -16
  299. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +1 -1
  300. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +2 -2
  301. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -1
  302. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +15 -3
  303. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +4 -1
  304. package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +2 -0
  305. package/edit/monitoring.coreos.com.prometheusrule/index.vue +2 -0
  306. package/edit/networking.k8s.io.ingress/Rules.vue +8 -3
  307. package/edit/networking.k8s.io.ingress/index.vue +64 -8
  308. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -0
  309. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +6 -2
  310. package/edit/networking.k8s.io.networkpolicy/__tests__/{PolicyRuleTarget.spec.ts → PolicyRuleTarget.test.ts} +46 -7
  311. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +1 -1
  312. package/edit/networking.k8s.io.networkpolicy/index.vue +2 -0
  313. package/edit/nodeDriver.vue +65 -0
  314. package/edit/persistentvolume/index.vue +2 -2
  315. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +33 -16
  316. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +276 -0
  317. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
  318. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +3 -0
  319. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +228 -0
  320. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  321. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
  322. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +77 -13
  323. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +391 -0
  324. package/edit/provisioning.cattle.io.cluster/import.vue +4 -4
  325. package/edit/provisioning.cattle.io.cluster/index.vue +126 -51
  326. package/edit/provisioning.cattle.io.cluster/rke2.vue +325 -791
  327. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
  328. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +217 -0
  329. package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +123 -129
  330. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +132 -0
  331. package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
  332. package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +1 -0
  333. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
  334. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +190 -0
  335. package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +3 -0
  336. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +148 -0
  337. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
  338. package/edit/resources.cattle.io.backup.vue +139 -124
  339. package/edit/resources.cattle.io.restore.vue +146 -126
  340. package/edit/service.vue +13 -0
  341. package/edit/serviceaccount.vue +46 -4
  342. package/edit/token.vue +1 -0
  343. package/edit/workload/Upgrading.vue +3 -2
  344. package/edit/workload/__tests__/Job.test.ts +1 -3
  345. package/edit/workload/__tests__/Upgrading.test.ts +2 -2
  346. package/edit/workload/index.vue +2 -1
  347. package/edit/workload/mixins/workload.js +35 -2
  348. package/edit/workload/storage/emptyDir.vue +2 -2
  349. package/initialize/App.vue +75 -0
  350. package/initialize/app-extended.js +128 -0
  351. package/initialize/entry-helpers.js +549 -0
  352. package/initialize/entry.js +32 -0
  353. package/initialize/install-components.js +23 -0
  354. package/initialize/install-directives.js +59 -0
  355. package/initialize/install-plugins.js +123 -0
  356. package/list/__tests__/workload.test.ts +1 -1
  357. package/list/catalog.cattle.io.app.vue +1 -0
  358. package/list/cis.cattle.io.clusterscan.vue +16 -10
  359. package/list/group.principal.vue +2 -2
  360. package/list/management.cattle.io.feature.vue +12 -14
  361. package/list/management.cattle.io.setting.vue +1 -0
  362. package/list/management.cattle.io.user.vue +13 -4
  363. package/list/networking.k8s.io.ingress.vue +36 -0
  364. package/list/node.vue +212 -73
  365. package/list/provisioning.cattle.io.cluster.vue +17 -4
  366. package/list/ui.cattle.io.navlink.vue +2 -2
  367. package/list/workload.vue +22 -0
  368. package/machine-config/__tests__/vmwarevsphere-pool-config-merge.test.ts +30 -0
  369. package/machine-config/__tests__/vmwarevsphere.test.ts +1 -3
  370. package/machine-config/amazonec2.vue +1 -1
  371. package/machine-config/azure.vue +2 -1
  372. package/machine-config/generic.vue +11 -15
  373. package/machine-config/vmwarevsphere-pool-config-merge.ts +25 -0
  374. package/machine-config/vmwarevsphere.vue +31 -27
  375. package/middleware/authenticated.js +23 -380
  376. package/mixins/__tests__/chart.test.ts +48 -6
  377. package/mixins/__tests__/create-edit-view.test.ts +2 -3
  378. package/mixins/auth-config.js +5 -9
  379. package/mixins/brand.js +102 -96
  380. package/mixins/chart.js +27 -13
  381. package/mixins/create-edit-view/index.js +2 -2
  382. package/mixins/fetch.client.js +42 -48
  383. package/mixins/labeled-form-element.ts +27 -2
  384. package/mixins/page-actions.js +7 -5
  385. package/mixins/resource-fetch-api-pagination.js +304 -0
  386. package/mixins/resource-fetch-namespaced.js +1 -1
  387. package/mixins/resource-fetch.js +46 -5
  388. package/models/__tests__/cluster.test.ts +44 -0
  389. package/models/__tests__/fleet.cattle.io.cluster.test.ts +36 -0
  390. package/models/__tests__/management.cattle.io.cluster.test.ts +23 -0
  391. package/models/__tests__/management.cattle.io.node.ts +85 -0
  392. package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
  393. package/models/__tests__/namespace.test.ts +49 -9
  394. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +241 -0
  395. package/models/__tests__/schema.tests.ts +24 -0
  396. package/models/__tests__/secret.test.ts +37 -0
  397. package/models/__tests__/steve-schema.test.ts +73 -0
  398. package/models/__tests__/storage.k8s.io.storageclass.test.ts +22 -0
  399. package/models/__tests__/workload.test.ts +91 -0
  400. package/models/catalog.cattle.io.app.js +8 -0
  401. package/models/catalog.cattle.io.clusterrepo.js +9 -1
  402. package/models/catalog.cattle.io.uiplugin.js +7 -8
  403. package/models/cis.cattle.io.clusterscan.js +29 -8
  404. package/models/cloudcredential.js +9 -1
  405. package/models/cluster/node.js +8 -4
  406. package/models/cluster/schema.js +6 -0
  407. package/models/cluster.js +33 -0
  408. package/models/cluster.x-k8s.io.machine.js +1 -1
  409. package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
  410. package/models/driver.js +62 -0
  411. package/models/fleet.cattle.io.cluster.js +27 -11
  412. package/models/fleet.cattle.io.gitrepo.js +66 -13
  413. package/models/helm.cattle.io.projecthelmchart.js +1 -1
  414. package/models/kontainerdriver.js +68 -0
  415. package/models/management/schema.js +6 -0
  416. package/models/management.cattle.io.authconfig.js +3 -2
  417. package/models/management.cattle.io.cluster.js +16 -7
  418. package/models/management.cattle.io.globalrole.js +2 -0
  419. package/models/management.cattle.io.kontainerdriver.js +1 -0
  420. package/models/management.cattle.io.node.js +18 -14
  421. package/models/management.cattle.io.nodepool.js +17 -0
  422. package/models/management.cattle.io.project.js +0 -36
  423. package/models/management.cattle.io.setting.js +11 -7
  424. package/models/management.cattle.io.user.js +2 -2
  425. package/models/monitoring.coreos.com.receiver.js +3 -1
  426. package/models/monitoring.coreos.com.route.js +1 -1
  427. package/models/namespace.js +1 -1
  428. package/models/networking.k8s.io.ingress.js +2 -1
  429. package/models/nodedriver.js +68 -0
  430. package/models/pod.js +20 -0
  431. package/models/provisioning.cattle.io.cluster.js +125 -10
  432. package/models/schema.js +28 -7
  433. package/models/secret.js +126 -18
  434. package/models/service.js +2 -0
  435. package/models/steve-schema.ts +254 -0
  436. package/models/storage.k8s.io.storageclass.js +1 -1
  437. package/models/workload.js +17 -0
  438. package/models/workload.service.js +18 -0
  439. package/package.json +17 -14
  440. package/pages/about.vue +12 -6
  441. package/pages/account/create-key.vue +0 -1
  442. package/pages/account/index.vue +7 -3
  443. package/pages/auth/login.vue +106 -103
  444. package/pages/auth/logout.vue +2 -4
  445. package/pages/auth/setup.vue +92 -66
  446. package/pages/auth/verify.vue +30 -24
  447. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +2 -17
  448. package/pages/c/_cluster/apps/charts/chart.vue +54 -9
  449. package/pages/c/_cluster/apps/charts/index.vue +99 -69
  450. package/pages/c/_cluster/apps/charts/install.helpers.js +2 -13
  451. package/pages/c/_cluster/apps/charts/install.vue +9 -9
  452. package/pages/c/_cluster/auth/config/_id.vue +0 -6
  453. package/pages/c/_cluster/auth/config/index.vue +15 -9
  454. package/pages/c/_cluster/auth/roles/index.vue +8 -10
  455. package/pages/c/_cluster/ecm/index.vue +0 -2
  456. package/pages/c/_cluster/explorer/ConfigBadge.vue +13 -8
  457. package/pages/c/_cluster/explorer/EventsTable.vue +18 -0
  458. package/pages/c/_cluster/explorer/__tests__/index.test.ts +181 -0
  459. package/pages/c/_cluster/explorer/index.vue +253 -91
  460. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +69 -0
  461. package/pages/c/_cluster/explorer/tools/index.vue +10 -6
  462. package/pages/c/_cluster/fleet/index.vue +89 -94
  463. package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +89 -0
  464. package/pages/c/_cluster/longhorn/index.vue +52 -17
  465. package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -25
  466. package/pages/c/_cluster/manager/drivers/kontainerDriver/_id.vue +12 -0
  467. package/pages/c/_cluster/manager/drivers/kontainerDriver/create.vue +15 -0
  468. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +94 -0
  469. package/pages/c/_cluster/manager/drivers/nodeDriver/_id.vue +12 -0
  470. package/pages/c/_cluster/manager/drivers/nodeDriver/create.vue +15 -0
  471. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +63 -0
  472. package/pages/c/_cluster/manager/jwt.authentication/index.vue +235 -0
  473. package/pages/c/_cluster/manager/pages/_page.vue +4 -5
  474. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +4 -0
  475. package/pages/c/_cluster/monitoring/route-receiver/index.vue +2 -2
  476. package/pages/c/_cluster/neuvector/index.vue +1 -0
  477. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
  478. package/pages/c/_cluster/settings/banners.vue +86 -10
  479. package/pages/c/_cluster/settings/brand.vue +261 -38
  480. package/pages/c/_cluster/settings/index.vue +4 -6
  481. package/pages/c/_cluster/settings/links.vue +3 -2
  482. package/pages/c/_cluster/settings/performance.vue +71 -3
  483. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +5 -2
  484. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +12 -8
  485. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +9 -6
  486. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
  487. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +11 -5
  488. package/pages/c/_cluster/uiplugins/InstallDialog.vue +53 -18
  489. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +36 -301
  490. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +14 -6
  491. package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +52 -106
  492. package/pages/c/_cluster/uiplugins/index.vue +38 -54
  493. package/pages/diagnostic.vue +2 -2
  494. package/pages/fail-whale.vue +103 -42
  495. package/pages/home.vue +81 -24
  496. package/pages/prefs.vue +8 -4
  497. package/pages/support/index.vue +14 -10
  498. package/pkg/auto-import.js +1 -1
  499. package/plugins/axios.js +0 -36
  500. package/plugins/back-button.js +3 -5
  501. package/plugins/clean-html-directive.js +5 -30
  502. package/plugins/clean-html.js +53 -0
  503. package/plugins/clean-tooltip-directive.js +6 -31
  504. package/plugins/codemirror-loader.js +1 -1
  505. package/plugins/codemirror.js +41 -9
  506. package/plugins/dashboard-store/__tests__/mutations.test.ts +389 -0
  507. package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
  508. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
  509. package/plugins/dashboard-store/actions.js +132 -25
  510. package/plugins/dashboard-store/classify.js +1 -18
  511. package/plugins/dashboard-store/getters.js +154 -44
  512. package/plugins/dashboard-store/index.js +0 -111
  513. package/plugins/dashboard-store/mutations.js +150 -52
  514. package/plugins/dashboard-store/resource-class.js +77 -127
  515. package/plugins/directives.js +6 -39
  516. package/plugins/ember-cookie.js +13 -0
  517. package/plugins/global-formatters.js +26 -5
  518. package/plugins/i18n.js +89 -55
  519. package/plugins/int-number.js +6 -20
  520. package/plugins/plugin.js +3 -3
  521. package/plugins/positive-int-number.js +6 -17
  522. package/plugins/steve/__tests__/{getters.spec.ts → getters.test.ts} +81 -10
  523. package/plugins/steve/__tests__/mutations.test.ts +49 -0
  524. package/plugins/steve/__tests__/resource-utils.test.ts +159 -0
  525. package/plugins/steve/__tests__/steve-class.test.ts +59 -0
  526. package/plugins/steve/__tests__/subscribe.spec.ts +4 -1
  527. package/plugins/steve/__tests__/utils/mutation.test.helpers.ts +105 -0
  528. package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
  529. package/plugins/steve/accept-or-reject-socket-message.ts +103 -0
  530. package/plugins/steve/actions.js +3 -38
  531. package/plugins/steve/getters.js +164 -61
  532. package/plugins/steve/hybrid-class.js +5 -1
  533. package/plugins/steve/mutations.js +24 -3
  534. package/plugins/steve/norman-class.js +142 -2
  535. package/{utils → plugins/steve}/projectAndNamespaceFiltering.utils.ts +28 -10
  536. package/plugins/steve/resource-utils.ts +38 -0
  537. package/plugins/steve/schema.d.ts +22 -0
  538. package/plugins/steve/steve-class.js +22 -0
  539. package/plugins/steve/steve-pagination-utils.ts +368 -0
  540. package/plugins/steve/subscribe.js +17 -76
  541. package/plugins/trim-whitespace.js +6 -34
  542. package/plugins/vue-js-modal.js +1 -1
  543. package/public/index.html +1 -0
  544. package/rancher-components/Form/LabeledInput/LabeledInput.vue +13 -8
  545. package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
  546. package/rancher-components/components/Banner/Banner.test.ts +1 -5
  547. package/rancher-components/components/Banner/Banner.vue +2 -2
  548. package/rancher-components/components/Card/Card.vue +4 -4
  549. package/rancher-components/components/Form/Checkbox/Checkbox.vue +4 -3
  550. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +18 -1
  551. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +57 -24
  552. package/rancher-components/components/Form/Radio/RadioButton.test.ts +1 -3
  553. package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
  554. package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
  555. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
  556. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  557. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
  558. package/rancher-components/components/StringList/StringList.test.ts +270 -0
  559. package/rancher-components/components/StringList/StringList.vue +65 -26
  560. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +69 -0
  561. package/scripts/clean +1 -1
  562. package/scripts/extension/bundle +19 -7
  563. package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +11 -0
  564. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -0
  565. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  566. package/scripts/extension/helm/package/Dockerfile +1 -1
  567. package/scripts/extension/helm/scripts/package +11 -3
  568. package/scripts/extension/helm/scripts/patch +27 -0
  569. package/scripts/extension/parse-tag-name +4 -4
  570. package/scripts/extension/publish +25 -14
  571. package/scripts/publish-shell.sh +11 -1
  572. package/scripts/serve-pkgs +0 -2
  573. package/scripts/test-plugins-build.sh +87 -11
  574. package/scripts/vue-migrate.js +683 -0
  575. package/server/har-file.js +183 -0
  576. package/store/__tests__/catalog.test.ts +224 -0
  577. package/store/__tests__/type-map.test.ts +1122 -0
  578. package/store/auth.js +23 -4
  579. package/store/aws.js +53 -6
  580. package/store/catalog.js +22 -6
  581. package/store/cru-resource.ts +26 -0
  582. package/store/customisation.js +35 -0
  583. package/store/features.js +7 -4
  584. package/store/i18n.js +11 -0
  585. package/store/index.js +139 -48
  586. package/store/plugins.js +8 -4
  587. package/store/prefs.js +33 -38
  588. package/store/type-map.js +288 -213
  589. package/store/type-map.utils.ts +226 -0
  590. package/tsconfig.json +34 -9
  591. package/tsconfig.paths.json +21 -0
  592. package/types/components/labeledSelect.ts +50 -0
  593. package/types/resources/settings.d.ts +32 -0
  594. package/types/{userPreferences.d.ts → resources/userPreferences.d.ts} +0 -1
  595. package/types/shell/index.d.ts +1042 -767
  596. package/types/store/dashboard-store.types.ts +42 -0
  597. package/types/store/pagination.types.ts +457 -0
  598. package/types/store/type-map.ts +30 -0
  599. package/types/store/vuex.d.ts +9 -0
  600. package/types/vue-shim.d.ts +51 -0
  601. package/utils/__tests__/cluster.test.ts +20 -18
  602. package/utils/__tests__/create-yaml.test.ts +359 -2
  603. package/utils/__tests__/kontainer.test.ts +92 -0
  604. package/utils/__tests__/pod-security-admission.test.ts +1 -1
  605. package/utils/alertmanagerconfig.js +19 -0
  606. package/utils/array.ts +40 -1
  607. package/utils/async.ts +2 -0
  608. package/utils/auth.js +152 -4
  609. package/utils/axios.js +2 -21
  610. package/utils/azure.js +24 -0
  611. package/utils/banners.js +103 -0
  612. package/utils/clipboard.js +5 -0
  613. package/utils/cluster.js +1 -1
  614. package/utils/config.js +4 -0
  615. package/utils/create-yaml.js +59 -28
  616. package/utils/custom-validators.js +0 -2
  617. package/utils/error.js +41 -1
  618. package/utils/formatter.js +5 -3
  619. package/utils/git.ts +1 -1
  620. package/utils/install-redirect.js +1 -1
  621. package/utils/kontainer.ts +186 -0
  622. package/utils/object.js +24 -0
  623. package/utils/pagination-utils.ts +154 -0
  624. package/utils/pod-security-admission.ts +1 -1
  625. package/utils/router.js +86 -0
  626. package/utils/settings.ts +46 -0
  627. package/utils/time.js +2 -1
  628. package/utils/unit-tests/ChildRenderingRouterLinkStub.ts +36 -0
  629. package/utils/url.ts +1 -1
  630. package/utils/validators/formRules/__tests__/index.test.ts +70 -4
  631. package/utils/validators/formRules/index.ts +15 -9
  632. package/utils/validators/index.js +1 -0
  633. package/utils/validators/setting.js +6 -10
  634. package/vue.config.js +377 -401
  635. package/.DS_Store +0 -0
  636. package/assets/images/providers/aks-black.svg +0 -28
  637. package/assets/images/providers/aks.svg +0 -31
  638. package/assets/styles/vendor/vue-js-modal.scss +0 -16
  639. package/components/ChartPsp.vue +0 -76
  640. package/components/EventsTable.vue +0 -67
  641. package/components/TabbedLinks/index.vue +0 -94
  642. package/components/__tests__/ChartPsp.test.ts +0 -75
  643. package/components/formatter/__tests__/ClusterProvider.test.ts +0 -28
  644. package/components/nuxt/nuxt-link.server.js +0 -16
  645. package/components/nuxt/nuxt.js +0 -101
  646. package/config/router.js +0 -408
  647. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -237
  648. package/initialize/App.js +0 -198
  649. package/initialize/client.js +0 -875
  650. package/initialize/index.js +0 -364
  651. package/initialize/layouts.ts +0 -26
  652. package/middleware/i18n.js +0 -10
  653. package/middleware/unauthenticated.js +0 -22
  654. package/mixins/fetch.server.js +0 -73
  655. package/pages/c/_cluster/apps/index.vue +0 -17
  656. package/pages/c/_cluster/auth/index.vue +0 -19
  657. package/pages/c/_cluster/index.vue +0 -17
  658. package/pages/c/_cluster/legacy/index.vue +0 -22
  659. package/pages/c/_cluster/manager/index.vue +0 -22
  660. package/pages/c/_cluster/mcapps/index.vue +0 -21
  661. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +0 -232
  662. package/pages/c/index.vue +0 -9
  663. package/pages/rio/mesh.vue +0 -508
  664. package/plugins/dashboard-store/__tests__/mutations.spec.ts +0 -406
  665. package/plugins/dashboard-store/rehydrate-all.js +0 -44
  666. package/plugins/portal-vue.js +0 -4
  667. package/plugins/portal.js +0 -4
  668. package/plugins/resize.js +0 -5
  669. package/plugins/shortkey.js +0 -4
  670. package/plugins/tooltip.js +0 -4
  671. package/plugins/transitions.js +0 -4
  672. package/plugins/v-select.js +0 -4
  673. package/plugins/vue-clipboard2.js +0 -4
  674. package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
  675. package/tsconfig.default.json +0 -46
  676. package/utils/group.js +0 -70
  677. package/utils/nuxt.js +0 -659
  678. package/utils/router.scrollBehavior.js +0 -80
  679. /package/components/__tests__/{Collapse.spec.ts → Collapse.test.ts} +0 -0
  680. /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
  681. /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
  682. /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
  683. /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
  684. /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
  685. /package/models/__tests__/{node.ts → node.test.ts} +0 -0
  686. /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
  687. /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
  688. /package/plugins/steve/__tests__/{header-warnings.spec.ts → header-warnings.test.ts} +0 -0
  689. /package/types/{pod-security-admission.ts → resources/pod-security-admission.ts} +0 -0
package/store/type-map.js CHANGED
@@ -37,6 +37,7 @@
37
37
  // ifHaveType, -- Show this product only if the given type exists in the store [inStore], This can also be specified as an object { type: TYPE, store: 'management' } if the type isn't in the current [inStore]
38
38
  // ifHaveVerb, -- In combination with ifHaveTYpe, show it only if the type also has this collectionMethod
39
39
  // inStore, -- Which store to look at for if* above and the left-nav, defaults to "cluster"
40
+ // rootProduct, -- Optional root (parent) product - if set, used to optimize navigation when product changes stays within root product
40
41
  // inExplorer, -- Determines if the product is to be scoped to the explorer
41
42
  // public, -- If true, show to all users. If false, only show when the Developer Tools pref is on (default true)
42
43
  // category, -- Group to show the product in for the nav hamburger menu
@@ -133,7 +134,7 @@ import {
133
134
  } from '@shell/config/types';
134
135
  import { VIEW_IN_API, EXPANDED_GROUPS, FAVORITE_TYPES } from '@shell/store/prefs';
135
136
  import {
136
- addObject, findBy, insertAt, isArray, removeObject, filterBy
137
+ addObject, findBy, isArray, removeObject, filterBy
137
138
  } from '@shell/utils/array';
138
139
  import { clone, get } from '@shell/utils/object';
139
140
  import {
@@ -150,15 +151,54 @@ import { sortBy } from '@shell/utils/sort';
150
151
 
151
152
  import { haveV2Monitoring } from '@shell/utils/monitoring';
152
153
  import { NEU_VECTOR_NAMESPACE } from '@shell/config/product/neuvector';
154
+ import { createHeaders, rowValueGetter } from '@shell/store/type-map.utils';
153
155
 
154
156
  export const NAMESPACED = 'namespaced';
155
157
  export const CLUSTER_LEVEL = 'cluster';
156
158
  export const BOTH = 'both';
157
159
 
158
- export const ALL = 'all';
159
- export const BASIC = 'basic';
160
- export const FAVORITE = 'favorite';
161
- export const USED = 'used';
160
+ export const TYPE_MODES = {
161
+ /**
162
+ * allTypes usage: All resource types
163
+ *
164
+ * getTree usage: Remove ignored schemas, resources not applicable to ns, etc
165
+ */
166
+ ALL: 'all',
167
+ /**
168
+ * Represents resource types that should be shown at the top of the side nav.
169
+ *
170
+ * For example all fixed resource types above `More Resources` in the cluster explorer
171
+ *
172
+ * These will always be shown in the side nav
173
+ *
174
+ * allTypes usage: Resources that are in a group
175
+ *
176
+ * getTree usage: Remove ignored schemas, resources not applicable to ns, etc
177
+ */
178
+ BASIC: 'basic',
179
+ /**
180
+ * Represents any type of resource type that has been favourited
181
+ *
182
+ * These will always be shown in the side nav.
183
+ *
184
+ * allTypes usage: Resource types that have been favorited
185
+ *
186
+ * getTree usage: Remove ignored schemas, resources not applicable to ns, etc
187
+ */
188
+ FAVORITE: 'favorite',
189
+ /**
190
+ * Represents no virtual or spoofed types that have a count.
191
+ *
192
+ * For example the `More Resource` in the cluster explorer
193
+ *
194
+ * These will be shown in the side nav if there are resources in the ns filter OR the resource is not namespaces
195
+ *
196
+ * allTypes usage: All resource types that are not virtual or spoofed
197
+ *
198
+ * getTree usage: Remove types with no counts. Remove ignored schemas, resources not applicable to ns, etc
199
+ */
200
+ USED: 'used',
201
+ };
162
202
 
163
203
  export const ROOT = 'root';
164
204
 
@@ -168,8 +208,6 @@ export const SPOOFED_API_PREFIX = '__[[spoofedapi]]__';
168
208
  const instanceMethods = {};
169
209
  const graphConfigMap = {};
170
210
 
171
- const FIELD_REGEX = /^\$\.metadata\.fields\[([0-9]*)\]/;
172
-
173
211
  export const IF_HAVE = {
174
212
  V2_MONITORING: 'v2-monitoring',
175
213
  PROJECT: 'project',
@@ -200,9 +238,14 @@ export function DSL(store, product, module = 'type-map') {
200
238
  ...inOpt
201
239
  };
202
240
 
241
+ // Convert strings to regex's - we do this once here for efficiency
203
242
  for ( const k of ['ifHaveGroup', 'ifHaveType'] ) {
204
243
  if ( opt[k] ) {
205
- opt[k] = regexToString(ensureRegex(opt[k]));
244
+ if (Array.isArray(opt[k])) {
245
+ opt[k] = opt[k].map((r) => regexToString(ensureRegex(r)));
246
+ } else {
247
+ opt[k] = regexToString(ensureRegex(opt[k]));
248
+ }
206
249
  }
207
250
  }
208
251
 
@@ -225,7 +268,7 @@ export function DSL(store, product, module = 'type-map') {
225
268
  store.commit(`${ module }/groupBy`, { type, field });
226
269
  },
227
270
 
228
- headers(type, headers) {
271
+ headers(type, headers, paginationHeaders = []) {
229
272
  headers.forEach((header) => {
230
273
  // If on the client, then use the value getter if there is one
231
274
  if (header.getValue) {
@@ -238,6 +281,7 @@ export function DSL(store, product, module = 'type-map') {
238
281
  });
239
282
 
240
283
  store.commit(`${ module }/headers`, { type, headers });
284
+ store.commit(`${ module }/paginationHeaders`, { type, paginationHeaders });
241
285
  },
242
286
 
243
287
  hideBulkActions(type, field) {
@@ -367,6 +411,7 @@ export const state = function() {
367
411
  typeOptions: [],
368
412
  groupBy: {},
369
413
  headers: {},
414
+ paginationHeaders: {},
370
415
  hideBulkActions: {},
371
416
  schemaGeneration: 1,
372
417
  cache: {
@@ -395,6 +440,7 @@ export const getters = {
395
440
  labelFor(state, getters, rootState, rootGetters) {
396
441
  return (schema, count = 1, language = null) => {
397
442
  return _applyMapping(schema, state.typeMappings, 'id', false, () => {
443
+ // i18n-uses typeLabel.*
398
444
  const key = `typeLabel."${ schema.id.toLowerCase() }"`;
399
445
 
400
446
  if ( rootGetters['i18n/exists'](key, language) ) {
@@ -462,22 +508,26 @@ export const getters = {
462
508
  };
463
509
  },
464
510
 
465
- optionsFor(state) {
511
+ optionsFor(state, getters, rootState, rootGetters) {
466
512
  const def = {
467
- isCreatable: true,
468
- isEditable: true,
469
- isRemovable: true,
470
- showState: true,
471
- showAge: true,
472
- canYaml: true,
473
- namespaced: null,
474
- listGroups: [],
475
- depaginate: false,
476
- customRoute: undefined,
477
- resourceEditMasthead: true,
513
+ isCreatable: true,
514
+ isEditable: true,
515
+ isRemovable: true,
516
+ showState: true,
517
+ showAge: true,
518
+ canYaml: true,
519
+ namespaced: null,
520
+ listGroups: [],
521
+ listGroupsWillOverride: false,
522
+ listMandatorySort: null,
523
+ depaginate: false,
524
+ customRoute: undefined,
525
+ resourceEditMasthead: true,
478
526
  };
479
527
 
480
- return (schemaOrType) => {
528
+ return (schemaOrType, pagination) => {
529
+ // Note - This can run a LOT so needs to be performant
530
+
481
531
  if (!schemaOrType) {
482
532
  return {};
483
533
  }
@@ -491,7 +541,20 @@ export const getters = {
491
541
 
492
542
  const opts = Object.assign({}, def, found || {});
493
543
 
494
- return opts;
544
+ // As this runs a lot, avoid anything we don't strictly need (like going out to another store)
545
+ if (!pagination) {
546
+ return opts;
547
+ }
548
+
549
+ const storeOptionsFor = schemaOrType?.$ctx?.getters?.['optionsFor'];
550
+ const storeOpts = storeOptionsFor ? storeOptionsFor({ getters, state }, {
551
+ schema: schemaOrType, pagination, opts
552
+ }) : {};
553
+
554
+ return {
555
+ ...opts,
556
+ ...storeOpts,
557
+ };
495
558
  };
496
559
  },
497
560
 
@@ -534,17 +597,16 @@ export const getters = {
534
597
  },
535
598
 
536
599
  getTree(state, getters, rootState, rootGetters) {
537
- return (productId, mode, allTypes, clusterId, namespaceMode, namespaces, currentType, search) => {
600
+ // Name the function so it's easily identifiable when performance tracing
601
+ return function getTree(productId, mode, allTypes, clusterId, namespaceMode, currentType, search) {
538
602
  // getTree has four modes:
539
- // - `basic` matches data types that should always be shown even if there
540
- // are 0 of them.
541
- // - `used` matches the data types where there are more than 0 of them
542
- // in the current set of namespaces.
603
+ // - `basic` matches data types that should always be shown (even if there are 0 of them).
604
+ // - `used` matches the data types where there are more than 0 of them in the current set of namespaces.
543
605
  // - `all` matches all types.
544
606
  // - `favorite` matches starred types.
545
607
  // namespaceMode: 'namespaced', 'cluster', or 'both'
546
608
  // namespaces: null means all, otherwise it will be an array of specific namespaces to include
547
- const isBasic = mode === BASIC;
609
+ const isBasic = mode === TYPE_MODES.BASIC;
548
610
 
549
611
  let searchRegex;
550
612
 
@@ -577,7 +639,8 @@ export const getters = {
577
639
  continue;
578
640
  }
579
641
 
580
- const count = _matchingCounts(typeObj, namespaces);
642
+ const inStore = rootGetters.currentStore(typeObj.name);
643
+ const count = rootGetters[`${ inStore }/count`](typeObj);
581
644
  const groupForBasicType = getters.groupForBasicType(productId, typeObj.name);
582
645
 
583
646
  if ( typeObj.id === currentType ) {
@@ -585,15 +648,15 @@ export const getters = {
585
648
  } else if ( isBasic && !groupForBasicType ) {
586
649
  // If we want the basic tree only return basic types;
587
650
  continue;
588
- } else if ( mode === USED && count <= 0 ) {
651
+ } else if ( mode === TYPE_MODES.USED && count <= 0 ) {
589
652
  // If there's none of this type, ignore this entry when viewing only in-use types
590
- // Note: count is sometimes null, which is <= 0.
653
+ // Note: count is sometimes null, in js `null <= 0` is `true`.
591
654
  continue;
592
655
  }
593
656
 
594
657
  const label = typeObj.labelKey ? rootGetters['i18n/t'](typeObj.labelKey) || typeObj.label : typeObj.label;
595
658
 
596
- const labelDisplay = highlightLabel(label, typeObj.count, typeObj.schema);
659
+ const labelDisplay = highlightLabel(label, count, typeObj.schema);
597
660
 
598
661
  if ( !labelDisplay ) {
599
662
  // Search happens in highlight and returns null if not found
@@ -604,10 +667,10 @@ export const getters = {
604
667
 
605
668
  if ( isBasic ) {
606
669
  group = _ensureGroup(root, groupForBasicType, true);
607
- } else if ( mode === FAVORITE ) {
670
+ } else if ( mode === TYPE_MODES.FAVORITE ) {
608
671
  group = _ensureGroup(root, 'starred');
609
672
  group.weight = 1000;
610
- } else if ( mode === USED ) {
673
+ } else if ( mode === TYPE_MODES.USED ) {
611
674
  group = _ensureGroup(root, `inUse::${ getters.groupLabelFor(typeObj.schema) }`);
612
675
  } else {
613
676
  group = _ensureGroup(root, typeObj.schema || typeObj.group || ROOT);
@@ -639,14 +702,14 @@ export const getters = {
639
702
  group.children.push({
640
703
  label,
641
704
  labelDisplay,
642
- mode: typeObj.mode,
643
- count,
644
- exact: typeObj.exact || false,
705
+ mode: typeObj.mode,
706
+ exact: typeObj.exact || false,
707
+ 'exact-path': typeObj['exact-path'] || false,
645
708
  namespaced,
646
709
  route,
647
- name: typeObj.name,
648
- weight: typeObj.weight || getters.typeWeightFor(typeObj.schema?.id || label, isBasic),
649
- overview: !!typeObj.overview,
710
+ name: typeObj.name,
711
+ weight: typeObj.weight || getters.typeWeightFor(typeObj.schema?.id || label, isBasic),
712
+ overview: !!typeObj.overview,
650
713
  });
651
714
  }
652
715
 
@@ -670,6 +733,7 @@ export const getters = {
670
733
 
671
734
  // Translate if an entry exists
672
735
  let label = name;
736
+ // i18n-uses nav.group.*
673
737
  const key = `nav.group."${ name }"`;
674
738
 
675
739
  if ( rootGetters['i18n/exists'](key) ) {
@@ -810,55 +874,93 @@ export const getters = {
810
874
  });
811
875
  },
812
876
 
877
+ /**
878
+ * Given many things, create a list of menu items per schema given the mode
879
+ */
813
880
  allTypes(state, getters, rootState, rootGetters) {
814
- return (product, mode = ALL) => {
815
- const module = findBy(state.products, 'name', product)?.inStore;
881
+ // Name the function so it's easily identifiable when performance tracing
882
+ return function allTypes(product, modes = [TYPE_MODES.ALL]) {
883
+ const module = state.products.find((p) => p.name === product)?.inStore;
816
884
  const schemas = rootGetters[`${ module }/all`](SCHEMA);
885
+ const isLocal = !rootGetters.currentCluster?.isLocal;
886
+ const isRancher = rootGetters.isRancher;
817
887
  const counts = rootGetters[`${ module }/all`](COUNT)?.[0]?.counts || {};
818
- const isDev = rootGetters['prefs/get'](VIEW_IN_API);
819
- const isBasic = mode === BASIC;
820
888
 
821
889
  const out = {};
822
890
 
891
+ // For performance reasons this must be super quick to iterate over.
892
+ // For each schema...
893
+ // 1) Determine if it's applicable given the mode
894
+ // 2) For each applicable mode create a `Type` entry
823
895
  for ( const schema of schemas ) {
896
+ let schemaModes = { };
897
+
898
+ modes.forEach((m) => {
899
+ schemaModes[m] = true;
900
+ });
901
+
824
902
  const attrs = schema.attributes || {};
825
- const count = counts[schema.id];
826
- const label = getters.labelFor(schema, count);
827
- const weight = getters.typeWeightFor(schema?.id || label, isBasic);
828
903
  const typeOptions = getters['optionsFor'](schema);
829
904
 
830
- if ( isBasic ) {
831
- // These are separate ifs so that things with no kind can still be basic
832
- if ( !getters.groupForBasicType(product, schema.id) ) {
833
- continue;
834
- }
835
- } else if ( mode === FAVORITE && !getters.isFavorite(schema.id) ) {
836
- continue;
837
- } else if ( !attrs.kind ) {
838
- // Skip the schemas that aren't top-level types
839
- continue;
840
- } else if ( typeof typeOptions.ifRancherCluster !== 'undefined' && typeOptions.ifRancherCluster !== rootGetters.isRancher ) {
905
+ schemaModes[TYPE_MODES.BASIC] = schemaModes[TYPE_MODES.BASIC] && getters.groupForBasicType(product, schema.id);
906
+
907
+ if (Object.values(schemaModes).every((s) => !s)) {
841
908
  continue;
842
- } else if (typeOptions.localOnly && !rootGetters.currentCluster?.isLocal) {
909
+ }
910
+
911
+ schemaModes[TYPE_MODES.FAVORITE] = schemaModes[TYPE_MODES.FAVORITE] && getters.isFavorite(schema.id);
912
+
913
+ if (Object.values(schemaModes).every((s) => !s)) {
843
914
  continue;
844
915
  }
845
916
 
846
- out[schema.id] = {
847
- label,
848
- mode,
849
- weight,
850
- schema,
851
- name: schema.id,
852
- namespaced: typeOptions.namespaced === null ? attrs.namespaced : typeOptions.namespaced,
853
- count: count ? count.summary.count || 0 : null,
854
- byNamespace: count ? count.namespaces : {},
855
- revision: count ? count.revision : null,
856
- route: typeOptions.customRoute
857
- };
917
+ const onlyBasic = schemaModes[TYPE_MODES.BASIC] && modes.length === 1;
918
+
919
+ // This clause is only valid for non-basic modes. So if we have only basic... skip it
920
+ if (!onlyBasic) {
921
+ const invalidType = !attrs.kind ||
922
+ (typeof typeOptions.ifRancherCluster !== 'undefined' && typeOptions.ifRancherCluster !== isRancher) ||
923
+ (typeOptions.localOnly && isLocal);
924
+
925
+ if (invalidType) {
926
+ // Remove anything not basic
927
+ schemaModes = { [TYPE_MODES.BASIC]: schemaModes[TYPE_MODES.BASIC] };
928
+ }
929
+ }
930
+
931
+ // This is an expensive request to make, so only do it if we really need to
932
+ let label;
933
+
934
+ Object.entries(schemaModes).forEach(([mode, enabled]) => {
935
+ if (!enabled) {
936
+ return;
937
+ }
938
+
939
+ if (!out[mode]) {
940
+ out[mode] = {};
941
+ }
942
+
943
+ if (!label) {
944
+ label = getters.labelFor(schema, counts[schema.id]);
945
+ }
946
+
947
+ out[mode][schema.id] = {
948
+ label,
949
+ mode,
950
+ weight: getters.typeWeightFor(schema?.id || label, mode === TYPE_MODES.BASIC),
951
+ schema,
952
+ name: schema.id,
953
+ namespaced: typeOptions.namespaced === null ? attrs.namespaced : typeOptions.namespaced,
954
+ route: typeOptions.customRoute
955
+ };
956
+ });
858
957
  }
859
958
 
959
+ const nonUsedModes = modes.filter((m) => m !== TYPE_MODES.USED);
960
+ const isDev = rootGetters['prefs/get'](VIEW_IN_API);
961
+
860
962
  // Add virtual and spoofed types
861
- if ( mode !== USED ) {
963
+ if ( nonUsedModes.length ) {
862
964
  const virtualTypes = state.virtualTypes[product] || [];
863
965
  const spoofedTypes = state.spoofedTypes[product] || [];
864
966
  const allTypes = [...virtualTypes, ...spoofedTypes];
@@ -866,13 +968,15 @@ export const getters = {
866
968
  for ( const type of allTypes ) {
867
969
  const item = clone(type);
868
970
  const id = item.name;
869
- const weight = type.weight || getters.typeWeightFor(item.label, isBasic);
971
+ const virtSpoofedModes = [...nonUsedModes];
870
972
 
871
973
  // Is there a virtual/spoofed type override for schema type?
872
974
  // Currently used by harvester, this should be investigated and removed if possible
873
- if (out[id]) {
874
- delete out[id];
875
- }
975
+ virtSpoofedModes.forEach((mode) => {
976
+ if (out[mode]?.[id]) {
977
+ delete out[mode][id];
978
+ }
979
+ });
876
980
 
877
981
  if ( item['public'] === false && !isDev ) {
878
982
  continue;
@@ -883,16 +987,29 @@ export const getters = {
883
987
  }
884
988
 
885
989
  if ( item.ifHaveType ) {
886
- const targetedSchemas = typeof item.ifHaveType === 'string' ? schemas : rootGetters[`${ item.ifHaveType.store }/all`](SCHEMA);
887
- const type = typeof item.ifHaveType === 'string' ? item.ifHaveType : item.ifHaveType?.type;
990
+ const ifHaveTypeArray = Array.isArray(item.ifHaveType) ? item.ifHaveType : [item.ifHaveType];
991
+ let satisfiesIfHave = true;
888
992
 
889
- const haveIds = filterBy(targetedSchemas, 'id', normalizeType(type)).map((s) => s.id);
993
+ // Support an array of required types that the user must have access to
994
+ for (let i = 0; i < ifHaveTypeArray.length; i++) {
995
+ const ifHaveType = ifHaveTypeArray[i];
996
+ const targetedSchemas = typeof ifHaveType === 'string' ? schemas : rootGetters[`${ ifHaveType.store }/all`](SCHEMA);
997
+ const type = typeof ifHaveType === 'string' ? ifHaveType : ifHaveType?.type;
890
998
 
891
- if (!haveIds.length) {
892
- continue;
999
+ const haveIds = filterBy(targetedSchemas, 'id', normalizeType(type)).map((s) => s.id);
1000
+
1001
+ if (!haveIds.length) {
1002
+ satisfiesIfHave = false;
1003
+ break;
1004
+ }
1005
+
1006
+ if (item.ifHaveVerb && !ifHaveVerb(rootGetters, module, item.ifHaveVerb, haveIds)) {
1007
+ satisfiesIfHave = false;
1008
+ break;
1009
+ }
893
1010
  }
894
1011
 
895
- if (item.ifHaveVerb && !ifHaveVerb(rootGetters, module, item.ifHaveVerb, haveIds)) {
1012
+ if (!satisfiesIfHave) {
896
1013
  continue;
897
1014
  }
898
1015
  }
@@ -911,14 +1028,27 @@ export const getters = {
911
1028
  continue;
912
1029
  }
913
1030
 
914
- if ( isBasic && !getters.groupForBasicType(product, id) ) {
915
- continue;
916
- } else if ( mode === FAVORITE && !getters.isFavorite(id) ) {
917
- continue;
1031
+ if (item.ifFeature) {
1032
+ if (item.ifFeature[0] === '!') {
1033
+ const feature = item.ifFeature.replace('!', '');
1034
+
1035
+ if (rootGetters['features/get'](feature)) {
1036
+ continue;
1037
+ }
1038
+ } else {
1039
+ if (!rootGetters['features/get'](item.ifFeature)) {
1040
+ continue;
1041
+ }
1042
+ }
1043
+ }
1044
+
1045
+ if (virtSpoofedModes.includes(TYPE_MODES.BASIC) && !getters.groupForBasicType(product, id) ) {
1046
+ virtSpoofedModes.splice(virtSpoofedModes.indexOf(TYPE_MODES.BASIC), 1);
918
1047
  }
919
1048
 
920
- item.mode = mode;
921
- item.weight = weight;
1049
+ if (virtSpoofedModes.includes(TYPE_MODES.FAVORITE) && !getters.isFavorite(id) ) { // mode === TYPE_MODES.FAVORITE &&
1050
+ virtSpoofedModes.splice(virtSpoofedModes.indexOf(TYPE_MODES.FAVORITE), 1);
1051
+ }
922
1052
 
923
1053
  // Ensure labelKey is taken into account... with a mock count
924
1054
  // This is harmless if the translation doesn't require count
@@ -929,7 +1059,17 @@ export const getters = {
929
1059
  item.label = item.label || item.name;
930
1060
  }
931
1061
 
932
- out[id] = item;
1062
+ virtSpoofedModes.forEach((mode) => {
1063
+ const isBasic = mode === TYPE_MODES.BASIC;
1064
+ const weight = type.weight || getters.typeWeightFor(item.label, isBasic);
1065
+
1066
+ item.mode = mode;
1067
+ item.weight = weight;
1068
+ if (!out[mode]) {
1069
+ out[mode] = {};
1070
+ }
1071
+ out[mode][id] = item;
1072
+ });
933
1073
  }
934
1074
  }
935
1075
 
@@ -950,99 +1090,46 @@ export const getters = {
950
1090
  },
951
1091
 
952
1092
  headersFor(state, getters, rootState, rootGetters) {
953
- return (schema) => {
954
- const attributes = schema.attributes || {};
955
- const columns = attributes.columns || [];
956
- const typeOptions = getters['optionsFor'](schema);
957
-
958
- // A specific list has been provided
959
- if ( state.headers[schema.id] ) {
960
- return state.headers[schema.id].map((entry) => {
961
- if ( typeof entry === 'string' ) {
962
- const col = findBy(columns, 'name', entry);
963
-
964
- if ( col ) {
965
- return fromSchema(col, rootGetters);
966
- } else {
967
- return null;
968
- }
969
- } else {
970
- return entry;
971
- }
972
- }).filter((col) => !!col);
973
- }
1093
+ return (schema, pagination) => {
1094
+ if (pagination) {
1095
+ const storeHeadersFor = schema?.$ctx?.getters?.['headersFor'];
974
1096
 
975
- // Otherwise make one up from schema
976
- const out = typeOptions.showState ? [STATE] : [];
977
- const namespaced = attributes.namespaced || false;
978
- let hasName = false;
979
-
980
- for ( const col of columns ) {
981
- if ( col.format === 'name' ) {
982
- hasName = true;
983
- out.push(NAME);
984
- if ( namespaced ) {
985
- out.push(NAMESPACE_COL);
986
- }
987
- } else {
988
- out.push(fromSchema(col, rootGetters));
989
- }
990
- }
1097
+ if (storeHeadersFor) {
1098
+ const res = storeHeadersFor({ getters, state }, { schema, pagination });
991
1099
 
992
- if ( !hasName ) {
993
- insertAt(out, 1, NAME);
994
- if ( namespaced ) {
995
- insertAt(out, 2, NAMESPACE_COL);
996
- }
997
- }
998
-
999
- // Age always goes last
1000
- if ( out.includes(AGE) ) {
1001
- removeObject(out, AGE);
1002
- if ( typeOptions.showAge ) {
1003
- out.push(AGE);
1100
+ if (res) {
1101
+ return res;
1102
+ }
1004
1103
  }
1005
1104
  }
1006
1105
 
1007
- return out;
1008
-
1009
- function fromSchema(col, rootGetters) {
1010
- let formatter, width, formatterOpts;
1011
-
1012
- if ( (col.format === '' || col.format === 'date') && col.name === 'Age' ) {
1013
- return AGE;
1014
- }
1015
-
1016
- if ( col.format === 'date' || col.type === 'date' ) {
1017
- formatter = 'Date';
1018
- width = 120;
1019
- formatterOpts = { multiline: true };
1020
- }
1106
+ return createHeaders({ rootGetters }, {
1107
+ headers: state.headers,
1108
+ typeOptions: getters['optionsFor'](schema, false),
1109
+ schema,
1110
+ columns: {
1111
+ state: STATE,
1112
+ name: NAME,
1113
+ namespace: NAMESPACE_COL,
1114
+ age: AGE,
1115
+ },
1116
+ pagination
1117
+ });
1118
+ };
1119
+ },
1021
1120
 
1022
- if ( col.type === 'number' || col.type === 'int' ) {
1023
- formatter = 'Number';
1024
- }
1121
+ /**
1122
+ * Simple getter to fetch pre-configured headers used in pagination
1123
+ */
1124
+ configuredPaginationHeaders(state) {
1125
+ return (schemaOrType) => state.paginationHeaders?.[schemaOrType.id || schemaOrType];
1126
+ },
1025
1127
 
1026
- const colName = col.name.includes(' ') ? col.name.split(' ').map((word) => word.charAt(0).toUpperCase() + word.substring(1) ).join('') : col.name;
1027
-
1028
- const exists = rootGetters['i18n/exists'];
1029
- const t = rootGetters['i18n/t'];
1030
- const labelKey = `tableHeaders.${ colName.charAt(0).toLowerCase() + colName.slice(1) }`;
1031
- const description = col.description || '';
1032
- const tooltip = description && description[description.length - 1] === '.' ? description.slice(0, -1) : description;
1033
-
1034
- return {
1035
- name: col.name.toLowerCase(),
1036
- label: exists(labelKey) ? t(labelKey) : col.name,
1037
- value: _rowValueGetter(col),
1038
- sort: [col.field],
1039
- formatter,
1040
- formatterOpts,
1041
- width,
1042
- tooltip
1043
- };
1044
- }
1045
- };
1128
+ /**
1129
+ * Simple getter to fetch pre-configured headers (not used in paginated lists)
1130
+ */
1131
+ configuredHeaders(state) {
1132
+ return (schemaOrType) => state.headers?.[schemaOrType.id || schemaOrType];
1046
1133
  },
1047
1134
 
1048
1135
  // ------------------------------------
@@ -1352,7 +1439,7 @@ export const getters = {
1352
1439
  return (schema, colName) => {
1353
1440
  const col = _findColumnByName(schema, colName);
1354
1441
 
1355
- return _rowValueGetter(col);
1442
+ return rowValueGetter(col);
1356
1443
  };
1357
1444
  },
1358
1445
 
@@ -1363,6 +1450,10 @@ export const getters = {
1363
1450
  return !!prod;
1364
1451
  };
1365
1452
  },
1453
+
1454
+ productByName(state) {
1455
+ return (productName) => state.products.find((p) => p.name === productName);
1456
+ }
1366
1457
  };
1367
1458
 
1368
1459
  export const mutations = {
@@ -1422,12 +1513,27 @@ export const mutations = {
1422
1513
  },
1423
1514
 
1424
1515
  product(state, obj) {
1425
- const existing = findBy(state.products, 'name', obj.name);
1516
+ let existing = state.products.find((p) => p.name === obj.name);
1426
1517
 
1427
1518
  if ( existing ) {
1428
1519
  Object.assign(existing, obj);
1429
1520
  } else {
1430
1521
  addObject(state.products, obj);
1522
+ existing = state.products.find((p) => p.name === obj.name);
1523
+ }
1524
+
1525
+ // Make sure deprecated `inExplorer` is synchronized with `rootProduct` (and vice-versa)
1526
+ if (existing?.inExplorer) {
1527
+ existing.rootProduct = EXPLORER;
1528
+ } else if (existing?.rootProduct === EXPLORER) {
1529
+ existing.inExplorer = true;
1530
+ }
1531
+
1532
+ // We make an assumption that if the store for a product is 'cluster' it will be displayed within cluster explorer
1533
+ // Detect that here and set rootProduct and inExporer in this case
1534
+ if (!existing?.rootProduct && existing?.inStore === 'cluster') {
1535
+ existing.rootProduct = EXPLORER;
1536
+ existing.inExplorer = (existing.rootProduct === EXPLORER);
1431
1537
  }
1432
1538
  },
1433
1539
 
@@ -1523,6 +1629,10 @@ export const mutations = {
1523
1629
  state.headers[type] = headers;
1524
1630
  },
1525
1631
 
1632
+ paginationHeaders(state, { type, paginationHeaders }) {
1633
+ state.paginationHeaders[type] = paginationHeaders;
1634
+ },
1635
+
1526
1636
  hideBulkActions(state, { type, field }) {
1527
1637
  state.hideBulkActions[type] = field;
1528
1638
  },
@@ -1679,22 +1789,6 @@ function _sortGroup(tree, mode) {
1679
1789
  }
1680
1790
  }
1681
1791
 
1682
- function _matchingCounts(typeObj, namespaces) {
1683
- // That was easy
1684
- if ( !typeObj.namespaced || !typeObj.byNamespace || namespaces === null || typeObj.count === null) {
1685
- return typeObj.count;
1686
- }
1687
-
1688
- let out = 0;
1689
-
1690
- // Otherwise start with 0 and count up
1691
- for ( const namespace of namespaces ) {
1692
- out += typeObj.byNamespace[namespace]?.count || 0;
1693
- }
1694
-
1695
- return out;
1696
- }
1697
-
1698
1792
  function _applyMapping(objOrValue, mappings, keyField, cache, defaultFn) {
1699
1793
  let key = objOrValue;
1700
1794
  let found = false;
@@ -1835,25 +1929,6 @@ function _findColumnByName(schema, colName) {
1835
1929
  return findBy(columns, 'name', colName);
1836
1930
  }
1837
1931
 
1838
- function _rowValueGetter(col) {
1839
- // 'field' comes from the schema - typically it is of the form $.metadata.field[N]
1840
- // We will use JsonPath to look up this value, which is costly - so if we can detect this format
1841
- // Use a more efficient function to get the value
1842
- const value = col.field.startsWith('.') ? `$${ col.field }` : col.field;
1843
-
1844
- if (process.client) {
1845
- const found = value.match(FIELD_REGEX);
1846
-
1847
- if (found && found.length === 2) {
1848
- const fieldIndex = parseInt(found[1], 10);
1849
-
1850
- return (row) => row.metadata?.fields?.[fieldIndex];
1851
- }
1852
- }
1853
-
1854
- return value;
1855
- }
1856
-
1857
1932
  // Is V1 Istio installed?
1858
1933
  function isV1Istio(getters) {
1859
1934
  const cluster = getters['currentCluster'];