@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
@@ -13,7 +13,7 @@ import {
13
13
  import { sortBy } from '@shell/utils/sort';
14
14
  import { ucFirst } from '@shell/utils/string';
15
15
 
16
- import { HCI, CATALOG, UI, SCHEMA } from '@shell/config/types';
16
+ import { HCI, UI, SCHEMA } from '@shell/config/types';
17
17
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
18
18
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
19
19
  import { TYPE_MODES } from '@shell/store/type-map';
@@ -74,13 +74,6 @@ export default {
74
74
  }
75
75
  },
76
76
 
77
- productId(a, b) {
78
- if ( a !== b) {
79
- // Immediately update because you'll see it come in later
80
- this.getGroups();
81
- }
82
- },
83
-
84
77
  // Queue namespaceMode and namespaces
85
78
  // Changes to namespaceMode can also change namespaces, so keep this simple and execute both in a shortened queue
86
79
 
@@ -103,6 +96,13 @@ export default {
103
96
  }
104
97
  },
105
98
 
99
+ rootProduct(a, b) {
100
+ if (a?.name !== b?.name) {
101
+ // Immediately update because you'll see it come in later
102
+ this.getGroups();
103
+ }
104
+ },
105
+
106
106
  $route(a, b) {
107
107
  this.$nextTick(() => this.syncNav());
108
108
  },
@@ -111,20 +111,14 @@ export default {
111
111
 
112
112
  computed: {
113
113
  ...mapState(['managementReady', 'clusterReady']),
114
- ...mapGetters(['productId', 'clusterId', 'currentProduct', 'isSingleProduct', 'namespaceMode', 'isExplorer', 'isVirtualCluster']),
114
+ ...mapGetters(['productId', 'clusterId', 'currentProduct', 'rootProduct', 'isSingleProduct', 'namespaceMode', 'isExplorer', 'isVirtualCluster']),
115
115
  ...mapGetters({ locale: 'i18n/selectedLocaleLabel', availableLocales: 'i18n/availableLocales' }),
116
116
  ...mapGetters('type-map', ['activeProducts']),
117
117
 
118
118
  favoriteTypes: mapPref(FAVORITE_TYPES),
119
119
 
120
- showClusterTools() {
121
- return this.isExplorer &&
122
- this.$store.getters['cluster/canList'](CATALOG.CLUSTER_REPO) &&
123
- this.$store.getters['cluster/canList'](CATALOG.APP);
124
- },
125
-
126
120
  supportLink() {
127
- const product = this.currentProduct;
121
+ const product = this.rootProduct;
128
122
 
129
123
  if (product?.supportRoute) {
130
124
  return { ...product.supportRoute, params: { ...product.supportRoute.params, cluster: this.clusterId } };
@@ -159,7 +153,7 @@ export default {
159
153
  },
160
154
 
161
155
  isVirtualProduct() {
162
- return this.currentProduct.name === HARVESTER;
156
+ return this.rootProduct.name === HARVESTER;
163
157
  },
164
158
 
165
159
  allNavLinks() {
@@ -420,33 +414,18 @@ export default {
420
414
  />
421
415
  </template>
422
416
  </div>
423
- <!-- Cluster tools -->
424
- <n-link
425
- v-if="showClusterTools"
426
- tag="div"
427
- class="tools"
428
- :to="{name: 'c-cluster-explorer-tools', params: {cluster: clusterId}}"
429
- >
430
- <a
431
- class="tools-button"
432
- @click="collapseAll()"
433
- >
434
- <i class="icon icon-gear" />
435
- <span>{{ t('nav.clusterTools') }}</span>
436
- </a>
437
- </n-link>
438
417
  <!-- SideNav footer area (seems to be tied to harvester) -->
439
418
  <div
440
419
  v-if="showProductFooter"
441
420
  class="footer"
442
421
  >
443
422
  <!-- support link -->
444
- <nuxt-link
423
+ <router-link
445
424
  :to="supportLink"
446
425
  class="pull-right"
447
426
  >
448
427
  {{ t('nav.support', {hasSupport: true}) }}
449
- </nuxt-link>
428
+ </router-link>
450
429
  <!-- version number -->
451
430
  <span
452
431
  v-clean-tooltip="{content: displayVersion, placement: 'top'}"
@@ -492,14 +471,13 @@ export default {
492
471
  v-else
493
472
  class="version text-muted flex"
494
473
  >
495
- <nuxt-link
474
+ <router-link
496
475
  v-if="singleProductAbout"
497
476
  :to="singleProductAbout"
498
477
  >
499
478
  {{ displayVersion }}
500
- </nuxt-link>
479
+ </router-link>
501
480
  <template v-else>
502
- <span>{{ displayVersion }}</span>
503
481
  <span
504
482
  v-if="isVirtualCluster && isExplorer"
505
483
  v-tooltip="{content: harvesterVersion, placement: 'top'}"
@@ -133,23 +133,23 @@ export default {
133
133
  {{ t('generic.links') }}
134
134
  </div>
135
135
  <div class="glance-item">
136
- <nuxt-link
136
+ <router-link
137
137
  :to="exploreLink"
138
138
  class="cluster-link"
139
139
  >
140
140
  {{ t('nav.categories.explore') }}
141
- </nuxt-link>
141
+ </router-link>
142
142
  </div>
143
143
  <div
144
144
  v-if="showClusterTools"
145
145
  class="glance-item"
146
146
  >
147
- <nuxt-link
147
+ <router-link
148
148
  :to="clusterToolsLink"
149
149
  class="cluster-link"
150
150
  >
151
151
  {{ t('nav.clusterTools') }}
152
- </nuxt-link>
152
+ </router-link>
153
153
  </div>
154
154
  </div>
155
155
  </div>
@@ -136,6 +136,9 @@ export default {
136
136
  isIndeterminate() {
137
137
  return this.howMuchSelected === SOME;
138
138
  },
139
+ hasColumnWithSubLabel() {
140
+ return this.columns.some((col) => col.subLabel);
141
+ }
139
142
  },
140
143
 
141
144
  methods: {
@@ -206,11 +209,10 @@ export default {
206
209
 
207
210
  <template>
208
211
  <thead>
209
- <tr :class="{'loading': loading}">
212
+ <tr :class="{'loading': loading, 'top-aligned': hasColumnWithSubLabel}">
210
213
  <th
211
214
  v-if="tableActions"
212
215
  :width="checkWidth"
213
- align="middle"
214
216
  >
215
217
  <Checkbox
216
218
  v-model="isAll"
@@ -237,11 +239,22 @@ export default {
237
239
  class="table-header-container"
238
240
  :class="{ 'not-filterable': hasAdvancedFiltering && !col.isFilter }"
239
241
  >
240
- <span
241
- v-if="col.sort"
242
+ <div
242
243
  v-clean-tooltip="tooltip(col)"
244
+ class="content"
243
245
  >
244
246
  <span v-clean-html="labelFor(col)" />
247
+ <span
248
+ v-if="col.subLabel"
249
+ class="text-muted"
250
+ >
251
+ {{ col.subLabel }}
252
+ </span>
253
+ </div>
254
+ <div
255
+ v-if="col.sort"
256
+ class="sort"
257
+ >
245
258
  <i
246
259
  v-show="hasAdvancedFiltering && !col.isFilter"
247
260
  v-clean-tooltip="t('sortableTable.tableHeader.noFilter')"
@@ -258,11 +271,7 @@ export default {
258
271
  class="icon icon-sort-up icon-stack-1x"
259
272
  />
260
273
  </span>
261
- </span>
262
- <span
263
- v-else
264
- v-clean-tooltip="tooltip(col)"
265
- >{{ labelFor(col) }}</span>
274
+ </div>
266
275
  </div>
267
276
  </th>
268
277
  <th
@@ -394,6 +403,11 @@ export default {
394
403
  }
395
404
  }
396
405
 
406
+ .top-aligned th {
407
+ vertical-align: top;
408
+ padding-top: 10px;
409
+ }
410
+
397
411
  thead {
398
412
  tr {
399
413
  background-color: var(--sortable-table-header-bg);
@@ -413,11 +427,11 @@ export default {
413
427
  color: var(--body-text);
414
428
 
415
429
  .table-header-container {
416
- display: inherit;
430
+ display: flex;
417
431
 
418
- > span {
432
+ .content {
419
433
  display: flex;
420
- align-items: center;
434
+ flex-direction: column;
421
435
  }
422
436
 
423
437
  &.not-filterable {
@@ -33,6 +33,10 @@ export default {
33
33
  }),
34
34
  */
35
35
  filteredRows() {
36
+ if (this.externalPaginationEnabled) {
37
+ return;
38
+ }
39
+
36
40
  // PROP hasAdvancedFiltering comes from Advanced Filtering mixin (careful changing data var there...)
37
41
  if (!this.hasAdvancedFiltering) {
38
42
  return this.handleFiltering();
@@ -162,7 +166,11 @@ export default {
162
166
  arrangedRows(q) {
163
167
  // The rows changed so the old filter result is no longer useful
164
168
  this.previousResult = null;
165
- }
169
+ },
170
+
171
+ searchQuery() {
172
+ this.debouncedPaginationChanged();
173
+ },
166
174
  },
167
175
  };
168
176
 
@@ -2,9 +2,16 @@ import { get } from '@shell/utils/object';
2
2
 
3
3
  export default {
4
4
  computed: {
5
+ /**
6
+ * The group config associated with the selected group
7
+ */
8
+ selectedGroupOption() {
9
+ return this.groupOptions?.find((go) => go.value === this.group);
10
+ },
11
+
5
12
  groupedRows() {
6
13
  const groupKey = this.groupBy;
7
- const refKey = this.groupRef || groupKey;
14
+ const refKey = this.groupRef || this.selectedGroupOption?.groupLabelKey || groupKey;
8
15
 
9
16
  if ( !groupKey) {
10
17
  return [{
@@ -29,30 +29,17 @@ import { getParent } from '@shell/utils/dom';
29
29
  // NOTE: This is populated by a plugin (formatters.js) to avoid issues with plugins
30
30
  export const FORMATTERS = {};
31
31
 
32
- export const COLUMN_BREAKPOINTS = {
33
- /**
34
- * Only show column if at tablet width or wider
35
- */
36
- TABLET: 'tablet',
37
- /**
38
- * Only show column if at laptop width or wider
39
- */
40
- LAPTOP: 'laptop',
41
- /**
42
- * Only show column if at desktop width or wider
43
- */
44
- DESKTOP: 'desktop'
45
- };
46
-
47
32
  // @TODO:
48
33
  // Fixed header/scrolling
49
34
 
50
35
  // Data Flow:
51
36
  // rows prop
52
- // -> arrangedRows (sorting.js)
53
- // -> filteredRows (filtering.js)
54
- // -> pagedRows (paging.js)
55
- // -> groupedRows (grouping.js)
37
+ // --> sorting.js arrangedRows
38
+ // --> filtering.js handleFiltering()
39
+ // --> filtering.js filteredRows
40
+ // --> paging.js pageRows
41
+ // --> grouping.js groupedRows
42
+ // --> index.vue displayedRows
56
43
 
57
44
  export default {
58
45
  name: 'SortableTable',
@@ -100,6 +87,16 @@ export default {
100
87
  required: false
101
88
  },
102
89
 
90
+ /**
91
+ * Alt Loading - True: Always show table rows and obscure them when `loading`. Intended for use with server-side pagination.
92
+ *
93
+ * Alt Loading - False: Hide the table rows when `loading`. Intended when all resources are provided up front.
94
+ */
95
+ altLoading: {
96
+ type: Boolean,
97
+ required: false
98
+ },
99
+
103
100
  groupBy: {
104
101
  // Field to group rows by, row[groupBy] must be something that can be a map key
105
102
  type: String,
@@ -164,6 +161,11 @@ export default {
164
161
  default: false,
165
162
  },
166
163
 
164
+ subRowsDescription: {
165
+ type: Boolean,
166
+ default: true,
167
+ },
168
+
167
169
  subExpandable: {
168
170
  type: Boolean,
169
171
  default: false,
@@ -266,7 +268,7 @@ export default {
266
268
  */
267
269
  noDataKey: {
268
270
  type: String,
269
- default: 'sortableTable.noData'
271
+ default: 'sortableTable.noData' // i18n-uses sortableTable.noData
270
272
  },
271
273
 
272
274
  /**
@@ -282,6 +284,14 @@ export default {
282
284
  default: null,
283
285
  },
284
286
 
287
+ /**
288
+ * The list will always be sorted by these regardless of what the user has selected
289
+ */
290
+ mandatorySort: {
291
+ type: Array,
292
+ default: null,
293
+ },
294
+
285
295
  /**
286
296
  * Allows you to link to a custom detail page for data that
287
297
  * doesn't have a class model. For example, a receiver configuration
@@ -313,6 +323,22 @@ export default {
313
323
  forceUpdateLiveAndDelayed: {
314
324
  type: Number,
315
325
  default: 0
326
+ },
327
+
328
+ /**
329
+ * True if pagination is executed outside of the component
330
+ */
331
+ externalPaginationEnabled: {
332
+ type: Boolean,
333
+ default: false
334
+ },
335
+
336
+ /**
337
+ * If `externalPaginationEnabled` is true this will be used as the current page
338
+ */
339
+ externalPaginationResult: {
340
+ type: Object,
341
+ default: null
316
342
  }
317
343
  },
318
344
 
@@ -327,12 +353,18 @@ export default {
327
353
  }
328
354
 
329
355
  return {
330
- currentPhase: ASYNC_BUTTON_STATES.WAITING,
331
- expanded: {},
356
+ refreshButtonPhase: ASYNC_BUTTON_STATES.WAITING,
357
+ expanded: {},
332
358
  searchQuery,
333
359
  eventualSearchQuery,
334
- actionOfInterest: null,
335
- loadingDelay: false,
360
+ subMatches: null,
361
+ actionOfInterest: null,
362
+ loadingDelay: false,
363
+ debouncedPaginationChanged: null,
364
+ /**
365
+ * The is the bool the DOM uses to show loading state. it's proxied from `loading` to avoid blipping the indicator (see usages)
366
+ */
367
+ isLoading: false,
336
368
  };
337
369
  },
338
370
 
@@ -346,12 +378,14 @@ export default {
346
378
 
347
379
  this._onScroll = this.onScroll.bind(this);
348
380
  $main?.addEventListener('scroll', this._onScroll);
381
+
382
+ this.debouncedPaginationChanged();
349
383
  },
350
384
 
351
385
  beforeDestroy() {
352
- clearTimeout(this.loadingDelayTimer);
353
386
  clearTimeout(this._scrollTimer);
354
387
  clearTimeout(this._loadingDelayTimer);
388
+ clearTimeout(this._altLoadingDelayTimer);
355
389
  clearTimeout(this._liveColumnsTimer);
356
390
  clearTimeout(this._delayedColumnsTimer);
357
391
  clearTimeout(this.manualRefreshTimer);
@@ -383,21 +417,27 @@ export default {
383
417
  descending(neu, old) {
384
418
  this.watcherUpdateLiveAndDelayed(neu, old);
385
419
  },
420
+
386
421
  searchQuery(neu, old) {
387
422
  this.watcherUpdateLiveAndDelayed(neu, old);
388
423
  },
424
+
389
425
  sortFields(neu, old) {
390
426
  this.watcherUpdateLiveAndDelayed(neu, old);
391
427
  },
428
+
392
429
  groupBy(neu, old) {
393
430
  this.watcherUpdateLiveAndDelayed(neu, old);
394
431
  },
432
+
395
433
  namespaces(neu, old) {
396
434
  this.watcherUpdateLiveAndDelayed(neu, old);
397
435
  },
436
+
398
437
  page(neu, old) {
399
438
  this.watcherUpdateLiveAndDelayed(neu, old);
400
439
  },
440
+
401
441
  forceUpdateLiveAndDelayed(neu, old) {
402
442
  this.watcherUpdateLiveAndDelayed(neu, old);
403
443
  },
@@ -418,17 +458,40 @@ export default {
418
458
  manualRefreshLoadingFinished: {
419
459
  handler(neu, old) {
420
460
  // this is merely to update the manual refresh button status
421
- this.currentPhase = !neu ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION;
461
+ this.refreshButtonPhase = !neu ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION;
422
462
  if (neu && neu !== old) {
423
463
  this.$nextTick(() => this.updateLiveAndDelayed());
424
464
  }
425
465
  },
426
466
  immediate: true
427
- }
467
+ },
468
+
469
+ loading: {
470
+ handler(neu, old) {
471
+ // Always ensure the Refresh button phase aligns with loading state (to ensure external phase changes which can then reset the internal phase changed by click)
472
+ this.refreshButtonPhase = neu ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION;
473
+
474
+ if (this.altLoading) {
475
+ // Delay setting the actual loading indicator. This should avoid flashing up the indicator if the API responds quickly
476
+ if (neu) {
477
+ this._altLoadingDelayTimer = setTimeout(() => {
478
+ this.isLoading = true;
479
+ }, 200); // this should be higher than the targetted quick response
480
+ } else {
481
+ clearTimeout(this._altLoadingDelayTimer);
482
+ this.isLoading = false;
483
+ }
484
+ } else {
485
+ this.isLoading = neu;
486
+ }
487
+ },
488
+ immediate: true
489
+ },
428
490
  },
429
491
 
430
492
  created() {
431
493
  this.debouncedRefreshTableData = debounce(this.refreshTableData, 500);
494
+ this.debouncedPaginationChanged = debounce(this.paginationChanged, 50);
432
495
  },
433
496
 
434
497
  computed: {
@@ -439,11 +502,16 @@ export default {
439
502
  },
440
503
 
441
504
  initalLoad() {
442
- return !!(!this.loading && !this._didinit && this.rows?.length);
505
+ return !!(!this.isLoading && !this._didinit && this.rows?.length);
443
506
  },
444
507
 
445
508
  manualRefreshLoadingFinished() {
446
- return !!(!this.loading && this._didinit && this.rows?.length && !this.isManualRefreshLoading);
509
+ const res = !!(!this.isLoading && this._didinit && this.rows?.length && !this.isManualRefreshLoading);
510
+
511
+ // Always ensure the Refresh button phase aligns with loading state (regardless of if manualRefreshLoadingFinished has changed or not)
512
+ this.refreshButtonPhase = !res || this.loading ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION;
513
+
514
+ return res;
447
515
  },
448
516
 
449
517
  fullColspan() {
@@ -543,6 +611,7 @@ export default {
543
611
  'body-dividers': this.bodyDividers,
544
612
  'overflow-y': this.overflowY,
545
613
  'overflow-x': this.overflowX,
614
+ 'alt-loading': this.altLoading && this.isLoading
546
615
  };
547
616
  },
548
617
 
@@ -771,6 +840,12 @@ export default {
771
840
  // console.warn(`Performance: Table valueFor: ${ col.name } ${ col.value }`); // eslint-disable-line no-console
772
841
 
773
842
  const expr = col.value || col.name;
843
+
844
+ if (!expr) {
845
+ console.error('No path has been defined for this column, unable to get value of cell', col); // eslint-disable-line no-console
846
+
847
+ return '';
848
+ }
774
849
  const out = get(row, expr);
775
850
 
776
851
  if ( out === null || out === undefined ) {
@@ -879,7 +954,7 @@ export default {
879
954
 
880
955
  showSubRow(row, keyField) {
881
956
  const hasInjectedSubRows = this.subRows && (!this.subExpandable || this.expanded[get(row, keyField)]);
882
- const hasStateDescription = row.stateDescription;
957
+ const hasStateDescription = this.subRowsDescription && row.stateDescription;
883
958
 
884
959
  return hasInjectedSubRows || hasStateDescription;
885
960
  },
@@ -898,6 +973,23 @@ export default {
898
973
  event,
899
974
  targetElement: this.$refs[`actionButton${ i }`][0],
900
975
  });
976
+ },
977
+
978
+ paginationChanged() {
979
+ if (!this.externalPaginationEnabled) {
980
+ return;
981
+ }
982
+
983
+ this.$emit('pagination-changed', {
984
+ page: this.page,
985
+ perPage: this.perPage,
986
+ filter: {
987
+ searchFields: this.searchFields,
988
+ searchQuery: this.searchQuery
989
+ },
990
+ sort: this.sortFields,
991
+ descending: this.descending
992
+ });
901
993
  }
902
994
  }
903
995
  };
@@ -1028,7 +1120,7 @@ export default {
1028
1120
  v-if="isTooManyItemsToAutoUpdate"
1029
1121
  class="manual-refresh"
1030
1122
  mode="manual-refresh"
1031
- :current-phase="currentPhase"
1123
+ :current-phase="refreshButtonPhase"
1032
1124
  @click="debouncedRefreshTableData"
1033
1125
  />
1034
1126
  <div
@@ -1121,7 +1213,7 @@ export default {
1121
1213
  :default-sort-by="_defaultSortBy"
1122
1214
  :descending="descending"
1123
1215
  :no-rows="noRows"
1124
- :loading="loading && !loadingDelay"
1216
+ :loading="isLoading && !loadingDelay"
1125
1217
  :no-results="noResults"
1126
1218
  @on-toggle-all="onToggleAll"
1127
1219
  @on-sort-change="changeSort"
@@ -1131,9 +1223,9 @@ export default {
1131
1223
  />
1132
1224
 
1133
1225
  <!-- Don't display anything if we're loading and the delay has yet to pass -->
1134
- <div v-if="loading && !loadingDelay" />
1226
+ <div v-if="isLoading && !loadingDelay" />
1135
1227
 
1136
- <tbody v-else-if="loading">
1228
+ <tbody v-else-if="isLoading && !altLoading">
1137
1229
  <slot name="loading">
1138
1230
  <tr>
1139
1231
  <td :colspan="fullColspan">
@@ -1378,7 +1470,8 @@ export default {
1378
1470
  <button
1379
1471
  type="button"
1380
1472
  class="btn btn-sm role-multi-action"
1381
- :disabled="page == 1"
1473
+ data-testid="pagination-first"
1474
+ :disabled="page == 1 || loading"
1382
1475
  @click="goToPage('first')"
1383
1476
  >
1384
1477
  <i class="icon icon-chevron-beginning" />
@@ -1386,7 +1479,8 @@ export default {
1386
1479
  <button
1387
1480
  type="button"
1388
1481
  class="btn btn-sm role-multi-action"
1389
- :disabled="page == 1"
1482
+ data-testid="pagination-prev"
1483
+ :disabled="page == 1 || loading"
1390
1484
  @click="goToPage('prev')"
1391
1485
  >
1392
1486
  <i class="icon icon-chevron-left" />
@@ -1397,7 +1491,8 @@ export default {
1397
1491
  <button
1398
1492
  type="button"
1399
1493
  class="btn btn-sm role-multi-action"
1400
- :disabled="page == totalPages"
1494
+ data-testid="pagination-next"
1495
+ :disabled="page == totalPages || loading"
1401
1496
  @click="goToPage('next')"
1402
1497
  >
1403
1498
  <i class="icon icon-chevron-right" />
@@ -1405,7 +1500,8 @@ export default {
1405
1500
  <button
1406
1501
  type="button"
1407
1502
  class="btn btn-sm role-multi-action"
1408
- :disabled="page == totalPages"
1503
+ data-testid="pagination-last"
1504
+ :disabled="page == totalPages || loading"
1409
1505
  @click="goToPage('last')"
1410
1506
  >
1411
1507
  <i class="icon icon-chevron-end" />
@@ -1443,7 +1539,11 @@ export default {
1443
1539
  </div>
1444
1540
  </template>
1445
1541
 
1446
- <style lang="scss" scoped>
1542
+ <style lang="scss" scoped>
1543
+ .sortable-table.alt-loading {
1544
+ opacity: 0.5;
1545
+ pointer-events: none;
1546
+ }
1447
1547
 
1448
1548
  .manual-refresh {
1449
1549
  height: 40px;
@@ -1607,9 +1707,9 @@ export default {
1607
1707
  margin-left: 10px;
1608
1708
  min-width: 180px;
1609
1709
  }
1610
- </style>
1710
+ </style>
1611
1711
 
1612
- <style lang="scss">
1712
+ <style lang="scss">
1613
1713
  //
1614
1714
  // Important: Almost all selectors in here need to be ">"-ed together so they
1615
1715
  // apply only to the current table, not one nested inside another table.
@@ -1941,4 +2041,4 @@ export default {
1941
2041
  min-width: 200px;
1942
2042
  }
1943
2043
  }
1944
- </style>
2044
+ </style>