@rancher/shell 0.5.3 → 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 (581) 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 +2 -0
  7. package/assets/styles/themes/_csp.scss +2 -2
  8. package/assets/styles/themes/_dark.scss +8 -2
  9. package/assets/styles/themes/_light.scss +2 -1
  10. package/assets/styles/themes/_suse.scss +1 -1
  11. package/assets/styles/vendor/vue-select.scss +5 -0
  12. package/assets/translations/en-us.yaml +296 -58
  13. package/assets/translations/zh-hans.yaml +5 -27
  14. package/babel.config.js +1 -1
  15. package/chart/__tests__/S3.test.ts +9 -2
  16. package/chart/monitoring/grafana/index.vue +6 -2
  17. package/chart/monitoring/prometheus/index.vue +2 -2
  18. package/chart/rancher-backup/S3.vue +11 -9
  19. package/chart/rancher-backup/index.vue +15 -5
  20. package/cloud-credential/__tests__/harvester.test.ts +18 -0
  21. package/cloud-credential/generic.vue +18 -9
  22. package/cloud-credential/harvester.vue +11 -3
  23. package/components/AppModal.vue +167 -0
  24. package/components/AssignTo.vue +7 -4
  25. package/components/AsyncButton.vue +18 -5
  26. package/components/BackLink.vue +4 -4
  27. package/components/BannerGraphic.vue +1 -0
  28. package/components/BrandImage.vue +47 -1
  29. package/components/Carousel.vue +14 -8
  30. package/components/Certificates.vue +8 -11
  31. package/components/ClusterBadge.vue +12 -3
  32. package/components/ClusterIconMenu.vue +44 -16
  33. package/components/ClusterProviderIcon.vue +14 -3
  34. package/components/CodeMirror.vue +73 -38
  35. package/components/CommunityLinks.vue +12 -8
  36. package/components/CreateDriver.vue +81 -0
  37. package/components/CruResource.vue +51 -27
  38. package/components/DetailTop.vue +2 -2
  39. package/components/Dialog.vue +6 -5
  40. package/components/DisableAuthProviderModal.vue +14 -8
  41. package/components/DraggableZone.vue +2 -2
  42. package/components/ExplorerMembers.vue +3 -3
  43. package/components/ExplorerProjectsNamespaces.vue +6 -6
  44. package/components/FixedBanner.vue +47 -36
  45. package/components/GlobalRoleBindings.vue +26 -0
  46. package/components/Import.vue +10 -6
  47. package/components/Inactivity.vue +1 -5
  48. package/components/KeyValueView.vue +14 -10
  49. package/components/MessageLink.vue +2 -2
  50. package/components/ModalWithCard.vue +5 -8
  51. package/components/MoveModal.vue +35 -33
  52. package/components/PodSecurityAdmission.vue +3 -3
  53. package/components/PromptChangePassword.vue +33 -33
  54. package/components/PromptModal.vue +11 -21
  55. package/components/PromptRemove.vue +11 -17
  56. package/components/PromptRestore.vue +18 -16
  57. package/components/Questions/__tests__/Boolean.test.ts +9 -19
  58. package/components/Questions/__tests__/Float.test.ts +9 -19
  59. package/components/Questions/__tests__/Int.test.ts +9 -19
  60. package/components/Questions/__tests__/String.test.ts +9 -19
  61. package/components/Questions/__tests__/Yaml.test.ts +9 -20
  62. package/components/Questions/__tests__/utils/questions-defaults.ts +20 -0
  63. package/components/Questions/index.vue +18 -2
  64. package/components/ResourceCancelModal.vue +34 -29
  65. package/components/ResourceDetail/Masthead.vue +23 -7
  66. package/components/ResourceDetail/index.vue +5 -0
  67. package/components/ResourceList/Masthead.vue +28 -10
  68. package/components/ResourceList/index.vue +65 -14
  69. package/components/ResourceTable.vue +73 -19
  70. package/components/ResourceYaml.vue +1 -0
  71. package/components/SelectIconGrid.vue +3 -3
  72. package/components/SideNav.vue +15 -37
  73. package/components/SingleClusterInfo.vue +4 -4
  74. package/components/SortableTable/THead.vue +26 -12
  75. package/components/SortableTable/filtering.js +9 -1
  76. package/components/SortableTable/grouping.js +8 -1
  77. package/components/SortableTable/index.vue +142 -42
  78. package/components/SortableTable/paging.js +36 -7
  79. package/components/SortableTable/selection.js +2 -1
  80. package/components/SortableTable/sorting.js +24 -7
  81. package/components/TabTitle.vue +84 -0
  82. package/components/Tabbed/index.vue +6 -1
  83. package/components/TableDataUserIcon.vue +47 -0
  84. package/components/TypeDescription.vue +1 -0
  85. package/components/Wizard.vue +1 -0
  86. package/components/__tests__/AppModal.test.ts +98 -0
  87. package/components/__tests__/AsyncButton.test.ts +1 -3
  88. package/components/__tests__/BackLink.test.ts +1 -1
  89. package/components/__tests__/ButtonGroup.test.ts +3 -6
  90. package/components/__tests__/Carousel.test.ts +43 -0
  91. package/components/__tests__/Certificates.test.ts +29 -0
  92. package/components/__tests__/{CodeMirror.spec.ts → CodeMirror.test.ts} +5 -17
  93. package/components/__tests__/CruResource.test.ts +10 -9
  94. package/components/__tests__/EtcdInfoBanner.test.ts +37 -0
  95. package/components/__tests__/FixedBanner.test.ts +5 -20
  96. package/components/__tests__/NamespaceFilter.test.ts +9 -18
  97. package/components/__tests__/TabTitle.test.ts +129 -0
  98. package/components/auth/AzureWarning.vue +2 -2
  99. package/components/auth/RoleDetailEdit.vue +10 -0
  100. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  101. package/components/auth/login/oidc.vue +7 -1
  102. package/components/fleet/FleetClusters.vue +9 -9
  103. package/components/fleet/FleetIntro.vue +11 -17
  104. package/components/fleet/FleetNoWorkspaces.vue +2 -2
  105. package/components/fleet/FleetRepos.vue +1 -0
  106. package/components/fleet/ForceDirectedTreeChart/index.vue +9 -3
  107. package/components/form/ArrayList.vue +30 -19
  108. package/components/form/ArrayListSelect.vue +9 -4
  109. package/components/form/ClusterAppearance.vue +132 -0
  110. package/components/form/ColorInput.vue +1 -0
  111. package/components/form/Error.vue +3 -3
  112. package/components/form/Footer.vue +2 -2
  113. package/components/form/GitPicker.vue +83 -38
  114. package/components/form/KeyValue.vue +67 -48
  115. package/components/form/LabeledSelect.vue +143 -43
  116. package/components/form/Labels.vue +3 -1
  117. package/components/form/NameNsDescription.vue +26 -9
  118. package/components/form/ResourceLabeledSelect.vue +187 -0
  119. package/components/form/ResourceTabs/index.vue +31 -15
  120. package/components/form/SecretSelector.vue +93 -18
  121. package/components/form/Select.vue +1 -1
  122. package/components/form/SelectOrCreateAuthSecret.vue +135 -62
  123. package/components/form/SimpleSecretSelector.vue +88 -28
  124. package/components/form/__tests__/BannerSettings.test.ts +53 -0
  125. package/components/form/__tests__/KeyValue.test.ts +121 -12
  126. package/components/form/__tests__/LabeledSelect.test.ts +0 -18
  127. package/components/form/__tests__/NameNsDescription.test.ts +25 -15
  128. package/components/form/labeled-select-utils/labeled-select-pagination.ts +151 -0
  129. package/components/form/labeled-select-utils/labeled-select.utils.ts +122 -0
  130. package/components/formatter/AppSummaryGraph.vue +2 -2
  131. package/components/formatter/CloudCredPublicData.vue +30 -0
  132. package/components/formatter/ClusterLink.vue +2 -2
  133. package/components/formatter/FleetSummaryGraph.vue +2 -1
  134. package/components/formatter/ImagePercentageBar.vue +0 -4
  135. package/components/formatter/IngressTarget.vue +18 -7
  136. package/components/formatter/Link.vue +2 -2
  137. package/components/formatter/LinkDetail.vue +2 -2
  138. package/components/formatter/LinkDetailImage.vue +2 -2
  139. package/components/formatter/LinkName.vue +2 -2
  140. package/components/formatter/LiveDate.vue +16 -0
  141. package/components/formatter/PrincipalGroupBindings.vue +2 -2
  142. package/components/formatter/SecretType.vue +2 -2
  143. package/components/formatter/VirtualServiceGateways.vue +2 -2
  144. package/components/formatter/__tests__/LinkDetail.test.ts +5 -5
  145. package/components/nav/Group.vue +7 -5
  146. package/components/nav/Header.vue +82 -43
  147. package/components/nav/NamespaceFilter.vue +8 -1
  148. package/components/nav/TopLevelMenu.vue +336 -125
  149. package/components/nav/Type.vue +58 -102
  150. package/components/nav/__tests__/TopLevelMenu.test.ts +370 -9
  151. package/components/nav/__tests__/Type.test.ts +321 -126
  152. package/components/nuxt/nuxt-child.js +0 -5
  153. package/components/nuxt/nuxt-error.vue +1 -1
  154. package/components/nuxt/nuxt-link.client.js +13 -95
  155. package/components/templates/default.vue +3 -3
  156. package/components/templates/error.vue +6 -10
  157. package/components/templates/standalone.vue +0 -4
  158. package/components/templates/unauthenticated.vue +1 -2
  159. package/components/user.retention/user-retention-header.vue +34 -0
  160. package/composables/useCompactInput.test.ts +36 -0
  161. package/composables/useCompactInput.ts +2 -2
  162. package/composables/useI18n.ts +26 -0
  163. package/composables/useLabeledFormElement.test.ts +135 -0
  164. package/composables/useStore.ts +16 -0
  165. package/config/home-links.js +32 -1
  166. package/config/labels-annotations.js +2 -1
  167. package/config/middleware.js +0 -6
  168. package/config/pagination-table-headers.js +57 -0
  169. package/config/pod-security-admission.ts +1 -1
  170. package/config/private-label.js +1 -3
  171. package/config/product/auth.js +1 -0
  172. package/config/product/explorer.js +167 -46
  173. package/config/product/legacy.js +3 -95
  174. package/config/product/manager.js +44 -11
  175. package/config/query-params.js +1 -0
  176. package/config/roles.ts +23 -0
  177. package/config/router/index.js +23 -0
  178. package/config/router/navigation-guards/attempt-first-login.js +73 -0
  179. package/config/router/navigation-guards/authentication.js +63 -0
  180. package/config/router/navigation-guards/index.js +15 -0
  181. package/config/router/navigation-guards/load-initial-settings.js +15 -0
  182. package/config/router/routes.js +487 -0
  183. package/config/settings.ts +38 -2
  184. package/config/store.js +7 -3
  185. package/config/table-headers.js +46 -1
  186. package/config/types.js +36 -16
  187. package/config/uiplugins.js +10 -5
  188. package/core/plugin-helpers.js +1 -1
  189. package/core/plugin.ts +2 -1
  190. package/core/plugins.js +289 -282
  191. package/creators/app/files/.eslintignore +0 -2
  192. package/creators/app/files/.vscode/settings.json +0 -1
  193. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +2 -6
  194. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +2 -6
  195. package/creators/pkg/init +32 -0
  196. package/detail/__tests__/service.test.ts +62 -0
  197. package/detail/catalog.cattle.io.app.vue +1 -1
  198. package/detail/cis.cattle.io.clusterscan.vue +14 -3
  199. package/detail/fleet.cattle.io.gitrepo.vue +15 -9
  200. package/detail/namespace.vue +2 -2
  201. package/detail/networking.k8s.io.ingress.vue +52 -19
  202. package/detail/node.vue +20 -43
  203. package/detail/pod.vue +1 -68
  204. package/detail/provisioning.cattle.io.cluster.vue +2 -1
  205. package/detail/service.vue +1 -1
  206. package/detail/workload/index.vue +2 -15
  207. package/dialog/AddCustomBadgeDialog.vue +318 -161
  208. package/dialog/DeactivateDriverDialog.vue +118 -0
  209. package/dialog/RollbackWorkloadDialog.vue +2 -2
  210. package/dialog/RotateCertificatesDialog.vue +0 -21
  211. package/directives/clean-html.js +15 -0
  212. package/directives/clean-tooltip.js +32 -0
  213. package/directives/focus.js +41 -0
  214. package/directives/int-number.js +21 -0
  215. package/directives/positive-int-number.js +19 -0
  216. package/directives/trim-whitespace.js +19 -0
  217. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +3 -2
  218. package/edit/__tests__/kontainerDriver.test.ts +107 -0
  219. package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +12 -1
  220. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  221. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +2 -3
  222. package/edit/__tests__/nodeDriver.test.ts +107 -0
  223. package/edit/__tests__/service.test.ts +1 -5
  224. package/edit/__tests__/ui.cattle.io.navlink.test.ts +3 -1
  225. package/edit/auth/AuthProviderWarningBanners.vue +34 -0
  226. package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +19 -0
  227. package/edit/auth/__tests__/azuread.test.ts +241 -0
  228. package/edit/auth/__tests__/oidc.test.ts +137 -0
  229. package/edit/auth/azuread.vue +133 -31
  230. package/edit/auth/github.vue +5 -17
  231. package/edit/auth/googleoauth.vue +5 -18
  232. package/edit/auth/ldap/index.vue +5 -17
  233. package/edit/auth/oidc.vue +143 -42
  234. package/edit/auth/saml.vue +5 -14
  235. package/edit/catalog.cattle.io.clusterrepo.vue +175 -20
  236. package/edit/cis.cattle.io.clusterscan.vue +5 -2
  237. package/edit/cis.cattle.io.clusterscanbenchmark.vue +41 -9
  238. package/edit/cloudcredential.vue +26 -4
  239. package/edit/configmap.vue +10 -4
  240. package/edit/fleet.cattle.io.gitrepo.vue +7 -4
  241. package/edit/helm.cattle.io.projecthelmchart.vue +29 -19
  242. package/edit/kontainerDriver.vue +65 -0
  243. package/edit/logging-flow/Match.vue +10 -9
  244. package/edit/logging-flow/index.vue +4 -19
  245. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +232 -2
  246. package/edit/logging.banzaicloud.io.output/index.vue +43 -26
  247. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -3
  248. package/edit/management.cattle.io.project.vue +2 -1
  249. package/edit/management.cattle.io.setting.vue +20 -0
  250. package/edit/management.cattle.io.user.vue +2 -1
  251. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +10 -7
  252. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +21 -16
  253. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +1 -0
  254. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -0
  255. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -0
  256. package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +2 -0
  257. package/edit/monitoring.coreos.com.prometheusrule/index.vue +2 -0
  258. package/edit/networking.k8s.io.ingress/Rules.vue +8 -3
  259. package/edit/networking.k8s.io.ingress/index.vue +64 -8
  260. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -0
  261. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +6 -2
  262. package/edit/networking.k8s.io.networkpolicy/__tests__/{PolicyRuleTarget.spec.ts → PolicyRuleTarget.test.ts} +45 -6
  263. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.test.ts +1 -1
  264. package/edit/networking.k8s.io.networkpolicy/index.vue +2 -0
  265. package/edit/nodeDriver.vue +65 -0
  266. package/edit/persistentvolume/index.vue +2 -2
  267. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +18 -9
  268. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +165 -1
  269. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +1 -1
  270. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +0 -3
  271. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +228 -0
  272. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +70 -12
  273. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +5 -0
  274. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  275. package/edit/provisioning.cattle.io.cluster/index.vue +21 -15
  276. package/edit/provisioning.cattle.io.cluster/rke2.vue +185 -114
  277. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +67 -7
  278. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +19 -6
  279. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +132 -0
  280. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +7 -0
  281. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +1 -0
  282. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +1 -0
  283. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +3 -0
  284. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -0
  285. package/edit/resources.cattle.io.backup.vue +139 -124
  286. package/edit/resources.cattle.io.restore.vue +146 -126
  287. package/edit/service.vue +1 -0
  288. package/edit/serviceaccount.vue +46 -4
  289. package/edit/workload/__tests__/Job.test.ts +1 -3
  290. package/edit/workload/__tests__/Upgrading.test.ts +2 -2
  291. package/edit/workload/mixins/workload.js +34 -1
  292. package/edit/workload/storage/emptyDir.vue +2 -2
  293. package/initialize/App.vue +75 -0
  294. package/initialize/app-extended.js +128 -0
  295. package/initialize/entry-helpers.js +549 -0
  296. package/initialize/entry.js +32 -0
  297. package/initialize/install-components.js +23 -0
  298. package/initialize/install-directives.js +59 -0
  299. package/initialize/install-plugins.js +123 -0
  300. package/list/__tests__/workload.test.ts +1 -1
  301. package/list/cis.cattle.io.clusterscan.vue +16 -10
  302. package/list/group.principal.vue +2 -2
  303. package/list/management.cattle.io.feature.vue +11 -7
  304. package/list/management.cattle.io.user.vue +36 -3
  305. package/list/networking.k8s.io.ingress.vue +36 -0
  306. package/list/node.vue +211 -73
  307. package/list/provisioning.cattle.io.cluster.vue +17 -4
  308. package/list/ui.cattle.io.navlink.vue +2 -2
  309. package/list/workload.vue +22 -0
  310. package/machine-config/__tests__/vmwarevsphere-pool-config-merge.test.ts +30 -0
  311. package/machine-config/__tests__/vmwarevsphere.test.ts +162 -59
  312. package/machine-config/amazonec2.vue +1 -1
  313. package/machine-config/azure.vue +38 -21
  314. package/machine-config/generic.vue +11 -15
  315. package/machine-config/vmwarevsphere-pool-config-merge.ts +25 -0
  316. package/machine-config/vmwarevsphere.vue +20 -11
  317. package/middleware/authenticated.js +9 -361
  318. package/mixins/__tests__/chart.test.ts +48 -6
  319. package/mixins/__tests__/create-edit-view.test.ts +2 -3
  320. package/mixins/auth-config.js +3 -2
  321. package/mixins/brand.js +75 -57
  322. package/mixins/chart.js +27 -13
  323. package/mixins/create-edit-view/index.js +2 -2
  324. package/mixins/fetch.client.js +42 -48
  325. package/mixins/labeled-form-element.ts +21 -1
  326. package/mixins/page-actions.js +7 -5
  327. package/mixins/resource-fetch-api-pagination.js +304 -0
  328. package/mixins/resource-fetch-namespaced.js +1 -1
  329. package/mixins/resource-fetch.js +46 -5
  330. package/models/__tests__/cluster.test.ts +44 -0
  331. package/models/__tests__/fleet.cattle.io.cluster.test.ts +36 -0
  332. package/models/__tests__/schema.tests.ts +24 -0
  333. package/models/__tests__/steve-schema.test.ts +73 -0
  334. package/models/__tests__/workload.test.ts +1 -1
  335. package/models/catalog.cattle.io.app.js +8 -0
  336. package/models/catalog.cattle.io.clusterrepo.js +9 -1
  337. package/models/catalog.cattle.io.uiplugin.js +7 -8
  338. package/models/cis.cattle.io.clusterscan.js +29 -8
  339. package/models/cloudcredential.js +9 -1
  340. package/models/cluster/node.js +4 -0
  341. package/models/cluster/schema.js +6 -0
  342. package/models/cluster.js +33 -0
  343. package/models/driver.js +62 -0
  344. package/models/fleet.cattle.io.cluster.js +23 -11
  345. package/models/fleet.cattle.io.gitrepo.js +10 -0
  346. package/models/helm.cattle.io.projecthelmchart.js +1 -1
  347. package/models/kontainerdriver.js +68 -0
  348. package/models/management/schema.js +6 -0
  349. package/models/management.cattle.io.authconfig.js +3 -2
  350. package/models/management.cattle.io.cluster.js +5 -4
  351. package/models/management.cattle.io.globalrole.js +2 -0
  352. package/models/management.cattle.io.user.js +67 -2
  353. package/models/monitoring.coreos.com.receiver.js +3 -1
  354. package/models/monitoring.coreos.com.route.js +1 -1
  355. package/models/networking.k8s.io.ingress.js +2 -1
  356. package/models/nodedriver.js +68 -0
  357. package/models/provisioning.cattle.io.cluster.js +34 -1
  358. package/models/schema.js +28 -7
  359. package/models/service.js +2 -0
  360. package/models/steve-schema.ts +254 -0
  361. package/models/workload.js +1 -0
  362. package/package.json +6 -5
  363. package/pages/about.vue +12 -5
  364. package/pages/account/index.vue +7 -2
  365. package/pages/auth/login.vue +106 -102
  366. package/pages/auth/logout.vue +2 -2
  367. package/pages/auth/setup.vue +57 -64
  368. package/pages/auth/verify.vue +17 -17
  369. package/pages/c/_cluster/apps/charts/chart.vue +54 -9
  370. package/pages/c/_cluster/apps/charts/index.vue +37 -13
  371. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  372. package/pages/c/_cluster/auth/config/_id.vue +0 -6
  373. package/pages/c/_cluster/auth/config/index.vue +15 -9
  374. package/pages/c/_cluster/auth/roles/index.vue +8 -10
  375. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  376. package/pages/c/_cluster/explorer/ConfigBadge.vue +13 -8
  377. package/pages/c/_cluster/explorer/EventsTable.vue +18 -0
  378. package/pages/c/_cluster/explorer/__tests__/index.test.ts +181 -0
  379. package/pages/c/_cluster/explorer/index.vue +231 -72
  380. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +69 -0
  381. package/pages/c/_cluster/explorer/tools/index.vue +12 -176
  382. package/pages/c/_cluster/fleet/index.vue +88 -93
  383. package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +89 -0
  384. package/pages/c/_cluster/longhorn/index.vue +52 -17
  385. package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -25
  386. package/pages/c/_cluster/manager/drivers/kontainerDriver/_id.vue +12 -0
  387. package/pages/c/_cluster/manager/drivers/kontainerDriver/create.vue +15 -0
  388. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +94 -0
  389. package/pages/c/_cluster/manager/drivers/nodeDriver/_id.vue +12 -0
  390. package/pages/c/_cluster/manager/drivers/nodeDriver/create.vue +15 -0
  391. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +63 -0
  392. package/pages/c/_cluster/manager/jwt.authentication/index.vue +235 -0
  393. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +4 -0
  394. package/pages/c/_cluster/monitoring/index.vue +1 -17
  395. package/pages/c/_cluster/monitoring/route-receiver/index.vue +2 -2
  396. package/pages/c/_cluster/neuvector/index.vue +1 -0
  397. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
  398. package/pages/c/_cluster/settings/banners.vue +86 -8
  399. package/pages/c/_cluster/settings/brand.vue +258 -36
  400. package/pages/c/_cluster/settings/index.vue +4 -4
  401. package/pages/c/_cluster/settings/links.vue +5 -3
  402. package/pages/c/_cluster/settings/performance.vue +71 -2
  403. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +5 -2
  404. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +10 -7
  405. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +9 -6
  406. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +11 -5
  407. package/pages/c/_cluster/uiplugins/InstallDialog.vue +53 -18
  408. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +36 -301
  409. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +14 -6
  410. package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +52 -106
  411. package/pages/c/_cluster/uiplugins/index.vue +38 -52
  412. package/pages/diagnostic.vue +1 -0
  413. package/pages/fail-whale.vue +103 -41
  414. package/pages/home.vue +81 -24
  415. package/pages/prefs.vue +8 -3
  416. package/pages/support/index.vue +12 -2
  417. package/plugins/clean-html-directive.js +5 -12
  418. package/plugins/clean-tooltip-directive.js +6 -31
  419. package/plugins/codemirror.js +0 -9
  420. package/plugins/dashboard-store/__tests__/mutations.test.ts +296 -313
  421. package/plugins/dashboard-store/actions.js +140 -32
  422. package/plugins/dashboard-store/getters.js +86 -39
  423. package/plugins/dashboard-store/index.js +0 -99
  424. package/plugins/dashboard-store/mutations.js +150 -48
  425. package/plugins/dashboard-store/resource-class.js +14 -109
  426. package/plugins/directives.js +6 -39
  427. package/plugins/ember-cookie.js +13 -0
  428. package/plugins/global-formatters.js +26 -5
  429. package/plugins/i18n.js +90 -56
  430. package/plugins/int-number.js +6 -20
  431. package/plugins/plugin.js +3 -3
  432. package/plugins/positive-int-number.js +6 -17
  433. package/plugins/steve/__tests__/{getters.spec.ts → getters.test.ts} +124 -31
  434. package/plugins/steve/__tests__/mutations.test.ts +49 -0
  435. package/plugins/steve/__tests__/subscribe.spec.ts +109 -0
  436. package/plugins/steve/__tests__/utils/mutation.test.helpers.ts +105 -0
  437. package/plugins/steve/accept-or-reject-socket-message.ts +103 -0
  438. package/plugins/steve/actions.js +0 -1
  439. package/plugins/steve/getters.js +183 -63
  440. package/plugins/steve/hybrid-class.js +5 -1
  441. package/plugins/steve/mutations.js +29 -5
  442. package/plugins/steve/norman-class.js +123 -2
  443. package/{utils → plugins/steve}/projectAndNamespaceFiltering.utils.ts +28 -10
  444. package/plugins/steve/schema.d.ts +22 -0
  445. package/plugins/steve/steve-pagination-utils.ts +368 -0
  446. package/plugins/steve/subscribe.js +37 -75
  447. package/plugins/trim-whitespace.js +6 -34
  448. package/plugins/vue-js-modal.js +1 -1
  449. package/public/index.html +1 -0
  450. package/rancher-components/Accordion/Accordion.vue +3 -2
  451. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  452. package/rancher-components/Banner/Banner.test.ts +1 -5
  453. package/rancher-components/Banner/Banner.vue +2 -2
  454. package/rancher-components/Card/Card.vue +4 -4
  455. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  456. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  457. package/rancher-components/Form/LabeledInput/LabeledInput.vue +66 -30
  458. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  459. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  460. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  461. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  462. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  463. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  464. package/rancher-components/StringList/StringList.vue +8 -8
  465. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  466. package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
  467. package/rancher-components/components/Banner/Banner.test.ts +1 -5
  468. package/rancher-components/components/Banner/Banner.vue +2 -2
  469. package/rancher-components/components/Card/Card.vue +4 -4
  470. package/rancher-components/components/Form/Checkbox/Checkbox.vue +4 -3
  471. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  472. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +66 -30
  473. package/rancher-components/components/Form/Radio/RadioButton.test.ts +1 -3
  474. package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
  475. package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
  476. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  477. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  478. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
  479. package/rancher-components/components/StringList/StringList.vue +8 -8
  480. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +27 -8
  481. package/scripts/clean +1 -1
  482. package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +11 -0
  483. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -0
  484. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  485. package/scripts/extension/helm/package/Dockerfile +1 -1
  486. package/scripts/extension/helm/scripts/patch +27 -0
  487. package/scripts/extension/publish +6 -6
  488. package/scripts/serve-pkgs +0 -2
  489. package/scripts/test-plugins-build.sh +6 -6
  490. package/scripts/vue-migrate.js +683 -0
  491. package/store/__tests__/catalog.test.ts +224 -0
  492. package/store/auth.js +23 -4
  493. package/store/aws.js +53 -6
  494. package/store/catalog.js +21 -5
  495. package/store/cru-resource.ts +26 -0
  496. package/store/customisation.js +35 -0
  497. package/store/features.js +6 -4
  498. package/store/index.js +132 -39
  499. package/store/plugins.js +8 -4
  500. package/store/type-map.js +143 -143
  501. package/store/type-map.utils.ts +226 -0
  502. package/tsconfig.json +0 -1
  503. package/tsconfig.paths.json +4 -1
  504. package/types/components/labeledSelect.ts +50 -0
  505. package/types/resources/settings.d.ts +32 -0
  506. package/types/{userPreferences.d.ts → resources/userPreferences.d.ts} +0 -1
  507. package/types/shell/index.d.ts +996 -782
  508. package/types/store/dashboard-store.types.ts +42 -0
  509. package/types/store/pagination.types.ts +457 -0
  510. package/types/store/type-map.ts +30 -0
  511. package/types/store/vuex.d.ts +9 -0
  512. package/types/vue-shim.d.ts +51 -0
  513. package/utils/__tests__/cluster.test.ts +20 -18
  514. package/utils/__tests__/create-yaml.test.ts +359 -2
  515. package/utils/__tests__/kontainer.test.ts +92 -0
  516. package/utils/__tests__/pod-security-admission.test.ts +1 -1
  517. package/utils/alertmanagerconfig.js +19 -0
  518. package/utils/array.ts +40 -1
  519. package/utils/async.ts +2 -0
  520. package/utils/auth.js +152 -4
  521. package/utils/axios.js +2 -2
  522. package/utils/banners.js +103 -0
  523. package/utils/cluster.js +1 -1
  524. package/utils/config.js +4 -0
  525. package/utils/create-yaml.js +54 -27
  526. package/utils/error.js +25 -0
  527. package/utils/formatter.js +5 -3
  528. package/utils/git.ts +1 -1
  529. package/utils/install-redirect.js +1 -1
  530. package/utils/kontainer.ts +186 -0
  531. package/utils/monitoring.js +2 -37
  532. package/utils/pagination-utils.ts +154 -0
  533. package/utils/pod-security-admission.ts +1 -1
  534. package/utils/router.js +86 -0
  535. package/utils/settings.ts +46 -0
  536. package/utils/socket.js +1 -0
  537. package/utils/time.js +1 -0
  538. package/utils/title.ts +3 -0
  539. package/utils/unit-tests/ChildRenderingRouterLinkStub.ts +36 -0
  540. package/utils/validators/formRules/__tests__/index.test.ts +21 -0
  541. package/utils/validators/formRules/index.ts +3 -0
  542. package/utils/validators/index.js +1 -0
  543. package/vue.config.js +376 -421
  544. package/assets/styles/vendor/vue-js-modal.scss +0 -16
  545. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  546. package/components/EventsTable.vue +0 -67
  547. package/components/TabbedLinks/index.vue +0 -94
  548. package/components/nuxt/nuxt-link.server.js +0 -16
  549. package/components/nuxt/nuxt.js +0 -101
  550. package/config/router.js +0 -425
  551. package/initialize/App.js +0 -152
  552. package/initialize/client.js +0 -734
  553. package/initialize/index.js +0 -287
  554. package/middleware/i18n.js +0 -10
  555. package/middleware/unauthenticated.js +0 -22
  556. package/mixins/v1-workload-metrics.js +0 -43
  557. package/pages/c/_cluster/apps/index.vue +0 -15
  558. package/pages/c/_cluster/auth/index.vue +0 -17
  559. package/pages/c/_cluster/index.vue +0 -15
  560. package/pages/c/_cluster/legacy/index.vue +0 -22
  561. package/pages/c/_cluster/manager/index.vue +0 -22
  562. package/pages/c/_cluster/mcapps/index.vue +0 -21
  563. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +0 -232
  564. package/plugins/dashboard-store/rehydrate-all.js +0 -44
  565. package/plugins/index.js +0 -11
  566. package/plugins/portal-vue.js +0 -4
  567. package/plugins/portal.js +0 -4
  568. package/plugins/resize.js +0 -5
  569. package/plugins/shortkey.js +0 -4
  570. package/plugins/tooltip.js +0 -4
  571. package/plugins/v-select.js +0 -4
  572. package/utils/group.js +0 -70
  573. package/utils/nuxt.js +0 -638
  574. package/utils/router.scrollBehavior.js +0 -78
  575. /package/components/__tests__/{Collapse.spec.ts → Collapse.test.ts} +0 -0
  576. /package/models/__tests__/{node.ts → node.test.ts} +0 -0
  577. /package/plugins/steve/__tests__/{header-warnings.spec.ts → header-warnings.test.ts} +0 -0
  578. /package/plugins/steve/__tests__/{steve-class.spec.ts → steve-class.test.ts} +0 -0
  579. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  580. /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  581. /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 {
@@ -148,8 +149,9 @@ import isObject from 'lodash/isObject';
148
149
  import { normalizeType } from '@shell/plugins/dashboard-store/normalize';
149
150
  import { sortBy } from '@shell/utils/sort';
150
151
 
151
- import { haveV1Monitoring, haveV2Monitoring } from '@shell/utils/monitoring';
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';
@@ -206,10 +208,7 @@ export const SPOOFED_API_PREFIX = '__[[spoofedapi]]__';
206
208
  const instanceMethods = {};
207
209
  const graphConfigMap = {};
208
210
 
209
- const FIELD_REGEX = /^\$\.metadata\.fields\[([0-9]*)\]/;
210
-
211
211
  export const IF_HAVE = {
212
- V1_MONITORING: 'v1-monitoring',
213
212
  V2_MONITORING: 'v2-monitoring',
214
213
  PROJECT: 'project',
215
214
  NO_PROJECT: 'no-project',
@@ -239,9 +238,14 @@ export function DSL(store, product, module = 'type-map') {
239
238
  ...inOpt
240
239
  };
241
240
 
241
+ // Convert strings to regex's - we do this once here for efficiency
242
242
  for ( const k of ['ifHaveGroup', 'ifHaveType'] ) {
243
243
  if ( opt[k] ) {
244
- 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
+ }
245
249
  }
246
250
  }
247
251
 
@@ -264,7 +268,7 @@ export function DSL(store, product, module = 'type-map') {
264
268
  store.commit(`${ module }/groupBy`, { type, field });
265
269
  },
266
270
 
267
- headers(type, headers) {
271
+ headers(type, headers, paginationHeaders = []) {
268
272
  headers.forEach((header) => {
269
273
  // If on the client, then use the value getter if there is one
270
274
  if (header.getValue) {
@@ -277,6 +281,7 @@ export function DSL(store, product, module = 'type-map') {
277
281
  });
278
282
 
279
283
  store.commit(`${ module }/headers`, { type, headers });
284
+ store.commit(`${ module }/paginationHeaders`, { type, paginationHeaders });
280
285
  },
281
286
 
282
287
  hideBulkActions(type, field) {
@@ -406,6 +411,7 @@ export const state = function() {
406
411
  typeOptions: [],
407
412
  groupBy: {},
408
413
  headers: {},
414
+ paginationHeaders: {},
409
415
  hideBulkActions: {},
410
416
  schemaGeneration: 1,
411
417
  cache: {
@@ -434,6 +440,7 @@ export const getters = {
434
440
  labelFor(state, getters, rootState, rootGetters) {
435
441
  return (schema, count = 1, language = null) => {
436
442
  return _applyMapping(schema, state.typeMappings, 'id', false, () => {
443
+ // i18n-uses typeLabel.*
437
444
  const key = `typeLabel."${ schema.id.toLowerCase() }"`;
438
445
 
439
446
  if ( rootGetters['i18n/exists'](key, language) ) {
@@ -501,22 +508,26 @@ export const getters = {
501
508
  };
502
509
  },
503
510
 
504
- optionsFor(state) {
511
+ optionsFor(state, getters, rootState, rootGetters) {
505
512
  const def = {
506
- isCreatable: true,
507
- isEditable: true,
508
- isRemovable: true,
509
- showState: true,
510
- showAge: true,
511
- canYaml: true,
512
- namespaced: null,
513
- listGroups: [],
514
- depaginate: false,
515
- customRoute: undefined,
516
- 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,
517
526
  };
518
527
 
519
- return (schemaOrType) => {
528
+ return (schemaOrType, pagination) => {
529
+ // Note - This can run a LOT so needs to be performant
530
+
520
531
  if (!schemaOrType) {
521
532
  return {};
522
533
  }
@@ -530,7 +541,20 @@ export const getters = {
530
541
 
531
542
  const opts = Object.assign({}, def, found || {});
532
543
 
533
- 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
+ };
534
558
  };
535
559
  },
536
560
 
@@ -626,7 +650,7 @@ export const getters = {
626
650
  continue;
627
651
  } else if ( mode === TYPE_MODES.USED && count <= 0 ) {
628
652
  // If there's none of this type, ignore this entry when viewing only in-use types
629
- // Note: count is sometimes null, which is <= 0.
653
+ // Note: count is sometimes null, in js `null <= 0` is `true`.
630
654
  continue;
631
655
  }
632
656
 
@@ -678,13 +702,14 @@ export const getters = {
678
702
  group.children.push({
679
703
  label,
680
704
  labelDisplay,
681
- mode: typeObj.mode,
682
- exact: typeObj.exact || false,
705
+ mode: typeObj.mode,
706
+ exact: typeObj.exact || false,
707
+ 'exact-path': typeObj['exact-path'] || false,
683
708
  namespaced,
684
709
  route,
685
- name: typeObj.name,
686
- weight: typeObj.weight || getters.typeWeightFor(typeObj.schema?.id || label, isBasic),
687
- overview: !!typeObj.overview,
710
+ name: typeObj.name,
711
+ weight: typeObj.weight || getters.typeWeightFor(typeObj.schema?.id || label, isBasic),
712
+ overview: !!typeObj.overview,
688
713
  });
689
714
  }
690
715
 
@@ -708,6 +733,7 @@ export const getters = {
708
733
 
709
734
  // Translate if an entry exists
710
735
  let label = name;
736
+ // i18n-uses nav.group.*
711
737
  const key = `nav.group."${ name }"`;
712
738
 
713
739
  if ( rootGetters['i18n/exists'](key) ) {
@@ -938,11 +964,11 @@ export const getters = {
938
964
  const virtualTypes = state.virtualTypes[product] || [];
939
965
  const spoofedTypes = state.spoofedTypes[product] || [];
940
966
  const allTypes = [...virtualTypes, ...spoofedTypes];
941
- const virtSpoofedModes = [...nonUsedModes];
942
967
 
943
968
  for ( const type of allTypes ) {
944
969
  const item = clone(type);
945
970
  const id = item.name;
971
+ const virtSpoofedModes = [...nonUsedModes];
946
972
 
947
973
  // Is there a virtual/spoofed type override for schema type?
948
974
  // Currently used by harvester, this should be investigated and removed if possible
@@ -961,16 +987,29 @@ export const getters = {
961
987
  }
962
988
 
963
989
  if ( item.ifHaveType ) {
964
- const targetedSchemas = typeof item.ifHaveType === 'string' ? schemas : rootGetters[`${ item.ifHaveType.store }/all`](SCHEMA);
965
- 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;
966
992
 
967
- 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;
968
998
 
969
- if (!haveIds.length) {
970
- 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
+ }
971
1010
  }
972
1011
 
973
- if (item.ifHaveVerb && !ifHaveVerb(rootGetters, module, item.ifHaveVerb, haveIds)) {
1012
+ if (!satisfiesIfHave) {
974
1013
  continue;
975
1014
  }
976
1015
  }
@@ -989,8 +1028,18 @@ export const getters = {
989
1028
  continue;
990
1029
  }
991
1030
 
992
- if (item.ifFeature && !rootGetters['features/get'](item.ifFeature)) {
993
- 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
+ }
994
1043
  }
995
1044
 
996
1045
  if (virtSpoofedModes.includes(TYPE_MODES.BASIC) && !getters.groupForBasicType(product, id) ) {
@@ -1041,99 +1090,46 @@ export const getters = {
1041
1090
  },
1042
1091
 
1043
1092
  headersFor(state, getters, rootState, rootGetters) {
1044
- return (schema) => {
1045
- const attributes = schema.attributes || {};
1046
- const columns = attributes.columns || [];
1047
- const typeOptions = getters['optionsFor'](schema);
1048
-
1049
- // A specific list has been provided
1050
- if ( state.headers[schema.id] ) {
1051
- return state.headers[schema.id].map((entry) => {
1052
- if ( typeof entry === 'string' ) {
1053
- const col = findBy(columns, 'name', entry);
1054
-
1055
- if ( col ) {
1056
- return fromSchema(col, rootGetters);
1057
- } else {
1058
- return null;
1059
- }
1060
- } else {
1061
- return entry;
1062
- }
1063
- }).filter((col) => !!col);
1064
- }
1093
+ return (schema, pagination) => {
1094
+ if (pagination) {
1095
+ const storeHeadersFor = schema?.$ctx?.getters?.['headersFor'];
1065
1096
 
1066
- // Otherwise make one up from schema
1067
- const out = typeOptions.showState ? [STATE] : [];
1068
- const namespaced = attributes.namespaced || false;
1069
- let hasName = false;
1070
-
1071
- for ( const col of columns ) {
1072
- if ( col.format === 'name' ) {
1073
- hasName = true;
1074
- out.push(NAME);
1075
- if ( namespaced ) {
1076
- out.push(NAMESPACE_COL);
1077
- }
1078
- } else {
1079
- out.push(fromSchema(col, rootGetters));
1080
- }
1081
- }
1097
+ if (storeHeadersFor) {
1098
+ const res = storeHeadersFor({ getters, state }, { schema, pagination });
1082
1099
 
1083
- if ( !hasName ) {
1084
- insertAt(out, 1, NAME);
1085
- if ( namespaced ) {
1086
- insertAt(out, 2, NAMESPACE_COL);
1087
- }
1088
- }
1089
-
1090
- // Age always goes last
1091
- if ( out.includes(AGE) ) {
1092
- removeObject(out, AGE);
1093
- if ( typeOptions.showAge ) {
1094
- out.push(AGE);
1100
+ if (res) {
1101
+ return res;
1102
+ }
1095
1103
  }
1096
1104
  }
1097
1105
 
1098
- return out;
1099
-
1100
- function fromSchema(col, rootGetters) {
1101
- let formatter, width, formatterOpts;
1102
-
1103
- if ( (col.format === '' || col.format === 'date') && col.name === 'Age' ) {
1104
- return AGE;
1105
- }
1106
-
1107
- if ( col.format === 'date' || col.type === 'date' ) {
1108
- formatter = 'Date';
1109
- width = 120;
1110
- formatterOpts = { multiline: true };
1111
- }
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
+ },
1112
1120
 
1113
- if ( col.type === 'number' || col.type === 'int' ) {
1114
- formatter = 'Number';
1115
- }
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
+ },
1116
1127
 
1117
- const colName = col.name.includes(' ') ? col.name.split(' ').map((word) => word.charAt(0).toUpperCase() + word.substring(1) ).join('') : col.name;
1118
-
1119
- const exists = rootGetters['i18n/exists'];
1120
- const t = rootGetters['i18n/t'];
1121
- const labelKey = `tableHeaders.${ colName.charAt(0).toLowerCase() + colName.slice(1) }`;
1122
- const description = col.description || '';
1123
- const tooltip = description && description[description.length - 1] === '.' ? description.slice(0, -1) : description;
1124
-
1125
- return {
1126
- name: col.name.toLowerCase(),
1127
- label: exists(labelKey) ? t(labelKey) : col.name,
1128
- value: _rowValueGetter(col),
1129
- sort: [col.field],
1130
- formatter,
1131
- formatterOpts,
1132
- width,
1133
- tooltip
1134
- };
1135
- }
1136
- };
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];
1137
1133
  },
1138
1134
 
1139
1135
  // ------------------------------------
@@ -1443,7 +1439,7 @@ export const getters = {
1443
1439
  return (schema, colName) => {
1444
1440
  const col = _findColumnByName(schema, colName);
1445
1441
 
1446
- return _rowValueGetter(col);
1442
+ return rowValueGetter(col);
1447
1443
  };
1448
1444
  },
1449
1445
 
@@ -1454,6 +1450,10 @@ export const getters = {
1454
1450
  return !!prod;
1455
1451
  };
1456
1452
  },
1453
+
1454
+ productByName(state) {
1455
+ return (productName) => state.products.find((p) => p.name === productName);
1456
+ }
1457
1457
  };
1458
1458
 
1459
1459
  export const mutations = {
@@ -1513,12 +1513,27 @@ export const mutations = {
1513
1513
  },
1514
1514
 
1515
1515
  product(state, obj) {
1516
- const existing = findBy(state.products, 'name', obj.name);
1516
+ let existing = state.products.find((p) => p.name === obj.name);
1517
1517
 
1518
1518
  if ( existing ) {
1519
1519
  Object.assign(existing, obj);
1520
1520
  } else {
1521
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);
1522
1537
  }
1523
1538
  },
1524
1539
 
@@ -1614,6 +1629,10 @@ export const mutations = {
1614
1629
  state.headers[type] = headers;
1615
1630
  },
1616
1631
 
1632
+ paginationHeaders(state, { type, paginationHeaders }) {
1633
+ state.paginationHeaders[type] = paginationHeaders;
1634
+ },
1635
+
1617
1636
  hideBulkActions(state, { type, field }) {
1618
1637
  state.hideBulkActions[type] = field;
1619
1638
  },
@@ -1863,9 +1882,6 @@ function ifHave(getters, option) {
1863
1882
  case IF_HAVE.V2_MONITORING: {
1864
1883
  return haveV2Monitoring(getters);
1865
1884
  }
1866
- case IF_HAVE.V1_MONITORING: {
1867
- return haveV1Monitoring(getters);
1868
- }
1869
1885
  case IF_HAVE.PROJECT: {
1870
1886
  return !!project(getters);
1871
1887
  }
@@ -1913,22 +1929,6 @@ function _findColumnByName(schema, colName) {
1913
1929
  return findBy(columns, 'name', colName);
1914
1930
  }
1915
1931
 
1916
- function _rowValueGetter(col) {
1917
- // 'field' comes from the schema - typically it is of the form $.metadata.field[N]
1918
- // We will use JsonPath to look up this value, which is costly - so if we can detect this format
1919
- // Use a more efficient function to get the value
1920
- const value = col.field.startsWith('.') ? `$${ col.field }` : col.field;
1921
- const found = value.match(FIELD_REGEX);
1922
-
1923
- if (found && found.length === 2) {
1924
- const fieldIndex = parseInt(found[1], 10);
1925
-
1926
- return (row) => row.metadata?.fields?.[fieldIndex];
1927
- }
1928
-
1929
- return value;
1930
- }
1931
-
1932
1932
  // Is V1 Istio installed?
1933
1933
  function isV1Istio(getters) {
1934
1934
  const cluster = getters['currentCluster'];