@rancher/shell 3.0.7 → 3.0.8-rc.10

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 (375) hide show
  1. package/assets/brand/suse/banner.svg +1 -0
  2. package/assets/brand/suse/dark/banner.svg +1 -0
  3. package/assets/brand/suse/dark/login-landscape.svg +1 -0
  4. package/assets/brand/suse/dark/rancher-logo.svg +1 -1
  5. package/assets/brand/suse/favicon.png +0 -0
  6. package/assets/brand/suse/login-landscape.svg +1 -0
  7. package/assets/brand/suse/metadata.json +11 -1
  8. package/assets/brand/suse/rancher-logo.svg +1 -1
  9. package/assets/fonts/suse/suse-v2-latin-300.woff +0 -0
  10. package/assets/fonts/suse/suse-v2-latin-300.woff2 +0 -0
  11. package/assets/fonts/suse/suse-v2-latin-600.woff +0 -0
  12. package/assets/fonts/suse/suse-v2-latin-600.woff2 +0 -0
  13. package/assets/fonts/suse/suse-v2-latin-700.woff +0 -0
  14. package/assets/fonts/suse/suse-v2-latin-700.woff2 +0 -0
  15. package/assets/fonts/suse/suse-v2-latin-800.woff +0 -0
  16. package/assets/fonts/suse/suse-v2-latin-800.woff2 +0 -0
  17. package/assets/fonts/suse/suse-v2-latin-regular.woff +0 -0
  18. package/assets/fonts/suse/suse-v2-latin-regular.woff2 +0 -0
  19. package/assets/images/content/README.md +5 -0
  20. package/assets/images/content/cloud-native.svg +84 -0
  21. package/assets/images/content/dark/cloud-native.svg +21 -0
  22. package/assets/images/content/dark/shield.svg +59 -0
  23. package/assets/images/content/dark/suse.svg +10 -0
  24. package/assets/images/content/shield.svg +59 -0
  25. package/assets/images/content/suse.svg +10 -0
  26. package/assets/images/vendor/githubapp.svg +13 -0
  27. package/assets/styles/base/_typography.scss +2 -1
  28. package/assets/styles/fonts/_fontstack.scss +53 -1
  29. package/assets/styles/global/_cards.scss +0 -3
  30. package/assets/styles/global/_layout.scss +21 -35
  31. package/assets/styles/themes/_dark.scss +1 -1
  32. package/assets/styles/themes/_light.scss +1 -1
  33. package/assets/styles/themes/_modern.scss +16 -8
  34. package/assets/styles/themes/_suse.scss +116 -24
  35. package/assets/translations/en-us.yaml +185 -21
  36. package/assets/translations/zh-hans.yaml +0 -4
  37. package/components/AutoscalerCard.vue +113 -0
  38. package/components/AutoscalerTab.vue +94 -0
  39. package/components/BackLink.vue +8 -0
  40. package/components/BannerGraphic.vue +36 -21
  41. package/components/BrandImage.vue +17 -6
  42. package/components/ClusterIconMenu.vue +1 -1
  43. package/components/ClusterProviderIcon.vue +1 -1
  44. package/components/Cron/CronExpressionEditor.vue +1 -1
  45. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  46. package/components/Drawer/Chrome.vue +2 -6
  47. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
  48. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
  49. package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
  50. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
  51. package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
  52. package/components/Drawer/types.ts +3 -0
  53. package/components/DynamicContent/DynamicContentBanner.vue +102 -0
  54. package/components/DynamicContent/DynamicContentCloseButton.vue +42 -0
  55. package/components/DynamicContent/DynamicContentIcon.vue +132 -0
  56. package/components/DynamicContent/DynamicContentPanel.vue +112 -0
  57. package/components/DynamicContent/content.ts +78 -0
  58. package/components/EmberPage.vue +1 -1
  59. package/components/IconOrSvg.vue +2 -2
  60. package/components/Inactivity.vue +222 -106
  61. package/components/InstallHelmCharts.vue +2 -2
  62. package/components/PaginatedResourceTable.vue +2 -6
  63. package/components/PopoverCard.vue +192 -0
  64. package/components/Questions/__tests__/index.test.ts +159 -0
  65. package/components/Resource/Detail/CopyToClipboard.vue +4 -1
  66. package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
  67. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  68. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
  69. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
  70. package/components/Resource/Detail/Metadata/KeyValueRow.vue +1 -1
  71. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  72. package/components/Resource/Detail/Metadata/composables.ts +9 -9
  73. package/components/Resource/Detail/Metadata/index.vue +3 -3
  74. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
  75. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
  76. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
  77. package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
  78. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
  79. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  80. package/components/Resource/Detail/TitleBar/index.vue +10 -6
  81. package/components/Resource/Detail/composables.ts +12 -0
  82. package/components/ResourceDetail/Masthead/latest.vue +29 -0
  83. package/components/ResourceDetail/index.vue +5 -2
  84. package/components/ResourceList/Masthead.vue +1 -1
  85. package/components/SortableTable/index.vue +18 -2
  86. package/components/Tabbed/__tests__/index.test.ts +86 -0
  87. package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
  88. package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
  89. package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
  90. package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
  91. package/components/__tests__/AutoscalerCard.test.ts +154 -0
  92. package/components/__tests__/AutoscalerTab.test.ts +125 -0
  93. package/components/__tests__/PopoverCard.test.ts +204 -0
  94. package/components/auth/SelectPrincipal.vue +24 -6
  95. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  96. package/components/fleet/FleetConfigMapSelector.vue +117 -0
  97. package/components/fleet/FleetSecretSelector.vue +127 -0
  98. package/components/fleet/__tests__/FleetConfigMapSelector.test.ts +125 -0
  99. package/components/fleet/__tests__/FleetSecretSelector.test.ts +82 -0
  100. package/components/form/FileImageSelector.vue +13 -4
  101. package/components/form/FileSelector.vue +11 -2
  102. package/components/form/ResourceLabeledSelect.vue +1 -0
  103. package/components/form/__tests__/ResourceLabeledSelect.test.ts +90 -0
  104. package/components/formatter/Autoscaler.vue +97 -0
  105. package/components/formatter/InternalExternalIP.vue +198 -24
  106. package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
  107. package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
  108. package/components/google/util/__tests__/formatter.test.ts +47 -0
  109. package/components/google/util/formatter.ts +5 -2
  110. package/components/nav/Group.vue +12 -3
  111. package/components/nav/Header.vue +37 -16
  112. package/components/nav/NamespaceFilter.vue +13 -1
  113. package/components/nav/NotificationCenter/index.vue +2 -1
  114. package/components/nav/TopLevelMenu.helper.ts +16 -6
  115. package/components/nav/TopLevelMenu.vue +4 -2
  116. package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
  117. package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
  118. package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
  119. package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
  120. package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
  121. package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
  122. package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
  123. package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
  124. package/components/nav/WindowManager/constants.ts +23 -0
  125. package/components/nav/WindowManager/index.vue +61 -575
  126. package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
  127. package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
  128. package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
  129. package/components/templates/default.vue +4 -40
  130. package/components/templates/home.vue +31 -5
  131. package/components/templates/plain.vue +30 -4
  132. package/components/templates/standalone.vue +1 -1
  133. package/composables/useI18n.ts +10 -1
  134. package/composables/useInterval.ts +15 -0
  135. package/config/__test__/uiplugins.test.ts +309 -0
  136. package/config/labels-annotations.js +9 -1
  137. package/config/product/auth.js +1 -0
  138. package/config/product/explorer.js +3 -1
  139. package/config/product/manager.js +20 -9
  140. package/config/query-params.js +1 -0
  141. package/config/router/routes.js +10 -2
  142. package/config/settings.ts +10 -2
  143. package/config/store.js +4 -2
  144. package/config/table-headers.js +8 -0
  145. package/config/types.js +11 -0
  146. package/config/uiplugins.js +46 -2
  147. package/config/version.js +1 -1
  148. package/core/__test__/extension-manager-impl.test.js +236 -0
  149. package/core/extension-manager-impl.js +23 -6
  150. package/core/plugin-helpers.ts +2 -0
  151. package/core/types-provisioning.ts +4 -1
  152. package/detail/pod.vue +1 -0
  153. package/detail/provisioning.cattle.io.cluster.vue +13 -1
  154. package/dialog/AddonConfigConfirmationDialog.vue +45 -1
  155. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  156. package/dialog/RollbackWorkloadDialog.vue +2 -5
  157. package/directives/ui-context.ts +103 -0
  158. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +52 -11
  159. package/edit/auth/AuthProviderWarningBanners.vue +14 -1
  160. package/edit/auth/__tests__/oidc.test.ts +26 -0
  161. package/edit/auth/github-app-steps.vue +97 -0
  162. package/edit/auth/github-steps.vue +75 -0
  163. package/edit/auth/github.vue +99 -65
  164. package/edit/auth/oidc.vue +5 -1
  165. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  166. package/edit/cloudcredential.vue +1 -1
  167. package/edit/configmap.vue +1 -0
  168. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  169. package/edit/fleet.cattle.io.gitrepo.vue +0 -10
  170. package/edit/fleet.cattle.io.helmop.vue +51 -2
  171. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  172. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  173. package/edit/logging-flow/index.vue +1 -0
  174. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  175. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  176. package/edit/management.cattle.io.project.vue +1 -0
  177. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  178. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  179. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  180. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  181. package/edit/monitoring.coreos.com.route.vue +1 -1
  182. package/edit/namespace.vue +1 -0
  183. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  184. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  185. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +15 -5
  186. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  187. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  188. package/edit/node.vue +1 -0
  189. package/edit/persistentvolume/index.vue +27 -22
  190. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  191. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  192. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  193. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  194. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  195. package/edit/persistentvolume/plugins/csi.vue +18 -16
  196. package/edit/persistentvolume/plugins/fc.vue +13 -14
  197. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  198. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  199. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  200. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  201. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  202. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  203. package/edit/persistentvolume/plugins/local.vue +1 -3
  204. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  205. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  206. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  207. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  208. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  209. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  210. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  211. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  212. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  213. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
  214. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
  215. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +155 -0
  216. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +11 -9
  217. package/edit/provisioning.cattle.io.cluster/index.vue +25 -15
  218. package/edit/provisioning.cattle.io.cluster/rke2.vue +98 -17
  219. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +28 -2
  220. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
  221. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +92 -4
  222. package/edit/secret/index.vue +1 -1
  223. package/edit/service.vue +9 -4
  224. package/edit/serviceaccount.vue +1 -0
  225. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  226. package/edit/workload/index.vue +2 -1
  227. package/edit/workload/mixins/workload.js +1 -1
  228. package/initialize/App.vue +4 -4
  229. package/initialize/install-directives.js +2 -0
  230. package/initialize/install-plugins.js +19 -2
  231. package/list/projectsecret.vue +1 -1
  232. package/list/provisioning.cattle.io.cluster.vue +15 -2
  233. package/machine-config/amazonec2.vue +42 -135
  234. package/machine-config/azure.vue +1 -1
  235. package/machine-config/components/EC2Networking.vue +490 -0
  236. package/machine-config/components/__tests__/EC2Networking.test.ts +148 -0
  237. package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
  238. package/machine-config/digitalocean.vue +11 -0
  239. package/machine-config/google.vue +1 -1
  240. package/mixins/__tests__/brand.spec.ts +2 -2
  241. package/mixins/__tests__/chart.test.ts +21 -0
  242. package/mixins/brand.js +1 -7
  243. package/mixins/chart.js +8 -2
  244. package/mixins/create-edit-view/index.js +5 -0
  245. package/models/__tests__/chart.test.ts +49 -12
  246. package/models/__tests__/compliance.cattle.io.clusterscanprofile.spec.js +30 -0
  247. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  248. package/models/catalog.cattle.io.app.js +1 -1
  249. package/models/chart.js +28 -14
  250. package/models/cluster/node.js +13 -6
  251. package/models/cluster.x-k8s.io.machine.js +10 -20
  252. package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
  253. package/models/compliance.cattle.io.clusterscanprofile.js +1 -1
  254. package/models/management.cattle.io.authconfig.js +1 -0
  255. package/models/management.cattle.io.cluster.js +21 -3
  256. package/models/management.cattle.io.kontainerdriver.js +1 -0
  257. package/models/provisioning.cattle.io.cluster.js +249 -33
  258. package/package.json +6 -5
  259. package/pages/auth/login.vue +43 -4
  260. package/pages/auth/verify.vue +1 -1
  261. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +3 -2
  262. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  263. package/pages/c/_cluster/apps/charts/chart.vue +35 -17
  264. package/pages/c/_cluster/apps/charts/index.vue +11 -13
  265. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  266. package/pages/c/_cluster/explorer/EventsTable.vue +89 -3
  267. package/pages/c/_cluster/explorer/index.vue +8 -6
  268. package/pages/c/_cluster/explorer/tools/index.vue +3 -3
  269. package/pages/c/_cluster/manager/hostedprovider/index.vue +220 -0
  270. package/pages/c/_cluster/settings/brand.vue +1 -1
  271. package/pages/c/_cluster/settings/performance.vue +12 -25
  272. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  273. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  274. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  275. package/pages/home.vue +327 -16
  276. package/pkg/dynamic-importer.lib.js +4 -0
  277. package/plugins/axios.js +2 -1
  278. package/plugins/dashboard-client-init.js +3 -0
  279. package/plugins/dashboard-store/actions.js +1 -1
  280. package/plugins/dashboard-store/getters.js +18 -1
  281. package/plugins/dashboard-store/resource-class.js +21 -6
  282. package/plugins/dynamic-content.js +13 -0
  283. package/plugins/i18n.js +8 -0
  284. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  285. package/plugins/steve/steve-pagination-utils.ts +41 -22
  286. package/plugins/steve/subscribe.js +17 -9
  287. package/plugins/subscribe-events.ts +4 -2
  288. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  289. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -34
  290. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  291. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  292. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  293. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  294. package/rancher-components/Pill/types.ts +0 -1
  295. package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -0
  296. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
  297. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  298. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  299. package/rancher-components/RcIcon/index.ts +1 -0
  300. package/rancher-components/RcIcon/types.ts +160 -0
  301. package/rancher-components/utils/status.test.ts +67 -0
  302. package/rancher-components/utils/status.ts +77 -0
  303. package/scripts/extension/publish +1 -1
  304. package/scripts/typegen.sh +1 -0
  305. package/store/action-menu.js +8 -0
  306. package/store/auth.js +11 -6
  307. package/store/aws.js +8 -6
  308. package/store/catalog.js +6 -0
  309. package/store/features.js +2 -0
  310. package/store/index.js +45 -20
  311. package/store/notifications.ts +51 -4
  312. package/store/plugins.js +7 -3
  313. package/store/prefs.js +12 -6
  314. package/store/type-map.js +3 -3
  315. package/store/ui-context.ts +86 -0
  316. package/store/wm.ts +244 -0
  317. package/types/kube/kube-api.ts +2 -1
  318. package/types/notifications/index.ts +27 -3
  319. package/types/rancher/index.d.ts +1 -0
  320. package/types/resources/settings.d.ts +29 -7
  321. package/types/shell/index.d.ts +138 -4
  322. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  323. package/types/store/pagination.types.ts +157 -9
  324. package/types/store/subscribe-events.types.ts +8 -1
  325. package/types/store/subscribe.types.ts +1 -0
  326. package/types/window-manager.ts +24 -0
  327. package/utils/__tests__/cluster.test.ts +379 -1
  328. package/utils/__tests__/object.test.ts +19 -0
  329. package/utils/__tests__/provider.test.ts +98 -0
  330. package/utils/__tests__/selector-typed.test.ts +263 -0
  331. package/utils/__tests__/version.test.ts +19 -1
  332. package/utils/autoscaler-utils.ts +7 -0
  333. package/utils/back-off.ts +3 -3
  334. package/utils/brand.ts +29 -0
  335. package/utils/chart.js +18 -0
  336. package/utils/cluster.js +157 -3
  337. package/utils/color.js +1 -1
  338. package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
  339. package/utils/dynamic-content/__tests__/config.test.ts +187 -0
  340. package/utils/dynamic-content/__tests__/index.test.ts +390 -0
  341. package/utils/dynamic-content/__tests__/info.test.ts +275 -0
  342. package/utils/dynamic-content/__tests__/new-release.test.ts +216 -0
  343. package/utils/dynamic-content/__tests__/support-notice.test.ts +262 -0
  344. package/utils/dynamic-content/__tests__/util.test.ts +235 -0
  345. package/utils/dynamic-content/announcement.ts +142 -0
  346. package/utils/dynamic-content/config.ts +55 -0
  347. package/utils/dynamic-content/example.json +40 -0
  348. package/utils/dynamic-content/index.ts +277 -0
  349. package/utils/dynamic-content/info.ts +261 -0
  350. package/utils/dynamic-content/new-release.ts +126 -0
  351. package/utils/dynamic-content/notification-handler.ts +48 -0
  352. package/utils/dynamic-content/support-notice.ts +169 -0
  353. package/utils/dynamic-content/types.d.ts +153 -0
  354. package/utils/dynamic-content/util.ts +122 -0
  355. package/utils/dynamic-importer.js +2 -2
  356. package/utils/favicon.js +4 -4
  357. package/utils/inactivity.ts +104 -0
  358. package/utils/object.js +20 -2
  359. package/utils/pagination-utils.ts +19 -4
  360. package/utils/pagination-wrapper.ts +12 -8
  361. package/utils/provider.ts +14 -0
  362. package/utils/release-notes.ts +1 -1
  363. package/utils/scroll.js +7 -0
  364. package/utils/selector-typed.ts +6 -2
  365. package/utils/settings.ts +15 -0
  366. package/utils/validators/machine-pool.ts +13 -3
  367. package/utils/version.js +15 -0
  368. package/assets/images/icons/document.svg +0 -3
  369. package/plugins/nuxt-client-init.js +0 -3
  370. package/store/wm.js +0 -95
  371. /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
  372. /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
  373. /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
  374. /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
  375. /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
@@ -0,0 +1,204 @@
1
+
2
+ import { mount } from '@vue/test-utils';
3
+ import PopoverCard from '@shell/components/PopoverCard.vue';
4
+
5
+ const mockFocusTrap = jest.fn();
6
+
7
+ jest.mock('@shell/composables/focusTrap', () => ({
8
+ ...jest.requireActual('@shell/composables/focusTrap'), // Keep DEFAULT_FOCUS_TRAP_OPTS
9
+ useWatcherBasedSetupFocusTrapWithDestroyIncluded: (...args: any[]) => mockFocusTrap(...args),
10
+ }));
11
+
12
+ const VDropdownStub = {
13
+ props: ['shown'],
14
+ template: `
15
+ <div>
16
+ <slot />
17
+ <div v-if="shown">
18
+ <slot name="popper" />
19
+ </div>
20
+ </div>
21
+ `,
22
+ };
23
+
24
+ describe('component: PopoverCard.vue', () => {
25
+ const createWrapper = (props = {}, slots = {}) => {
26
+ return mount(PopoverCard, {
27
+ props: {
28
+ cardTitle: 'Test Title',
29
+ ...props,
30
+ },
31
+ slots,
32
+ global: {
33
+ stubs: {
34
+ VDropdown: VDropdownStub,
35
+ Card: {
36
+ template: `
37
+ <div>
38
+ <slot name="heading-action" />
39
+ <slot />
40
+ </div>
41
+ `,
42
+ },
43
+ RcButton: { template: '<button><slot /></button>' },
44
+ },
45
+ }
46
+ });
47
+ };
48
+
49
+ beforeEach(() => {
50
+ mockFocusTrap.mockClear();
51
+ });
52
+
53
+ describe('props', () => {
54
+ it('should use default props', () => {
55
+ const wrapper = createWrapper();
56
+ const button = wrapper.find('button');
57
+
58
+ expect(button.attributes('aria-label')).toBe('Show more');
59
+ });
60
+
61
+ it('should accept and render custom props', () => {
62
+ const props = {
63
+ cardTitle: 'My Custom Title',
64
+ showPopoverAriaLabel: 'Click for details'
65
+ };
66
+ const wrapper = createWrapper(props);
67
+ const button = wrapper.find('button');
68
+
69
+ expect(button.attributes('aria-label')).toBe(props.showPopoverAriaLabel);
70
+ // Note: cardTitle is passed to the Card component inside the popper,
71
+ // which is only rendered when the popover is shown.
72
+ });
73
+ });
74
+
75
+ describe('popover Visibility', () => {
76
+ it('should not be visible initially', () => {
77
+ const wrapper = createWrapper();
78
+
79
+ expect(wrapper.find('[id="popover-card"]').exists()).toBe(false);
80
+ });
81
+
82
+ it('should show on mouseenter and hide on mouseleave', async() => {
83
+ const wrapper = createWrapper();
84
+ const target = wrapper.find('.popover-card-target');
85
+
86
+ await target.trigger('mouseenter');
87
+ expect(wrapper.vm.showPopover).toBe(true);
88
+
89
+ const root = wrapper.find('.popover-card-base');
90
+
91
+ await root.trigger('mouseleave');
92
+ expect(wrapper.vm.showPopover).toBe(false);
93
+ });
94
+
95
+ it('should show on button click', async() => {
96
+ const wrapper = createWrapper();
97
+ const button = wrapper.find('button');
98
+
99
+ await button.trigger('click');
100
+ expect(wrapper.vm.showPopover).toBe(true);
101
+ expect(wrapper.vm.focusOpen).toBe(true);
102
+ });
103
+
104
+ it('should hide on Escape keydown', async() => {
105
+ const wrapper = createWrapper();
106
+
107
+ // Open it first
108
+ await wrapper.find('button').trigger('click');
109
+ expect(wrapper.vm.showPopover).toBe(true);
110
+ expect(wrapper.vm.focusOpen).toBe(true);
111
+
112
+ // Trigger escape
113
+ const root = wrapper.find('.popover-card-base');
114
+
115
+ await root.trigger('keydown.escape');
116
+
117
+ expect(wrapper.vm.showPopover).toBe(false);
118
+ expect(wrapper.vm.focusOpen).toBe(false);
119
+ });
120
+ });
121
+
122
+ describe('focus Trap', () => {
123
+ it('should NOT setup focus trap on mouseenter', async() => {
124
+ const wrapper = createWrapper();
125
+ const target = wrapper.find('.popover-card-target');
126
+
127
+ await target.trigger('mouseenter');
128
+ await wrapper.vm.$nextTick();
129
+
130
+ expect(wrapper.vm.focusOpen).toBe(false);
131
+ expect(mockFocusTrap).not.toHaveBeenCalled();
132
+ });
133
+
134
+ it('should setup focus trap when opened via click', async() => {
135
+ const wrapper = createWrapper({ fallbackFocus: '#my-fallback' });
136
+ const button = wrapper.find('button');
137
+
138
+ await button.trigger('click');
139
+ await wrapper.vm.$nextTick(); // Let watcher for `card` run
140
+
141
+ expect(wrapper.vm.focusOpen).toBe(true);
142
+ expect(mockFocusTrap).toHaveBeenCalledTimes(1);
143
+
144
+ // Check arguments passed to the composable
145
+ const focusTrapOptions = mockFocusTrap.mock.calls[0][2];
146
+
147
+ expect(focusTrapOptions.fallbackFocus).toBe('#my-fallback');
148
+ expect(focusTrapOptions.setReturnFocus()).toBe('.focus-button');
149
+ });
150
+ });
151
+
152
+ describe('slots', () => {
153
+ it('should render the default slot content', () => {
154
+ const wrapper = createWrapper({}, { default: '<span class="default-slot-content">Hello</span>' });
155
+
156
+ expect(wrapper.find('.default-slot-content').exists()).toBe(true);
157
+ expect(wrapper.find('.default-slot-content').text()).toBe('Hello');
158
+ });
159
+
160
+ it('should render the card-body slot content', async() => {
161
+ const wrapper = createWrapper({}, { 'card-body': '<div class="card-body-content">Card Body</div>' });
162
+
163
+ // Open popover to render the slot
164
+ await wrapper.find('button').trigger('click');
165
+
166
+ expect(wrapper.find('.card-body-content').exists()).toBe(true);
167
+ expect(wrapper.find('.card-body-content').text()).toBe('Card Body');
168
+ });
169
+
170
+ it('should pass a close function to the heading-action slot', async() => {
171
+ const wrapper = createWrapper({}, {
172
+ 'heading-action': `
173
+ <template #heading-action="{ close }">
174
+ <button class="close-button" @click="close">Close</button>
175
+ </template>
176
+ `
177
+ });
178
+
179
+ // Open popover
180
+ await wrapper.find('button').trigger('click');
181
+ expect(wrapper.vm.showPopover).toBe(true);
182
+ expect(wrapper.vm.focusOpen).toBe(true);
183
+
184
+ // Click the button that uses the `close` slot prop
185
+ await wrapper.find('.close-button').trigger('click');
186
+
187
+ // Due to the bug, this should be true, not false
188
+ expect(wrapper.vm.showPopover).toBe(false);
189
+ expect(wrapper.vm.focusOpen).toBe(false);
190
+ });
191
+
192
+ it('should allow overriding the entire card via the card slot', async() => {
193
+ const wrapper = createWrapper({}, { card: '<div class="custom-card">My Custom Card</div>' });
194
+
195
+ // Open popover
196
+ await wrapper.find('button').trigger('click');
197
+
198
+ expect(wrapper.find('.custom-card').exists()).toBe(true);
199
+ expect(wrapper.find('.custom-card').text()).toBe('My Custom Card');
200
+ // The default Card component should not be rendered
201
+ expect(wrapper.find('[id="popover-card"]').exists()).toBe(false);
202
+ });
203
+ });
204
+ });
@@ -56,11 +56,13 @@ export default {
56
56
 
57
57
  data() {
58
58
  return {
59
- principals: null,
60
- searchStr: '',
61
- options: [],
62
- newValue: '',
63
- tooltipContent: null,
59
+ principals: null,
60
+ searchStr: '',
61
+ options: [],
62
+ newValue: '',
63
+ tooltipContent: null,
64
+ hasSearchTooShort: false,
65
+ minSearchLength: 2,
64
66
  };
65
67
  },
66
68
 
@@ -133,9 +135,20 @@ export default {
133
135
  this.searchStr = str;
134
136
 
135
137
  if ( str ) {
138
+ // Backend requires minimum 2 characters for search
139
+ if (str.length < this.minSearchLength) {
140
+ this.hasSearchTooShort = true;
141
+ this.options = [];
142
+ loading(false);
143
+
144
+ return;
145
+ }
146
+
147
+ this.hasSearchTooShort = false;
136
148
  loading(true);
137
149
  this.debouncedSearch(str, loading);
138
150
  } else {
151
+ this.hasSearchTooShort = false;
139
152
  this.search(null, loading);
140
153
  }
141
154
  },
@@ -196,7 +209,12 @@ export default {
196
209
  @on-close="setTooltipContent()"
197
210
  >
198
211
  <template v-slot:no-options="{ searching }">
199
- <template v-if="searching">
212
+ <template v-if="hasSearchTooShort">
213
+ <span class="search-slot">
214
+ {{ t('cluster.memberRoles.addClusterMember.minCharacters', { count: minSearchLength }) }}
215
+ </span>
216
+ </template>
217
+ <template v-else-if="searching">
200
218
  <span class="search-slot">
201
219
  {{ t('cluster.memberRoles.addClusterMember.noResults') }}
202
220
  </span>
@@ -0,0 +1,119 @@
1
+ import { shallowMount, type VueWrapper } from '@vue/test-utils';
2
+ import SelectPrincipal from '@shell/components/auth/SelectPrincipal.vue';
3
+
4
+ describe('component: SelectPrincipal', () => {
5
+ const mockStore = { dispatch: jest.fn().mockResolvedValue([]) };
6
+
7
+ const defaultMountOptions = {
8
+ global: {
9
+ mocks: {
10
+ $fetchState: { pending: false },
11
+ $store: mockStore,
12
+ t: (key: string, opts?: any) => opts?.count ? `${ key } ${ opts.count }` : key,
13
+ },
14
+ stubs: {
15
+ LabeledSelect: {
16
+ template: '<div class="labeled-select-stub"><slot name="no-options" :searching="searching" /></div>',
17
+ props: ['options', 'searchable', 'filterable'],
18
+ data() {
19
+ return { searching: false };
20
+ }
21
+ },
22
+ Principal: true,
23
+ },
24
+ },
25
+ };
26
+
27
+ beforeEach(() => {
28
+ jest.clearAllMocks();
29
+ mockStore.dispatch.mockResolvedValue([]);
30
+ });
31
+
32
+ describe('onSearch', () => {
33
+ it('should set hasSearchTooShort to true when search string is less than minSearchLength', async() => {
34
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
35
+
36
+ // Set principals to an empty array to avoid null errors
37
+ wrapper.vm.principals = [];
38
+ await wrapper.vm.$nextTick();
39
+
40
+ const loadingFn = jest.fn();
41
+
42
+ wrapper.vm.onSearch('a', loadingFn);
43
+
44
+ expect(wrapper.vm.hasSearchTooShort).toBe(true);
45
+ expect(wrapper.vm.options).toStrictEqual([]);
46
+ expect(loadingFn).toHaveBeenCalledWith(false);
47
+ });
48
+
49
+ it('should set hasSearchTooShort to false when search string meets minSearchLength', async() => {
50
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
51
+
52
+ wrapper.vm.principals = [];
53
+ await wrapper.vm.$nextTick();
54
+
55
+ const loadingFn = jest.fn();
56
+
57
+ wrapper.vm.onSearch('ab', loadingFn);
58
+
59
+ expect(wrapper.vm.hasSearchTooShort).toBe(false);
60
+ expect(loadingFn).toHaveBeenCalledWith(true);
61
+ });
62
+
63
+ it('should set hasSearchTooShort to false when search string is empty', async() => {
64
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
65
+
66
+ wrapper.vm.principals = [];
67
+ await wrapper.vm.$nextTick();
68
+
69
+ // First set hasSearchTooShort to true
70
+ wrapper.vm.hasSearchTooShort = true;
71
+
72
+ const loadingFn = jest.fn();
73
+
74
+ wrapper.vm.onSearch('', loadingFn);
75
+
76
+ expect(wrapper.vm.hasSearchTooShort).toBe(false);
77
+ });
78
+
79
+ it('should not call debouncedSearch when search string is too short', async() => {
80
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
81
+
82
+ wrapper.vm.principals = [];
83
+ await wrapper.vm.$nextTick();
84
+
85
+ // Spy on the debounced search
86
+ const debouncedSearchSpy = jest.spyOn(wrapper.vm, 'debouncedSearch');
87
+ const loadingFn = jest.fn();
88
+
89
+ wrapper.vm.onSearch('x', loadingFn);
90
+
91
+ expect(debouncedSearchSpy).not.toHaveBeenCalled();
92
+ });
93
+
94
+ it('should call debouncedSearch when search string meets minimum length', async() => {
95
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
96
+
97
+ wrapper.vm.principals = [];
98
+ await wrapper.vm.$nextTick();
99
+
100
+ const debouncedSearchSpy = jest.spyOn(wrapper.vm, 'debouncedSearch');
101
+ const loadingFn = jest.fn();
102
+
103
+ wrapper.vm.onSearch('xy', loadingFn);
104
+
105
+ expect(debouncedSearchSpy).toHaveBeenCalledWith('xy', loadingFn);
106
+ });
107
+ });
108
+
109
+ describe('minSearchLength', () => {
110
+ it('should have a default minSearchLength of 2', async() => {
111
+ const wrapper: VueWrapper<any> = shallowMount(SelectPrincipal, defaultMountOptions);
112
+
113
+ wrapper.vm.principals = [];
114
+ await wrapper.vm.$nextTick();
115
+
116
+ expect(wrapper.vm.minSearchLength).toBe(2);
117
+ });
118
+ });
119
+ });
@@ -0,0 +1,117 @@
1
+ <script lang="ts" setup>
2
+ import { ref } from 'vue';
3
+ import { _EDIT } from '@shell/config/query-params';
4
+ import { CONFIG_MAP } from '@shell/config/types';
5
+ import { PaginationParamFilter } from '@shell/types/store/pagination.types';
6
+ import ResourceLabeledSelect from '@shell/components/form/ResourceLabeledSelect.vue';
7
+
8
+ interface ConfigMap {
9
+ id?: string;
10
+ name: string;
11
+ namespace: string;
12
+ }
13
+
14
+ const props = defineProps({
15
+ value: {
16
+ type: Object,
17
+ required: true,
18
+ },
19
+ namespace: {
20
+ type: String,
21
+ required: true,
22
+ },
23
+ inStore: {
24
+ type: String,
25
+ default: 'management',
26
+ },
27
+ mode: {
28
+ type: String,
29
+ default: _EDIT
30
+ },
31
+ label: {
32
+ type: String,
33
+ default: '',
34
+ },
35
+ });
36
+
37
+ const emit = defineEmits(['update:value']);
38
+
39
+ const configMaps = ref<ConfigMap[]>([]);
40
+
41
+ const allConfigMapsSettings = {
42
+ updateResources: (configMapsList: ConfigMap[]) => {
43
+ const allConfigMapsInNamespace = configMapsList.filter((configMap) => configMap.namespace === props.namespace);
44
+ const mappedConfigMaps = mapConfigMaps(allConfigMapsInNamespace.sort((a, b) => a.name.localeCompare(b.name)));
45
+
46
+ configMaps.value = allConfigMapsInNamespace;
47
+
48
+ return mappedConfigMaps;
49
+ }
50
+ };
51
+
52
+ const paginateConfigMapsSetting = {
53
+ requestSettings: paginatePageOptions,
54
+ updateResources: (configMapsList: ConfigMap[]) => {
55
+ const mappedConfigMaps = mapConfigMaps(configMapsList);
56
+
57
+ configMaps.value = configMapsList;
58
+
59
+ return mappedConfigMaps;
60
+ }
61
+ };
62
+
63
+ function mapConfigMaps(configMapsList: ConfigMap[]) {
64
+ return configMapsList.reduce<{ label: string; value: string }[]>((res, c) => {
65
+ if (c.id) {
66
+ res.push({ label: c.name, value: c.name });
67
+ } else {
68
+ res.push(c as any);
69
+ }
70
+
71
+ return res;
72
+ }, []);
73
+ }
74
+
75
+ function paginatePageOptions(opts: any) {
76
+ const { opts: { filter } } = opts;
77
+
78
+ const filters = !!filter ? [PaginationParamFilter.createSingleField({
79
+ field: 'metadata.name', value: filter, exact: false, equals: true
80
+ })] : [];
81
+
82
+ filters.push(
83
+ PaginationParamFilter.createSingleField({ field: 'metadata.namespace', value: props.namespace }),
84
+ );
85
+
86
+ return {
87
+ ...opts,
88
+ filters,
89
+ groupByNamespace: false,
90
+ classify: true,
91
+ sort: [{ asc: true, field: 'metadata.name' }],
92
+ };
93
+ }
94
+
95
+ function update(value: any) {
96
+ emit('update:value', value);
97
+ }
98
+ </script>
99
+
100
+ <template>
101
+ <ResourceLabeledSelect
102
+ :key="namespace"
103
+ :value="value"
104
+ :label="label || t('fleet.configMaps.label')"
105
+ :mode="mode"
106
+ :resource-type="CONFIG_MAP"
107
+ :loading="$fetchState.pending"
108
+ :in-store="inStore"
109
+ :paginated-resource-settings="paginateConfigMapsSetting"
110
+ :all-resources-settings="allConfigMapsSettings"
111
+ :multiple="true"
112
+ @update:value="update"
113
+ />
114
+ </template>
115
+
116
+ <style lang="scss" scoped>
117
+ </style>
@@ -0,0 +1,127 @@
1
+ <script lang="ts" setup>
2
+ import { ref, computed, defineProps, defineEmits } from 'vue';
3
+ import { _EDIT } from '@shell/config/query-params';
4
+ import { TYPES } from '@shell/models/secret';
5
+ import { SECRET } from '@shell/config/types';
6
+ import { PaginationParamFilter } from '@shell/types/store/pagination.types';
7
+ import ResourceLabeledSelect from '@shell/components/form/ResourceLabeledSelect.vue';
8
+
9
+ interface Secret {
10
+ id?: string;
11
+ name: string;
12
+ namespace: string;
13
+ _type: string;
14
+ }
15
+
16
+ const props = defineProps({
17
+ value: {
18
+ type: Object,
19
+ required: true,
20
+ },
21
+ namespace: {
22
+ type: String,
23
+ required: true,
24
+ },
25
+ inStore: {
26
+ type: String,
27
+ default: 'management',
28
+ },
29
+ mode: {
30
+ type: String,
31
+ default: _EDIT
32
+ },
33
+ label: {
34
+ type: String,
35
+ default: '',
36
+ },
37
+ });
38
+
39
+ const emit = defineEmits(['update:value']);
40
+
41
+ const types = computed<string[]>(() => Object.values(TYPES));
42
+
43
+ const secrets = ref<Secret[]>([]);
44
+
45
+ const allSecretsSettings = {
46
+ updateResources: (secretsList: Secret[]) => {
47
+ const allSecretsInNamespace = secretsList.filter((secret) => types.value.includes(secret._type) && secret.namespace === props.namespace);
48
+ const mappedSecrets = mapSecrets(allSecretsInNamespace.sort((a, b) => a.name.localeCompare(b.name)));
49
+
50
+ secrets.value = allSecretsInNamespace;
51
+
52
+ return mappedSecrets;
53
+ }
54
+ };
55
+
56
+ const paginateSecretsSetting = {
57
+ requestSettings: paginatePageOptions,
58
+ updateResources: (secretsList: Secret[]) => {
59
+ const mappedSecrets = mapSecrets(secretsList);
60
+
61
+ secrets.value = secretsList;
62
+
63
+ return mappedSecrets;
64
+ }
65
+ };
66
+
67
+ function mapSecrets(secretsList: Secret[]) {
68
+ return secretsList.reduce<{ label: string; value: string }[]>((res, s) => {
69
+ if (s.id) {
70
+ res.push({ label: s.name, value: s.name });
71
+ } else {
72
+ res.push(s as any);
73
+ }
74
+
75
+ return res;
76
+ }, []);
77
+ }
78
+
79
+ function update(value: any) {
80
+ emit('update:value', value);
81
+ }
82
+
83
+ function paginatePageOptions(opts: any) {
84
+ const { opts: { filter } } = opts;
85
+
86
+ const filters = !!filter ? [PaginationParamFilter.createSingleField({
87
+ field: 'metadata.name', value: filter, exact: false, equals: true
88
+ })] : [];
89
+
90
+ filters.push(
91
+ PaginationParamFilter.createSingleField({ field: 'metadata.namespace', value: props.namespace }),
92
+ PaginationParamFilter.createMultipleFields(types.value.map((t) => ({
93
+ field: 'metadata.fields.1',
94
+ equals: true,
95
+ exact: true,
96
+ value: t
97
+ })))
98
+ );
99
+
100
+ return {
101
+ ...opts,
102
+ filters,
103
+ groupByNamespace: false,
104
+ classify: true,
105
+ sort: [{ asc: true, field: 'metadata.name' }],
106
+ };
107
+ }
108
+ </script>
109
+
110
+ <template>
111
+ <ResourceLabeledSelect
112
+ :key="namespace"
113
+ :value="value"
114
+ :label="label || t('fleet.secrets.label')"
115
+ :mode="mode"
116
+ :resource-type="SECRET"
117
+ :loading="$fetchState.pending"
118
+ :in-store="inStore"
119
+ :paginated-resource-settings="paginateSecretsSetting"
120
+ :all-resources-settings="allSecretsSettings"
121
+ :multiple="true"
122
+ @update:value="update"
123
+ />
124
+ </template>
125
+
126
+ <style lang="scss" scoped>
127
+ </style>