@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/plugins/i18n.js CHANGED
@@ -1,7 +1,9 @@
1
- import Vue from 'vue';
1
+ /* eslint-disable no-console */
2
2
  import { escapeHtml } from '../utils/string';
3
+ import Vue, { watchEffect, ref, h } from 'vue';
4
+ import { useStore } from '../composables/useStore';
3
5
 
4
- function stringFor(store, key, args, raw = false, escapehtml = true) {
6
+ export function stringFor(store, key, args, raw = false, escapehtml = true) {
5
7
  const translation = store.getters['i18n/t'](key, args);
6
8
 
7
9
  let out;
@@ -26,10 +28,6 @@ function stringFor(store, key, args, raw = false, escapehtml = true) {
26
28
  }
27
29
  }
28
30
 
29
- Vue.prototype.t = function(key, args, raw) {
30
- return stringFor(this.$store, key, args, raw);
31
- };
32
-
33
31
  function directive(el, binding, vnode /*, oldVnode */) {
34
32
  const { context } = vnode;
35
33
  const raw = binding.modifiers && binding.modifiers.raw === true;
@@ -43,6 +41,9 @@ function directive(el, binding, vnode /*, oldVnode */) {
43
41
  }
44
42
 
45
43
  export function directiveSsr(vnode, binding) {
44
+ // eslint-disable-next-line no-console
45
+ console.warn('Function `directiveSsr` is deprecated. Please install i18n as a vue plugin: `Vue.use(i18n)`');
46
+
46
47
  const { context } = vnode;
47
48
  const raw = binding.modifiers && binding.modifiers.raw === true;
48
49
  const str = stringFor(context.$store, binding.value, {}, raw);
@@ -54,54 +55,87 @@ export function directiveSsr(vnode, binding) {
54
55
  }
55
56
  }
56
57
 
57
- // InnerHTML: <some-tag v-t="'some.key'" />
58
- // As an attribute: <some-tag v-t:title="'some.key'" />
59
- Vue.directive('t', {
60
- bind() {
61
- directive(...arguments);
62
- },
63
-
64
- update() {
65
- directive(...arguments);
66
- },
67
- });
68
-
69
- // Basic (but you might want the directive above): <t k="some.key" />
70
- // With interpolation: <t k="some.key" count="1" :foo="bar" />
71
- Vue.component('t', {
72
- inheritAttrs: false,
73
- props: {
74
- k: {
75
- type: String,
76
- required: true,
77
- },
78
- raw: {
79
- type: Boolean,
80
- default: false,
81
- },
82
- tag: {
83
- type: [String, Object],
84
- default: 'span'
85
- },
86
- escapehtml: {
87
- type: Boolean,
88
- default: true,
89
- }
90
- },
91
-
92
- render(h) {
93
- const msg = stringFor(this.$store, this.k, this.$attrs, this.raw, this.escapehtml);
94
-
95
- if ( this.raw ) {
96
- return h(
97
- this.tag,
98
- { domProps: { innerHTML: msg } }
99
- );
100
- } else {
101
- return h(
102
- this.tag,
103
- [msg]
104
- );
58
+ const i18n = {
59
+ name: 'i18n',
60
+ install: (Vue, _options) => {
61
+ if (Vue.prototype.t && Vue.directive('t') && Vue.component('t')) {
62
+ // eslint-disable-next-line no-console
63
+ console.debug('Skipping i18n install. Directive, component, and option already exist.');
105
64
  }
106
- },
107
- });
65
+
66
+ Vue.prototype.t = function(key, args, raw) {
67
+ return stringFor(this.$store, key, args, raw);
68
+ };
69
+
70
+ // InnerHTML: <some-tag v-t="'some.key'" />
71
+ // As an attribute: <some-tag v-t:title="'some.key'" />
72
+ Vue.directive('t', {
73
+ bind() {
74
+ directive(...arguments);
75
+ },
76
+ update() {
77
+ directive(...arguments);
78
+ },
79
+ });
80
+
81
+ // Basic (but you might want the directive above): <t k="some.key" />
82
+ // With interpolation: <t k="some.key" count="1" :foo="bar" />
83
+ Vue.component('t', {
84
+ inheritAttrs: false,
85
+ props: {
86
+ k: {
87
+ type: String,
88
+ required: true,
89
+ },
90
+ raw: {
91
+ type: Boolean,
92
+ default: false,
93
+ },
94
+ tag: {
95
+ type: [String, Object],
96
+ default: 'span'
97
+ },
98
+ escapehtml: {
99
+ type: Boolean,
100
+ default: true,
101
+ }
102
+ },
103
+ setup(props, ctx) {
104
+ const msg = ref('');
105
+ const store = useStore();
106
+
107
+ // Update msg whenever k, $attrs, raw, or escapehtml changes
108
+ watchEffect(() => {
109
+ msg.value = stringFor(store, props.k, ctx.attrs, props.raw, props.escapehtml);
110
+ });
111
+
112
+ return { msg };
113
+ },
114
+ render() {
115
+ if (this.raw) {
116
+ return h(
117
+ this.tag,
118
+ { domProps: { innerHTML: this.msg } }
119
+ );
120
+ } else {
121
+ return h(
122
+ this.tag,
123
+ [this.msg]
124
+ );
125
+ }
126
+ }
127
+ });
128
+ }
129
+ };
130
+
131
+ export default i18n;
132
+
133
+ // This is being done for backwards compatibility with our extensions that have written tests and didn't properly make use of Vue.use() when importing and mocking translations
134
+ // Example failing test https://github.com/rancher/dashboard/actions/runs/8927503474/job/24521022320?pr=10923
135
+ const isThisFileBeingExecutedInATest = process.env.NODE_ENV === 'test';
136
+
137
+ if (isThisFileBeingExecutedInATest) {
138
+ // Go take a look at our jest.setup.js to see how we make use of Vue.use(i18n, ...)
139
+ console.warn('The implicit addition of i18n options has been deprecated in Rancher Shell and will be removed in a future version. Make sure to invoke `Vue.use(i18n)` to maintain compatibility.');
140
+ Vue.use(i18n);
141
+ }
@@ -1,22 +1,8 @@
1
1
  import Vue from 'vue';
2
+ import intNumberDirective from '@shell/directives/int-number';
2
3
 
3
- export default Vue.directive('intNumber', {
4
- inserted(el) {
5
- el.addEventListener('keypress', (e) => {
6
- e = e || window.event;
7
- const charcode = typeof e.charCode === 'number' ? e.charCode : e.keyCode;
8
- const inputChar = String.fromCharCode(charcode);
9
-
10
- // Allow digits, minus sign at the beginning, and Ctrl key combinations
11
- const re = /^-?\d*$/;
12
-
13
- if (!re.test(inputChar) && charcode > 9 && !e.ctrlKey) {
14
- if (e.preventDefault) {
15
- e.preventDefault();
16
- } else {
17
- e.returnValue = false;
18
- }
19
- }
20
- });
21
- }
22
- });
4
+ export default intNumberDirective;
5
+ /* eslint-disable-next-line no-console */
6
+ console.warn(`Importing intNumberDirective from plugins has been deprecated, use shell/directives/int-number.js instead.
7
+ Make sure to invoke it using Vue.directive('intNumber', intNumberDirective) to maintain compatibility.`);
8
+ Vue.directive('intNumber', intNumberDirective);
package/plugins/plugin.js CHANGED
@@ -32,7 +32,7 @@ export default async function(context) {
32
32
  // Fetch list of installed plugins from endpoint
33
33
  try {
34
34
  const res = await context.store.dispatch('management/request', {
35
- url: `${ UI_PLUGIN_BASE_URL }/index.json`,
35
+ url: `${ UI_PLUGIN_BASE_URL }`,
36
36
  method: 'GET',
37
37
  headers: { accept: 'application/json' },
38
38
  redirectUnauthorized: false,
@@ -68,10 +68,10 @@ export default async function(context) {
68
68
  const res = pluginLoads[name];
69
69
 
70
70
  if (res?.status === 'rejected') {
71
- console.error(`Failed to load plugin: ${ name }`); // eslint-disable-line no-console
71
+ console.error(`Failed to load plugin: ${ name }. `, res.reason || 'Unknown reason'); // eslint-disable-line no-console
72
72
 
73
73
  // Record error in the uiplugins store, so that we can show this to the user
74
- context.store.dispatch('uiplugins/setError', { name, error: 'plugins.error.load' });
74
+ context.store.dispatch('uiplugins/setError', { name, error: 'plugins.error.load' }); // i18n-uses plugins.error.load
75
75
  }
76
76
  });
77
77
  }
@@ -1,19 +1,8 @@
1
1
  import Vue from 'vue';
2
+ import positiveIntNumberDirective from '@shell/directives/positive-int-number';
2
3
 
3
- export default Vue.directive('positiveIntNumber', {
4
- inserted(el) {
5
- el.addEventListener('keypress', (e) => {
6
- e = e || window.event;
7
- const charcode = typeof e.charCode === 'number' ? e.charCode : e.keyCode;
8
- const re = /^\d+$/; // Use regex to match positive numbers
9
-
10
- if (!re.test(String.fromCharCode(charcode)) && charcode > 9 && !e.ctrlKey) {
11
- if (e.preventDefault) {
12
- e.preventDefault();
13
- } else {
14
- e.returnValue = false;
15
- }
16
- }
17
- });
18
- }
19
- });
4
+ export default positiveIntNumberDirective;
5
+ /* eslint-disable-next-line no-console */
6
+ console.warn(`Importing positiveIntNumberDirective from plugins has been deprecated, use shell/directives/positive-int-number.js instead.
7
+ Make sure to invoke it using Vue.directive('positiveIntNumber', positiveIntNumberDirective) to maintain compatibility.`);
8
+ Vue.directive('positiveIntNumber', positiveIntNumberDirective);
@@ -1,55 +1,77 @@
1
1
  import _getters from '@shell/plugins/steve/getters';
2
2
 
3
- const { urlFor, urlOptions } = _getters;
3
+ const { urlFor, urlOptions, pathExistsInSchema } = _getters;
4
4
 
5
- describe('steve: getters', () => {
6
- describe('steve > getters > urlFor', () => {
5
+ describe('steve: getters:', () => {
6
+ describe('urlFor', () => {
7
7
  // we're not testing function output based off of state or getter inputs here since they are dependencies
8
- const state = { config: { baseUrl: 'protocol' } };
8
+ const baseUrl = '/v1';
9
+ const collectionUrl = 'https://abc.com/v1/urlFoo';
10
+ const namespace = 'myNamespace';
11
+ const state = { config: { baseUrl } };
9
12
  const getters = {
10
- normalizeType: (type) => type,
11
- schemaFor: (type) => {
12
- if (type === 'typeFoo') {
13
- return { links: { collection: 'urlFoo' } };
13
+ normalizeType: (type: string) => type,
14
+ schemaFor: (type: string) => {
15
+ if (type === 'rType') {
16
+ return { links: { collection: collectionUrl } };
17
+ }
18
+ if (type === 'trailingforwardslash') {
19
+ return { links: { collection: `${ collectionUrl }/` } };
14
20
  }
15
21
  },
16
22
  // this has its own tests so it just returns the input string
17
- urlOptions: (string) => string
23
+ urlOptions: (url: string, opt: any, type: string) => {
24
+ if (opt.addParam) {
25
+ url += '?param=true';
26
+ }
27
+
28
+ return url;
29
+ }
18
30
  };
19
31
 
20
32
  const urlForGetter = urlFor(state, getters);
21
33
 
22
34
  // most tests for this getter will go through the dashboard-store getters test spec, this only tests logic specific to the steve variant
23
35
 
24
- it('expects urlFor to return a function', () => {
25
- expect(typeof urlFor(state, getters)).toBe('function');
26
- });
36
+ it.each([
37
+ ['rType', undefined, undefined, collectionUrl],
27
38
 
28
- it('expects function returned by urlFor to return a string a type', () => {
29
- expect(urlForGetter('typeFoo')).toBe('protocol/urlFoo');
30
- });
39
+ // No namespace
40
+ ['rType', undefined, { }, `${ collectionUrl }`],
41
+ ['rType', undefined, { addParam: true }, `${ collectionUrl }?param=true`],
42
+ ['rType', 'abc', { }, `${ collectionUrl }/abc`],
43
+ ['rType', 'abc', { addParam: true }, `${ collectionUrl }/abc?param=true`],
31
44
 
32
- it('expects function returned by urlFor to return a string containing a namespace when provided with a type and a single namespace string', () => {
33
- expect(urlForGetter('typeFoo', undefined, { namespaced: 'nsBar' })).toBe('protocol/urlFoo/nsBar');
34
- });
45
+ // With namespace
46
+ ['rType', undefined, { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }`],
47
+ ['rType', undefined, { addParam: true, namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }?param=true`],
48
+ ['rType', 'abc', { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }/abc`],
49
+ ['rType', 'abc', { addParam: true, namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }/abc?param=true`],
50
+
51
+ // With url (mostly no op)
52
+ ['rType', undefined, { url: `${ baseUrl }/urlFoo`, namespaced: `${ namespace }` }, `${ baseUrl }/urlFoo`],
53
+ ['rType', undefined, { url: `${ baseUrl }/urlFoo/abc`, namespaced: `${ namespace }` }, `${ baseUrl }/urlFoo/abc`],
54
+ ['rType', undefined, { url: `/urlFoo`, namespaced: `${ namespace }` }, `/urlFoo`],
55
+ ['rType', undefined, { url: `/urlFoo/abc`, namespaced: `${ namespace }` }, `/urlFoo/abc`],
35
56
 
36
- it('expects function returned by urlFor to return a string not containing a namespace when provided with a type and a multiple namespaces string', () => {
37
- expect(urlForGetter('typeFoo', undefined, { namespaced: ['nsBar', 'nsBaz'] })).toBe('protocol/urlFoo');
57
+ // multiple namespaces (no op)
58
+ ['rType', undefined, { namespaced: [`${ namespace }`, 'nsBaz'] }, `${ collectionUrl }`],
59
+
60
+ // handle trailing space
61
+ ['trailingforwardslash', undefined, { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }`],
62
+
63
+ ])("given type '%p', id '%p' and opt '%p', should get url '%p'", (type, id, opt, url) => {
64
+ expect(urlForGetter(type, id, opt)).toBe(url);
38
65
  });
39
66
  });
40
67
 
41
- describe('steve > getters > urlOptions', () => {
68
+ describe('urlOptions', () => {
42
69
  // we're not testing function output based off of state or getter inputs here since they are dependencies
43
70
  const state = { config: { baseUrl: 'protocol' } };
44
71
  const getters = {
45
72
  normalizeType: (type) => type,
46
- schemaFor: (type) => {
47
- if (type === 'typeFoo') {
48
- return { links: { collection: 'urlFoo' } };
49
- }
50
- },
51
73
  // this has its own tests so it just returns the input string
52
- urlOptions: (string) => string
74
+ urlOptions: (string) => string
53
75
  };
54
76
 
55
77
  const urlOptionsGetter = urlOptions();
@@ -93,7 +115,7 @@ describe('steve: getters', () => {
93
115
  it('returns a string without an exclude statement if excludeFields is but the url does not start with "/v1/"', () => {
94
116
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
95
117
  });
96
- it('returns a string without an exclude statement if excludeFields is an array but the URL doesnt include the "/v1/ string"', () => {
118
+ it('returns a string without an exclude statement if excludeFields is an array but the URL doesn\'t include the "/v1/ string"', () => {
97
119
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
98
120
  });
99
121
  it('returns a string with a limit applied if a limit is provided', () => {
@@ -103,16 +125,87 @@ describe('steve: getters', () => {
103
125
  expect(urlOptionsGetter('foo', { sortBy: 'bar' })).toBe('foo?sort=bar');
104
126
  });
105
127
  it('returns a string with a sorting criteria formatted for steve if the sort option is provided and the url starts with "/v1"', () => {
106
- expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar' })).toBe('/v1/foo?exclude=metadata.managedFields&sort=bar');
128
+ expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar' })).toBe('/v1/foo?sort=bar&exclude=metadata.managedFields');
107
129
  });
108
130
  it('returns a string with a sorting criteria if the sort option is provided and an order if sortOrder is provided', () => {
109
131
  expect(urlOptionsGetter('foo', { sortBy: 'bar', sortOrder: 'baz' })).toBe('foo?sort=bar&order=baz');
110
132
  });
111
133
  it('returns a string with a sorting criteria formatted for steve if the sort option is provided and an order if sortOrder is provided and the url starts with "/v1"', () => {
112
- expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar', sortOrder: 'baz' })).toBe('/v1/foo?exclude=metadata.managedFields&sort=bar');
134
+ expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar', sortOrder: 'baz' })).toBe('/v1/foo?sort=bar&exclude=metadata.managedFields');
113
135
  });
114
136
  it('returns a string with a sorting criteria formatted for steve if the sort option is provided and an order if sortOrder is "desc" and the url starts with "/v1"', () => {
115
- expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar', sortOrder: 'desc' })).toBe('/v1/foo?exclude=metadata.managedFields&sort=-bar');
137
+ expect(urlOptionsGetter('/v1/foo', { sortBy: 'bar', sortOrder: 'desc' })).toBe('/v1/foo?sort=-bar&exclude=metadata.managedFields');
138
+ });
139
+ });
140
+
141
+ describe('pathExistsInSchema', () => {
142
+ const state = {};
143
+
144
+ const getters = { schemaFor: (type: string) => ({}) };
145
+
146
+ it('expects pathExistsInSchema to return a function', () => {
147
+ expect(typeof pathExistsInSchema(state, getters)).toBe('function');
148
+ });
149
+
150
+ describe('resourceFields', () => {
151
+ it('requires resourceFields but no resourceFields', () => {
152
+ expect(pathExistsInSchema(state, {
153
+ ...getters,
154
+ schemaFor: () => ({
155
+ requiresResourceFields: true,
156
+ hasResourceFields: false,
157
+ })
158
+ })()).toBe(false);
159
+ });
160
+
161
+ it('requires resourceFields but empty resourceFields', () => {
162
+ expect(pathExistsInSchema(state, {
163
+ ...getters,
164
+ schemaFor: () => ({
165
+ requiresResourceFields: true,
166
+ hasResourceFields: true,
167
+ schemaDefinitions: {}
168
+ })
169
+ })('', 'name')).toBe(false);
170
+ });
171
+
172
+ it('requires resourceFields and has resourceFields', () => {
173
+ expect(pathExistsInSchema(state, {
174
+ ...getters,
175
+ schemaFor: () => ({
176
+ requiresResourceFields: true,
177
+ hasResourceFields: true,
178
+ resourceFields: { name: { type: 'string' } },
179
+ schemaDefinitions: { name: { } },
180
+ })
181
+ })('n/a', 'name')).toBe(true);
182
+ });
183
+
184
+ it('requires nested resourceFields and has resourceFields', () => {
185
+ expect(pathExistsInSchema(state, {
186
+ ...getters,
187
+ schemaFor: (type) => {
188
+ const metadata = { resourceFields: { name: { type: 'string' } } };
189
+
190
+ switch (type) {
191
+ case 'root':
192
+ return {
193
+ requiresResourceFields: true,
194
+ hasResourceFields: true,
195
+ resourceFields: { metadata: { type: 'metadata' } },
196
+ schemaDefinitions: { metadata: { ...metadata } },
197
+ };
198
+ case 'metadata':
199
+ return {
200
+ requiresResourceFields: true,
201
+ hasResourceFields: true,
202
+ ...metadata,
203
+ };
204
+ }
205
+ expect(type).toBe('Something known');
206
+ }
207
+ })('root', 'metadata.name')).toBe(true);
208
+ });
116
209
  });
117
210
  });
118
211
  });
@@ -0,0 +1,49 @@
1
+ import mutations from '@shell/plugins/steve/mutations.js';
2
+ import { POD } from '@shell/config/types';
3
+ import Resource from '@shell/plugins/dashboard-store/resource-class';
4
+ import mutationHelpers from '@shell/plugins/steve/__tests__/utils/mutation.test.helpers';
5
+
6
+ describe('steve-store: mutations', () => {
7
+ describe('loadAdd', () => {
8
+ const createNewEntry = () => {
9
+ const res = mutationHelpers.loadAll.createNewEntry();
10
+ const pod = res.params[1].data[0];
11
+
12
+ res.params[0].podsByNamespace = {};
13
+ res.expected.podsByNamespace = {
14
+ [pod.namespace]: {
15
+ list: [new Resource(pod)],
16
+ map: new Map([
17
+ [pod.id, new Resource(pod)]
18
+ ])
19
+ }
20
+ };
21
+
22
+ return res;
23
+ };
24
+
25
+ it.each([['No change', mutationHelpers.loadAll.createNoOp()]])('%s', (_, run) => {
26
+ mutations.loadAdd(...run.params);
27
+
28
+ expect(run.params[0]).toStrictEqual(run.expected.state);
29
+ });
30
+
31
+ it.each([
32
+ ['Add a new pod', createNewEntry()],
33
+ ])('%s', (_, run) => { // eslint-disable-line jest/no-identical-title
34
+ mutations.loadAdd(...run.params);
35
+ const { map: cacheMap, ...cacheState } = run.params[0].types?.[POD] ;
36
+ const cachePodsByNamespace = run.params[0].podsByNamespace ;
37
+ const { map: expectedMap, ...expected } = run.expected.types?.[POD];
38
+ const expectedPodsByNamespace = run.expected.podsByNamespace ;
39
+
40
+ expect(cacheMap).toBeDefined();
41
+ expect(expectedMap).toBeDefined();
42
+
43
+ expect(cacheState).toStrictEqual(expected);
44
+ expect(cacheMap).toStrictEqual(expectedMap);
45
+
46
+ expect(cachePodsByNamespace).toStrictEqual(expectedPodsByNamespace);
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,109 @@
1
+ import { actions } from '../subscribe';
2
+
3
+ describe('steve: subscribe', () => {
4
+ describe('actions', () => {
5
+ describe('watch', () => {
6
+ const state = {};
7
+ const getters = {
8
+ normalizeType: (type: string) => type,
9
+ schemaFor: () => null,
10
+ inError: () => false,
11
+ watchStarted: () => false,
12
+ };
13
+ const rootGetters = {
14
+ 'type-map/isSpoofed': () => false,
15
+ 'features/get': () => false,
16
+ };
17
+
18
+ const type = 'test';
19
+ const selector = undefined;
20
+ const id = undefined;
21
+ const revision = 1;
22
+ const namespace = undefined;
23
+ const stop = false;
24
+ const force = undefined;
25
+
26
+ it('no schema', () => {
27
+ const dispatch = jest.fn();
28
+
29
+ actions.watch({
30
+ state, dispatch, getters, rootGetters
31
+ }, {
32
+ type, selector, id, revision, namespace, stop, force
33
+ });
34
+
35
+ expect(dispatch).toHaveBeenCalledWith('send', {
36
+ resourceType: type,
37
+ resourceVersion: revision.toString(),
38
+
39
+ });
40
+ });
41
+
42
+ it('schema with watch verb', () => {
43
+ const dispatch = jest.fn();
44
+ const testGetters = {
45
+ ...getters,
46
+ schemaFor: (type: string) => ({ attributes: { verbs: ['watch'] } }),
47
+ };
48
+
49
+ actions.watch({
50
+ state, dispatch, getters: testGetters, rootGetters
51
+ }, {
52
+ type, selector, id, revision, namespace, stop, force
53
+ });
54
+
55
+ expect(dispatch).toHaveBeenCalledWith('send', {
56
+ resourceType: type,
57
+ resourceVersion: revision.toString(),
58
+ });
59
+ });
60
+
61
+ it('schema with no watch verb', () => {
62
+ const dispatch = jest.fn();
63
+ const testGetters = {
64
+ ...getters,
65
+ schemaFor: (type: string) => ({ attributes: { verbs: [] } }),
66
+ };
67
+
68
+ actions.watch({
69
+ state, dispatch, getters: testGetters, rootGetters
70
+ }, {
71
+ type, selector, id, revision, namespace, stop, force
72
+ });
73
+
74
+ expect(dispatch).not.toHaveBeenCalled();
75
+ });
76
+
77
+ it('don\'t watch when the watch is in error', () => {
78
+ const dispatch = jest.fn();
79
+ const testGetters = {
80
+ ...getters,
81
+ inError: (params: any) => true,
82
+ };
83
+
84
+ actions.watch({
85
+ state, dispatch, getters: testGetters, rootGetters
86
+ }, {
87
+ type, selector, id, revision, namespace, stop, force
88
+ });
89
+
90
+ expect(dispatch).not.toHaveBeenCalled();
91
+ });
92
+ });
93
+
94
+ describe('ws.resource.error', () => {
95
+ it('handle no permission error', () => {
96
+ const commit = jest.fn();
97
+ const getters = { storeName: 'storeName' };
98
+ const dispatch = undefined;
99
+
100
+ const msg = { data: { error: 'the server does not allow this method on the requested resource' } };
101
+
102
+ actions['ws.resource.error']({
103
+ getters, commit, dispatch
104
+ }, msg);
105
+ expect(commit).toHaveBeenCalledWith('setInError', { msg, reason: 'NO_PERMS' });
106
+ });
107
+ });
108
+ });
109
+ });