dashboard-shell-shell 3.0.2-test.20250913 → 3.0.5-test.2

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 (628) hide show
  1. package/assets/data/aws-regions.json +3 -0
  2. package/assets/icons/demo.css:Zone.Identifier +0 -0
  3. package/assets/icons/demo_index.html:Zone.Identifier +0 -0
  4. package/assets/icons/iconfont.css:Zone.Identifier +0 -0
  5. package/assets/icons/iconfont.js:Zone.Identifier +0 -0
  6. package/assets/icons/iconfont.json:Zone.Identifier +0 -0
  7. package/assets/icons/iconfont.ttf:Zone.Identifier +0 -0
  8. package/assets/icons/iconfont.woff2:Zone.Identifier +0 -0
  9. package/assets/icons/iconfont.woff:Zone.Identifier +0 -0
  10. package/assets/images/icons/document.svg +3 -0
  11. package/assets/images/key.svg +17 -0
  12. package/assets/images/providers/sks.svg +1 -0
  13. package/assets/images/vendor/cognito.svg +1 -0
  14. package/assets/styles/app.scss +3 -0
  15. package/assets/styles/base/_basic.scss +10 -0
  16. package/assets/styles/base/_spacing.scss +29 -0
  17. package/assets/styles/base/_variables.scss +16 -10
  18. package/assets/styles/global/_labeled-input.scss +1 -1
  19. package/assets/styles/global/_layout.scss +1 -1
  20. package/assets/styles/themes/_dark.scss +30 -0
  21. package/assets/styles/themes/_light.scss +80 -2
  22. package/assets/translations/en-us.yaml +822 -105
  23. package/assets/translations/zh-hans.yaml +13 -3
  24. package/chart/__tests__/S3.test.ts +2 -1
  25. package/chart/monitoring/index.vue +1 -1
  26. package/cloud-credential/gcp.vue +9 -1
  27. package/components/ActionMenuShell.vue +3 -7
  28. package/components/AppModal.vue +9 -28
  29. package/components/AsyncButton.vue +2 -0
  30. package/components/BrandImage.vue +0 -21
  31. package/components/Certificates.vue +5 -0
  32. package/components/CodeMirror.vue +3 -3
  33. package/components/CommunityLinks.vue +3 -58
  34. package/components/ConfigMapSettings/Settings.vue +377 -0
  35. package/components/ConfigMapSettings/index.vue +354 -0
  36. package/components/CruResource.vue +103 -16
  37. package/components/DetailText.vue +61 -11
  38. package/components/Drawer/Chrome.vue +115 -0
  39. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  40. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  41. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  42. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  43. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +106 -0
  44. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  45. package/components/Drawer/ResourceDetailDrawer/composables.ts +53 -0
  46. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  47. package/components/Drawer/ResourceDetailDrawer/index.vue +123 -0
  48. package/components/ExplorerProjectsNamespaces.vue +46 -29
  49. package/components/FilterPanel.vue +156 -0
  50. package/components/FixedBanner.vue +19 -5
  51. package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
  52. package/components/GrowlManager.vue +16 -15
  53. package/components/IconOrSvg.vue +19 -35
  54. package/components/KeyValueView.vue +1 -1
  55. package/components/LandingPagePreference.vue +2 -0
  56. package/components/Loading.vue +1 -1
  57. package/components/LocaleSelector.vue +10 -2
  58. package/components/PaginatedResourceTable.vue +53 -1
  59. package/components/ProgressBarMulti.vue +1 -0
  60. package/components/PromptModal.vue +38 -7
  61. package/components/PromptRemove.vue +5 -1
  62. package/components/PromptRestore.vue +22 -44
  63. package/components/RelatedResources.vue +4 -12
  64. package/components/Resource/Detail/Additional.vue +46 -0
  65. package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
  66. package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
  67. package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
  68. package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
  69. package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
  70. package/components/Resource/Detail/Card/Scaler.vue +89 -0
  71. package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
  72. package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
  73. package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
  74. package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
  75. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
  76. package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
  77. package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
  78. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
  79. package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
  80. package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
  81. package/components/Resource/Detail/Card/index.vue +56 -0
  82. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
  83. package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
  84. package/components/Resource/Detail/Metadata/Annotations/index.vue +31 -0
  85. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  86. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
  87. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +72 -0
  88. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +317 -0
  89. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +140 -0
  90. package/components/Resource/Detail/Metadata/KeyValue.vue +140 -0
  91. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
  92. package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
  93. package/components/Resource/Detail/Metadata/Labels/index.vue +31 -0
  94. package/components/Resource/Detail/Metadata/Rectangle.vue +34 -0
  95. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
  96. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
  97. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  98. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
  99. package/components/Resource/Detail/Metadata/composables.ts +81 -0
  100. package/components/Resource/Detail/Metadata/index.vue +88 -0
  101. package/components/Resource/Detail/Page.vue +37 -0
  102. package/components/Resource/Detail/PercentageBar.vue +40 -0
  103. package/components/Resource/Detail/ResourceRow.vue +138 -0
  104. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  105. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  106. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  107. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  108. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  109. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  110. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  111. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  112. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  113. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  114. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  115. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  116. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  117. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  118. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  119. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  120. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  121. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  122. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  123. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  124. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  125. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  126. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  127. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  128. package/components/Resource/Detail/SpacedRow.vue +14 -0
  129. package/components/Resource/Detail/StatusBar.vue +59 -0
  130. package/components/Resource/Detail/StatusRow.vue +61 -0
  131. package/components/Resource/Detail/TitleBar/Title.vue +14 -0
  132. package/components/Resource/Detail/TitleBar/Top.vue +14 -0
  133. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
  134. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
  135. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  136. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
  137. package/components/Resource/Detail/TitleBar/composables.ts +46 -0
  138. package/components/Resource/Detail/TitleBar/index.vue +204 -0
  139. package/components/Resource/Detail/Top/index.vue +34 -0
  140. package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
  141. package/components/Resource/Detail/composables.ts +45 -0
  142. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  143. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  144. package/components/ResourceDetail/Masthead/index.vue +65 -0
  145. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  146. package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -1
  147. package/components/ResourceDetail/__tests__/index.test.ts +135 -0
  148. package/components/ResourceDetail/index.vue +75 -575
  149. package/components/ResourceDetail/legacy.vue +564 -0
  150. package/components/ResourceList/Masthead.vue +69 -20
  151. package/components/ResourceList/index.vue +3 -2
  152. package/components/ResourceTable.vue +59 -85
  153. package/components/ResourceYaml.vue +15 -2
  154. package/components/RichTranslation.vue +106 -0
  155. package/components/SlideInPanelManager.vue +116 -14
  156. package/components/SortableTable/index.vue +10 -2
  157. package/components/SortableTable/paging.js +15 -16
  158. package/components/SortableTable/selection.js +22 -10
  159. package/components/StateDot/index.vue +28 -0
  160. package/components/StatusBadge.vue +6 -4
  161. package/components/SubtleLink.vue +25 -0
  162. package/components/Tabbed/index.vue +38 -22
  163. package/components/Wizard.vue +16 -3
  164. package/components/YamlEditor.vue +1 -2
  165. package/components/__tests__/AsyncButton.test.ts +39 -0
  166. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  167. package/components/__tests__/CruResource.test.ts +63 -0
  168. package/components/__tests__/FilterPanel.test.ts +81 -0
  169. package/components/__tests__/GrowlManager.test.ts +0 -25
  170. package/components/__tests__/PromptModal.test.ts +146 -0
  171. package/components/__tests__/PromptRestore.test.ts +1 -65
  172. package/components/__tests__/RichTranslation.test.ts +115 -0
  173. package/components/auth/AuthBanner.vue +15 -14
  174. package/components/auth/Principal.vue +0 -1
  175. package/components/auth/RoleDetailEdit.vue +44 -4
  176. package/components/auth/login/ldap.vue +2 -2
  177. package/components/auth/login/oidc.vue +6 -1
  178. package/components/fleet/FleetApplications.vue +174 -0
  179. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  180. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  181. package/components/fleet/FleetClusters.vue +25 -6
  182. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  183. package/components/fleet/FleetHelmOps.vue +123 -0
  184. package/components/fleet/FleetIntro.vue +58 -28
  185. package/components/fleet/FleetNoWorkspaces.vue +5 -1
  186. package/components/fleet/FleetOCIStorageSecret.vue +171 -0
  187. package/components/fleet/FleetRepos.vue +37 -80
  188. package/components/fleet/FleetResources.vue +69 -27
  189. package/components/fleet/FleetSummary.vue +26 -51
  190. package/components/fleet/FleetValuesFrom.vue +295 -0
  191. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  192. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  193. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
  194. package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
  195. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  196. package/components/fleet/dashboard/Empty.vue +73 -0
  197. package/components/fleet/dashboard/ResourceCard.vue +184 -0
  198. package/components/fleet/dashboard/ResourceCardSummary.vue +195 -0
  199. package/components/fleet/dashboard/ResourceDetails.vue +194 -0
  200. package/components/fleet/dashboard/ResourcePanel.vue +384 -0
  201. package/components/form/ArrayList.vue +144 -116
  202. package/components/form/BannerSettings.vue +117 -50
  203. package/components/form/ChangePassword.vue +3 -1
  204. package/components/form/ColorInput.vue +35 -6
  205. package/components/form/FileImageSelector.vue +1 -1
  206. package/components/form/Footer.vue +10 -4
  207. package/components/form/KeyValue.vue +92 -51
  208. package/components/form/LabeledSelect.vue +72 -54
  209. package/components/form/Labels.vue +91 -21
  210. package/components/form/MatchExpressions.vue +56 -9
  211. package/components/form/NameNsDescription.vue +12 -8
  212. package/components/form/Networking.vue +24 -19
  213. package/components/form/NotificationSettings.vue +15 -1
  214. package/components/form/ResourceLabeledSelect.vue +22 -8
  215. package/components/form/ResourceSelector.vue +27 -23
  216. package/components/form/ResourceTabs/index.vue +7 -1
  217. package/components/form/SSHKnownHosts/index.vue +14 -11
  218. package/components/form/SecretSelector.vue +18 -2
  219. package/components/form/Select.vue +57 -26
  220. package/components/form/SelectOrCreateAuthSecret.vue +6 -3
  221. package/components/form/SimpleSecretSelector.vue +17 -4
  222. package/components/form/Taints.vue +21 -2
  223. package/components/form/UnitInput.vue +21 -0
  224. package/components/form/ValueFromResource.vue +31 -19
  225. package/components/form/__tests__/ArrayList.test.ts +32 -0
  226. package/components/form/__tests__/ColorInput.test.ts +35 -0
  227. package/components/form/__tests__/KeyValue.test.ts +36 -0
  228. package/components/form/__tests__/LabeledSelect.test.ts +79 -2
  229. package/components/form/__tests__/Labels.test.ts +360 -0
  230. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  231. package/components/form/__tests__/Networking.test.ts +116 -0
  232. package/components/form/__tests__/SSHKnownHosts.test.ts +11 -2
  233. package/components/form/__tests__/Select.test.ts +37 -1
  234. package/components/form/__tests__/UnitInput.test.ts +23 -1
  235. package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
  236. package/components/formatter/ClusterLink.vue +5 -8
  237. package/components/formatter/Description.vue +30 -0
  238. package/components/formatter/FleetApplicationClustersReady.vue +77 -0
  239. package/components/formatter/FleetApplicationSource.vue +79 -0
  240. package/components/formatter/FleetSummaryGraph.vue +7 -0
  241. package/components/formatter/PodImages.vue +1 -1
  242. package/components/formatter/WorkloadHealthScale.vue +1 -1
  243. package/components/formatter/__tests__/ClusterLink.test.ts +2 -32
  244. package/components/formatter/__tests__/LiveDate.test.ts +10 -2
  245. package/components/google/AccountAccess.vue +209 -0
  246. package/components/google/types/gcp.d.ts +136 -0
  247. package/components/google/types/index.d.ts +101 -0
  248. package/components/google/util/__mocks__/gcp.ts +465 -0
  249. package/components/google/util/formatter.ts +82 -0
  250. package/components/google/util/gcp.ts +134 -0
  251. package/components/google/util/index.d.ts +11 -0
  252. package/components/nav/Favorite.vue +1 -1
  253. package/components/nav/Group.vue +5 -0
  254. package/components/nav/Header.vue +24 -38
  255. package/components/nav/NamespaceFilter.vue +141 -84
  256. package/components/nav/NotificationCenter/Notification.vue +484 -0
  257. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  258. package/components/nav/NotificationCenter/index.vue +148 -0
  259. package/components/nav/TopLevelMenu.helper.ts +55 -34
  260. package/components/nav/TopLevelMenu.vue +11 -0
  261. package/components/nav/Type.vue +4 -1
  262. package/components/nav/WindowManager/ContainerLogs.vue +87 -61
  263. package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
  264. package/components/nav/WindowManager/index.vue +3 -2
  265. package/components/templates/default.vue +0 -3
  266. package/components/templates/plain.vue +0 -3
  267. package/composables/drawer.ts +26 -0
  268. package/composables/focusTrap.ts +3 -3
  269. package/composables/resources.test.ts +63 -0
  270. package/composables/resources.ts +38 -0
  271. package/composables/useI18n.ts +12 -11
  272. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  273. package/config/labels-annotations.js +22 -11
  274. package/config/pagination-table-headers.js +8 -1
  275. package/config/private-label.js +0 -1
  276. package/config/product/auth.js +20 -3
  277. package/config/product/{cis.js → compliance.js} +23 -26
  278. package/config/product/explorer.js +49 -17
  279. package/config/product/fleet.js +77 -17
  280. package/config/product/manager.js +1 -29
  281. package/config/product/settings.js +23 -11
  282. package/config/query-params.js +16 -1
  283. package/config/roles.ts +2 -1
  284. package/config/router/navigation-guards/authentication.js +51 -2
  285. package/config/router/navigation-guards/index.js +5 -67
  286. package/config/router/routes.js +65 -31
  287. package/config/secret.ts +15 -0
  288. package/config/settings.ts +33 -16
  289. package/config/store.js +2 -0
  290. package/config/system-namespaces.js +1 -1
  291. package/config/table-headers.js +91 -30
  292. package/config/types.js +18 -7
  293. package/config/version.js +1 -1
  294. package/core/plugin-helpers.ts +3 -2
  295. package/core/plugin.ts +32 -7
  296. package/core/types.ts +25 -7
  297. package/detail/catalog.cattle.io.app.vue +5 -1
  298. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  299. package/detail/fleet.cattle.io.bundle.vue +70 -6
  300. package/detail/fleet.cattle.io.cluster.vue +28 -15
  301. package/detail/fleet.cattle.io.gitrepo.vue +11 -2
  302. package/detail/fleet.cattle.io.helmop.vue +157 -0
  303. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  304. package/detail/management.cattle.io.oidcclient.vue +369 -0
  305. package/detail/namespace.vue +0 -3
  306. package/detail/node.vue +20 -16
  307. package/detail/pod.vue +2 -2
  308. package/detail/provisioning.cattle.io.cluster.vue +16 -50
  309. package/detail/service.vue +10 -2
  310. package/detail/workload/index.vue +48 -39
  311. package/dialog/AddCustomBadgeDialog.vue +0 -1
  312. package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
  313. package/dialog/AddonConfigConfirmationDialog.vue +1 -1
  314. package/dialog/AssignToDialog.vue +176 -0
  315. package/dialog/ChangePasswordDialog.vue +106 -0
  316. package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
  317. package/dialog/DisableAuthProviderDialog.vue +101 -0
  318. package/dialog/DrainNode.vue +1 -1
  319. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
  320. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +87 -66
  321. package/dialog/FeatureFlagListDialog.vue +288 -0
  322. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  323. package/dialog/GenericPrompt.vue +1 -1
  324. package/dialog/HelmOpForceUpdateDialog.vue +132 -0
  325. package/{components/Import.vue → dialog/ImportDialog.vue} +8 -13
  326. package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
  327. package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -62
  328. package/dialog/MoveNamespaceDialog.vue +157 -0
  329. package/dialog/OidcClientSecretDialog.vue +117 -0
  330. package/dialog/RedeployWorkloadDialog.vue +164 -0
  331. package/dialog/RotateEncryptionKeyDialog.vue +10 -30
  332. package/dialog/ScalePoolDownDialog.vue +1 -1
  333. package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
  334. package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
  335. package/dialog/WechatDialog.vue +57 -0
  336. package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +15 -34
  337. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  338. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +60 -68
  339. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  340. package/edit/__tests__/service.test.ts +2 -1
  341. package/edit/auth/ldap/__tests__/config.test.ts +14 -0
  342. package/edit/auth/ldap/config.vue +24 -0
  343. package/edit/auth/oidc.vue +159 -93
  344. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  345. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  346. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  347. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  348. package/edit/configmap.vue +8 -2
  349. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  350. package/edit/fleet.cattle.io.gitrepo.vue +70 -256
  351. package/edit/fleet.cattle.io.helmop.vue +786 -0
  352. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  353. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  354. package/edit/logging-flow/index.vue +1 -0
  355. package/edit/logging.banzaicloud.io.output/index.vue +2 -1
  356. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
  357. package/edit/management.cattle.io.fleetworkspace.vue +44 -10
  358. package/edit/management.cattle.io.oidcclient.vue +162 -0
  359. package/edit/management.cattle.io.project.vue +4 -1
  360. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  361. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  362. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  363. package/edit/monitoring.coreos.com.receiver/auth.vue +3 -3
  364. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  365. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  366. package/edit/monitoring.coreos.com.route.vue +1 -0
  367. package/edit/namespace.vue +2 -4
  368. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  369. package/edit/networking.k8s.io.ingress/Certificate.vue +11 -3
  370. package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +37 -0
  371. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  372. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -14
  373. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +57 -62
  374. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +10 -16
  375. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.test.ts +72 -41
  376. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +17 -1
  377. package/edit/networking.k8s.io.networkpolicy/index.vue +23 -31
  378. package/edit/node.vue +1 -0
  379. package/edit/persistentvolume/index.vue +4 -1
  380. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
  381. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +69 -2
  382. package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
  383. package/edit/provisioning.cattle.io.cluster/index.vue +21 -73
  384. package/edit/provisioning.cattle.io.cluster/rke2.vue +535 -428
  385. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +48 -39
  386. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
  387. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  388. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -2
  389. package/edit/resources.cattle.io.restore.vue +1 -1
  390. package/edit/secret/basic.vue +1 -0
  391. package/edit/secret/index.vue +127 -15
  392. package/edit/service.vue +17 -29
  393. package/edit/serviceaccount.vue +4 -1
  394. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  395. package/edit/workload/index.vue +11 -15
  396. package/edit/workload/mixins/workload.js +0 -2
  397. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  398. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  399. package/list/fleet.cattle.io.helmop.vue +108 -0
  400. package/list/harvesterhci.io.management.cluster.vue +0 -17
  401. package/list/management.cattle.io.feature.vue +4 -288
  402. package/list/management.cattle.io.oidcclient.vue +108 -0
  403. package/list/management.cattle.io.user.vue +13 -20
  404. package/list/namespace.vue +6 -2
  405. package/list/node.vue +2 -0
  406. package/list/projectsecret.vue +345 -0
  407. package/list/secret.vue +109 -0
  408. package/list/workload.vue +6 -2
  409. package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
  410. package/machine-config/amazonec2.vue +3 -24
  411. package/machine-config/components/GCEImage.vue +374 -0
  412. package/machine-config/google.vue +617 -0
  413. package/machine-config/vmwarevsphere.vue +7 -17
  414. package/mixins/__tests__/brand.spec.ts +170 -0
  415. package/mixins/auth-config.js +8 -1
  416. package/mixins/brand.js +16 -17
  417. package/mixins/create-edit-view/impl.js +10 -1
  418. package/mixins/create-edit-view/index.js +5 -0
  419. package/mixins/preset.js +100 -0
  420. package/mixins/resource-fetch-api-pagination.js +73 -44
  421. package/mixins/resource-fetch.js +18 -8
  422. package/mixins/resource-table-watch.js +45 -0
  423. package/mixins/vue-select-overrides.js +1 -4
  424. package/models/__tests__/chart.test.ts +296 -0
  425. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
  426. package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  427. package/models/__tests__/node.test.ts +7 -63
  428. package/models/__tests__/workload.test.ts +1 -0
  429. package/models/chart.js +157 -2
  430. package/models/cluster/node.js +2 -1
  431. package/models/cluster.js +32 -2
  432. package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
  433. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  434. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  435. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  436. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  437. package/models/fleet-application.js +297 -0
  438. package/models/fleet.cattle.io.bundle.js +9 -8
  439. package/models/fleet.cattle.io.cluster.js +21 -4
  440. package/models/fleet.cattle.io.gitrepo.js +46 -382
  441. package/models/fleet.cattle.io.helmop.js +202 -0
  442. package/models/management.cattle.io.authconfig.js +1 -0
  443. package/models/management.cattle.io.cluster.js +0 -20
  444. package/models/management.cattle.io.feature.js +7 -1
  445. package/models/management.cattle.io.fleetworkspace.js +14 -1
  446. package/models/management.cattle.io.node.js +7 -22
  447. package/models/management.cattle.io.nodepool.js +12 -0
  448. package/models/management.cattle.io.oidcclient.js +18 -0
  449. package/models/management.cattle.io.registration.js +3 -0
  450. package/models/management.cattle.io.setting.js +0 -1
  451. package/models/namespace.js +12 -1
  452. package/models/provisioning.cattle.io.cluster.js +60 -97
  453. package/models/secret.js +157 -2
  454. package/models/service.js +28 -9
  455. package/models/storage.k8s.io.storageclass.js +2 -2
  456. package/models/workload.js +91 -51
  457. package/package.json +6 -5
  458. package/pages/about.vue +17 -61
  459. package/pages/account/index.vue +9 -1
  460. package/pages/auth/login.vue +2 -3
  461. package/pages/auth/verify.vue +13 -1
  462. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +36 -0
  463. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
  464. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +57 -0
  465. package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
  466. package/pages/c/_cluster/apps/charts/index.vue +501 -468
  467. package/pages/c/_cluster/apps/charts/install.vue +0 -1
  468. package/pages/c/_cluster/auth/roles/index.vue +19 -48
  469. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  470. package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
  471. package/pages/c/_cluster/explorer/index.vue +14 -3
  472. package/pages/c/_cluster/explorer/projectsecret.vue +34 -0
  473. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  474. package/pages/c/_cluster/fleet/__tests__/index.test.ts +720 -0
  475. package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
  476. package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
  477. package/pages/c/_cluster/fleet/application/create.vue +341 -0
  478. package/pages/c/_cluster/fleet/application/index.vue +139 -0
  479. package/pages/c/_cluster/fleet/graph/config.js +277 -0
  480. package/pages/c/_cluster/fleet/index.vue +866 -328
  481. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  482. package/pages/c/_cluster/longhorn/index.vue +5 -2
  483. package/pages/c/_cluster/settings/banners.vue +56 -2
  484. package/pages/c/_cluster/settings/brand.vue +2 -1
  485. package/pages/c/_cluster/settings/performance.vue +7 -26
  486. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  487. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  488. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
  489. package/pages/c/_cluster/uiplugins/index.vue +98 -55
  490. package/pages/explorer/resource/detail/configmap.vue +42 -0
  491. package/pages/explorer/resource/detail/projectsecret.vue +9 -0
  492. package/pages/explorer/resource/detail/secret.vue +63 -0
  493. package/pages/home.vue +8 -104
  494. package/pages/prefs.vue +0 -1
  495. package/pages/support/index.vue +4 -6
  496. package/plugins/clean-html.js +2 -0
  497. package/plugins/dashboard-store/__tests__/actions.test.ts +4 -1
  498. package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
  499. package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
  500. package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
  501. package/plugins/dashboard-store/actions.js +212 -55
  502. package/plugins/dashboard-store/getters.js +112 -24
  503. package/plugins/dashboard-store/mutations.js +61 -12
  504. package/plugins/dashboard-store/normalize.js +29 -19
  505. package/plugins/dashboard-store/resource-class.js +132 -49
  506. package/plugins/steve/__tests__/getters.test.ts +19 -12
  507. package/plugins/steve/__tests__/steve-class.test.ts +1 -0
  508. package/plugins/steve/__tests__/subscribe.spec.ts +324 -1
  509. package/plugins/steve/actions.js +37 -24
  510. package/plugins/steve/getters.js +47 -12
  511. package/plugins/steve/resourceWatcher.js +10 -3
  512. package/plugins/steve/steve-class.js +5 -0
  513. package/plugins/steve/steve-pagination-utils.ts +225 -43
  514. package/plugins/steve/subscribe.js +418 -53
  515. package/plugins/steve/worker/web-worker.advanced.js +5 -1
  516. package/rancher-components/Banner/Banner.test.ts +51 -3
  517. package/rancher-components/Banner/Banner.vue +37 -6
  518. package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
  519. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -9
  520. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +51 -0
  521. package/rancher-components/Form/LabeledInput/LabeledInput.vue +21 -3
  522. package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
  523. package/rancher-components/Form/Radio/RadioButton.vue +21 -5
  524. package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
  525. package/rancher-components/Form/Radio/RadioGroup.vue +81 -38
  526. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +4 -0
  527. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +22 -1
  528. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  529. package/rancher-components/RcButton/RcButton.vue +1 -1
  530. package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
  531. package/rancher-components/RcDropdown/RcDropdown.vue +6 -0
  532. package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -55
  533. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +69 -0
  534. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +93 -0
  535. package/rancher-components/RcDropdown/RcDropdownMenu.vue +7 -8
  536. package/rancher-components/RcDropdown/index.ts +2 -0
  537. package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
  538. package/rancher-components/RcDropdown/useDropdownItem.ts +92 -0
  539. package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
  540. package/rancher-components/RcItemCard/RcItemCard.vue +430 -0
  541. package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
  542. package/rancher-components/RcItemCard/index.ts +2 -0
  543. package/rancher-components/StringList/StringList.vue +1 -1
  544. package/scripts/extension/publish +1 -1
  545. package/static/loading-indicator.html +1 -1
  546. package/store/action-menu.js +26 -56
  547. package/store/auth.js +3 -0
  548. package/store/catalog.js +85 -25
  549. package/store/features.js +0 -1
  550. package/store/growl.js +97 -8
  551. package/store/i18n.js +1 -1
  552. package/store/index.js +44 -14
  553. package/store/notifications.ts +426 -0
  554. package/store/prefs.js +2 -8
  555. package/store/slideInPanel.ts +6 -0
  556. package/store/type-map.js +34 -17
  557. package/store/type-map.utils.ts +49 -6
  558. package/store/uiplugins.ts +15 -1
  559. package/types/fleet.d.ts +60 -1
  560. package/types/kube/kube-api.ts +34 -0
  561. package/types/notifications/index.ts +74 -0
  562. package/types/resources/fleet.d.ts +43 -0
  563. package/types/resources/pod-security-admission.ts +36 -0
  564. package/types/resources/settings.d.ts +107 -0
  565. package/types/resources/userPreferences.d.ts +13 -0
  566. package/types/shell/index.d.ts +971 -745
  567. package/types/store/dashboard-store.types.ts +57 -4
  568. package/types/store/pagination.types.ts +41 -9
  569. package/types/store/subscribe.types.ts +50 -0
  570. package/utils/__mocks__/tabbable.js +13 -0
  571. package/utils/__tests__/back-off.test.ts +354 -0
  572. package/utils/__tests__/create-yaml.test.ts +235 -0
  573. package/utils/__tests__/fleet.test.ts +148 -0
  574. package/utils/__tests__/kontainer.test.ts +19 -0
  575. package/utils/__tests__/object.test.ts +54 -1
  576. package/utils/__tests__/string.test.ts +273 -1
  577. package/utils/__tests__/time.test.ts +31 -0
  578. package/utils/auth.js +41 -6
  579. package/utils/back-off.ts +176 -0
  580. package/utils/cluster.js +24 -20
  581. package/utils/create-yaml.js +103 -9
  582. package/utils/crypto/encryption.ts +103 -0
  583. package/utils/cspAdaptor.ts +51 -0
  584. package/utils/error.js +0 -5
  585. package/utils/fleet-types.ts +0 -0
  586. package/utils/fleet.ts +204 -74
  587. package/utils/grafana.js +1 -0
  588. package/utils/kontainer.ts +3 -5
  589. package/utils/object.js +36 -12
  590. package/utils/pagination-utils.ts +50 -3
  591. package/utils/pagination-wrapper.ts +132 -50
  592. package/utils/perf-setting.utils.ts +28 -0
  593. package/utils/release-notes.ts +48 -0
  594. package/utils/selector-typed.ts +210 -0
  595. package/utils/selector.js +29 -6
  596. package/utils/settings.ts +4 -1
  597. package/utils/string.js +24 -0
  598. package/utils/style.ts +39 -0
  599. package/utils/{time.js → time.ts} +25 -6
  600. package/utils/uiplugins.ts +41 -8
  601. package/utils/v-sphere.ts +5 -1
  602. package/utils/validators/formRules/__tests__/index.test.ts +76 -6
  603. package/utils/validators/formRules/index.ts +99 -4
  604. package/utils/window.js +11 -7
  605. package/.DS_Store +0 -0
  606. package/components/AssignTo.vue +0 -199
  607. package/components/DisableAuthProviderModal.vue +0 -115
  608. package/components/MoveModal.vue +0 -167
  609. package/components/PromptChangePassword.vue +0 -123
  610. package/components/ResourceList/Masthead-btn.vue +0 -225
  611. package/components/__tests__/ApplicationCard.test.ts +0 -27
  612. package/components/cards/ApplicationCard.vue +0 -145
  613. package/components/fleet/FleetBundleResources.vue +0 -86
  614. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
  615. package/components/formatter/RKETemplateName.vue +0 -37
  616. package/config/product/legacy.js +0 -62
  617. package/config/secret.js +0 -14
  618. package/dialog/SaveAsRKETemplateDialog.vue +0 -139
  619. package/models/etcdbackup.js +0 -45
  620. package/pages/auth copy/login.vue +0 -595
  621. package/pages/auth copy/logout.vue +0 -47
  622. package/pages/auth copy/setup.vue +0 -523
  623. package/pages/auth copy/verify.vue +0 -203
  624. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
  625. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  626. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  627. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  628. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
@@ -86,8 +86,16 @@ export function createLoadArgs(ctx, dataType) {
86
86
  };
87
87
  }
88
88
 
89
+ /**
90
+ * Add or update the given resource in the store
91
+ *
92
+ * invalidatePageCache
93
+ * - if something calls `load` then the cache no longer has a page so we invalidate it
94
+ * - however on resource create or remove this can lead to lists showing nothing... before the new page is fetched
95
+ * - for those cases avoid invaliding the page cache
96
+ */
89
97
  export function load(state, {
90
- data, ctx, existing, cachedArgs
98
+ data, ctx, existing, cachedArgs, invalidatePageCache = true,
91
99
  }) {
92
100
  const { getters } = ctx;
93
101
  // Optimisation. This can run once per resource loaded.., so pass in from parent
@@ -130,8 +138,12 @@ export function load(state, {
130
138
  }
131
139
  } else {
132
140
  if (inMap) {
141
+ // In theory cached `entry` should match provided `existing`, so changes merged from `data` into `entry` should be reflected in `existing`.
142
+ // However.. there's a disconnect happening somewhere so merge data into `existing` before merging into `entry`
143
+ const latestEntry = existing && entry !== existing ? replaceResource(existing, data, getters) : data;
144
+
133
145
  // There's already an entry in the store, so merge changes into it. The list entry is a reference to the map (and vice versa)
134
- entry = replaceResource(entry, data, getters);
146
+ entry = replaceResource(entry, latestEntry, getters);
135
147
  } else {
136
148
  // There's no entry, make a new proxy
137
149
  entry = reactive(classify(ctx, data));
@@ -164,7 +176,8 @@ export function load(state, {
164
176
  }
165
177
  }
166
178
 
167
- cache.havePage = false;
179
+ // see `invalidatePageCache` description above
180
+ cache.havePage = invalidatePageCache ? false : cache.havePage;
168
181
 
169
182
  return entry;
170
183
  }
@@ -413,13 +426,18 @@ export default {
413
426
  loadSelector(state, {
414
427
  type, entries, ctx, selector, revision
415
428
  }) {
429
+ const keyField = ctx.getters.keyFieldForType(type);
416
430
  const cache = registerType(state, type);
417
- const cachedArgs = createLoadArgs(ctx, entries?.[0]?.type);
431
+ const proxies = reactive(entries.map((x) => classify(ctx, x)));
418
432
 
419
- for ( const data of entries ) {
420
- load(state, {
421
- data, ctx, cachedArgs
422
- });
433
+ clear(cache.list);
434
+ cache.map.clear();
435
+ cache.generation++;
436
+
437
+ addObjects(cache.list, proxies);
438
+
439
+ for ( let i = 0 ; i < proxies.length ; i++ ) {
440
+ cache.map.set(proxies[i][keyField], proxies[i]);
423
441
  }
424
442
 
425
443
  cache.haveSelector[selector] = true;
@@ -471,29 +489,60 @@ export default {
471
489
  data,
472
490
  ctx,
473
491
  pagination,
492
+ revision
474
493
  }) {
475
494
  if (!data) {
476
495
  return;
477
496
  }
497
+ // We loop over data three times in this mutator, which is bad
498
+ // However we're only dealing with pageSize worth of data and splitting out into three loops improves legibility
478
499
 
479
500
  const keyField = ctx.getters.keyFieldForType(type);
480
- const proxies = reactive(data.map((x) => classify(ctx, x)));
501
+
502
+ // Why don't we just replace the map? Because we
503
+ // 1. nav to list, subscribe to changes
504
+ // 2. nav to resource in list
505
+ // 3. update to page comes over
506
+ // 4. need to update the reference the detail list uses
507
+ const proxiesMap = {};
508
+ const proxies = reactive(data.map((x) => {
509
+ proxiesMap[x[keyField]] = true;
510
+
511
+ return classify(ctx, x);
512
+ }));
481
513
  const cache = registerType(state, type);
482
514
 
483
- clear(cache.list);
484
- cache.map.clear();
485
515
  cache.generation++;
486
516
 
517
+ // Update list
518
+ clear(cache.list);
487
519
  addObjects(cache.list, proxies);
488
520
 
521
+ // Update Map (remove stale)
522
+ cache.map.forEach((value, key) => {
523
+ if (!proxiesMap[value[keyField]]) {
524
+ cache.map.delete(key);
525
+ }
526
+ });
527
+
528
+ // Update Map (update existing / add latest)
489
529
  for ( let i = 0 ; i < proxies.length ; i++ ) {
490
- cache.map.set(proxies[i][keyField], proxies[i]);
530
+ // This could probably be merged with the first loop above
531
+ const existing = cache.map.get(proxies[i][keyField]);
532
+ const latest = proxies[i];
533
+
534
+ if (existing) {
535
+ replaceResource(existing, latest, ctx.getters);
536
+ } else {
537
+ cache.map.set(latest[keyField], latest);
538
+ }
491
539
  }
492
540
 
493
541
  // havePage is of type `StorePagination`
494
542
  cache.havePage = pagination;
495
543
  cache.haveNamespace = undefined;
496
544
  cache.haveAll = undefined;
545
+ cache.revision = revision;
497
546
 
498
547
  return proxies;
499
548
  },
@@ -2,8 +2,6 @@ import { SCHEMA } from '@shell/config/types';
2
2
 
3
3
  import { applyChangeset, changeset, changesetConflicts } from '@shell/utils/object';
4
4
 
5
- import { cloud2harvesterhci } from '@shell/utils/router'
6
-
7
5
  export const KEY_FIELD_FOR = {
8
6
  [SCHEMA]: '_id',
9
7
  default: 'id',
@@ -19,28 +17,40 @@ export function normalizeType(type) {
19
17
  return type;
20
18
  }
21
19
 
22
- // Detect and resolve conflicts from a 409 response.
23
- // If they are resolved, return a false-y value
24
- // Else they can't be resolved, return an array of errors to show to the user.
25
- export async function handleConflict(initialValueJSON, value, liveValue, rootGetters, store, storeNamespace) {
26
- const orig = await store.dispatch(`${ storeNamespace }/cleanForDiff`, initialValueJSON, { root: true });
27
- const user = await store.dispatch(`${ storeNamespace }/cleanForDiff`, value.toJSON(), { root: true });
28
- const cur = await store.dispatch(`${ storeNamespace }/cleanForDiff`, liveValue.toJSON(), { root: true });
29
-
30
- const bgChange = changeset(orig, cur);
31
- const userChange = changeset(orig, user);
32
- const actualConflicts = changesetConflicts(bgChange, userChange);
33
-
34
- console.log('Background Change', bgChange); // eslint-disable-line no-console
35
- console.log('User Change', userChange); // eslint-disable-line no-console
20
+ /**
21
+ * Detect and resolve conflicts from a 409 response.
22
+ *
23
+ * @param {*} initialValue the initial value before changes
24
+ * @param {*} userValue the value containing the local changes. this function will intentionally mutate this to contain changes made from the server
25
+ * @param {*} serverValue the very latest value from the server
26
+ * @returns If `value` has been successfully updated return a false-y value. Else they can't be resolved, return an array of errors to show the user.
27
+ */
28
+ export async function handleConflict(initialValue, userValue, serverValue, store, storeNamespace, toJSON = (x) => x.toJSON()) {
29
+ // initial value
30
+ const initial = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(initialValue), { root: true });
31
+ // changed value (user edits)
32
+ const user = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(userValue), { root: true });
33
+ // server value
34
+ const server = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(serverValue), { root: true });
35
+
36
+ // changes made to the server value
37
+ const serverChanges = changeset(initial, server);
38
+ // changes made locally
39
+ const userChanges = changeset(initial, user);
40
+ // Any incompatibilities between changes made locally and the server?
41
+ const actualConflicts = changesetConflicts(serverChanges, userChanges);
42
+
43
+ console.log('Background Change', serverChanges); // eslint-disable-line no-console
44
+ console.log('User Change', userChanges); // eslint-disable-line no-console
36
45
  console.log('Conflicts', actualConflicts); // eslint-disable-line no-console
37
46
 
38
- value.metadata.resourceVersion = liveValue.metadata.resourceVersion;
39
- applyChangeset(value, bgChange);
47
+ userValue.metadata.resourceVersion = serverValue.metadata.resourceVersion;
48
+ // Apply changes made on the server to the changed (user) value
49
+ applyChangeset(userValue, serverChanges);
40
50
 
41
51
  if ( actualConflicts.length ) {
42
52
  // Stop the save and let the user inspect and continue editing
43
- const out = [rootGetters['i18n/t']('validation.conflict', { fields: actualConflicts.join(', '), fieldCount: actualConflicts.length })];
53
+ const out = [store.getters['i18n/t']('validation.conflict', { fields: actualConflicts.join(', '), fieldCount: actualConflicts.length })];
44
54
 
45
55
  return out;
46
56
  } else {
@@ -32,9 +32,10 @@ import isFunction from 'lodash/isFunction';
32
32
  import isString from 'lodash/isString';
33
33
  import { markRaw } from 'vue';
34
34
 
35
+ import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
35
36
  import { ExtensionPoint, ActionLocation } from '@shell/core/types';
36
37
  import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
37
- import { harvesterhci2cloud, cloud2harvesterhci } from '@shell/utils/router'
38
+ import { parse } from '@shell/utils/selector';
38
39
 
39
40
  export const DNS_LIKE_TYPES = ['dnsLabel', 'dnsLabelRestricted', 'hostname'];
40
41
 
@@ -736,6 +737,17 @@ export default class Resource {
736
737
  );
737
738
  }
738
739
 
740
+ get stateColorPair() {
741
+ return {
742
+ state: this.stateDisplay,
743
+ color: this.stateSimpleColor
744
+ };
745
+ }
746
+
747
+ get stateSimpleColor() {
748
+ return this.stateColor.replace('text-', '');
749
+ }
750
+
739
751
  get stateBackground() {
740
752
  return this.stateColor.replace('text-', 'bg-');
741
753
  }
@@ -886,6 +898,10 @@ export default class Resource {
886
898
  return out;
887
899
  }
888
900
 
901
+ get canEdit() {
902
+ return this.canUpdate && this.canCustomEdit;
903
+ }
904
+
889
905
  // You can add custom actions by overriding your own availableActions (and probably reading super._availableActions)
890
906
  get _availableActions() {
891
907
  // get menu actions available by plugins configuration
@@ -897,42 +913,42 @@ export default class Resource {
897
913
  {
898
914
  action: this.canUpdate ? 'goToEdit' : 'goToViewConfig',
899
915
  label: this.t(this.canUpdate ? 'action.edit' : 'action.view'),
900
- // icon: 'icon icon-edit',
916
+ icon: 'icon icon-edit',
901
917
  enabled: this.canCustomEdit,
902
918
  },
903
- // {
904
- // action: this.canEditYaml ? 'goToEditYaml' : 'goToViewYaml',
905
- // label: this.t(this.canEditYaml ? 'action.editYaml' : 'action.viewYaml'),
906
- // icon: 'icon icon-file',
907
- // enabled: this.canYaml,
908
- // },
919
+ {
920
+ action: this.canEditYaml ? 'goToEditYaml' : 'goToViewYaml',
921
+ label: this.t(this.canEditYaml ? 'action.editYaml' : 'action.viewYaml'),
922
+ icon: 'icon icon-file',
923
+ enabled: this.canYaml,
924
+ },
909
925
  {
910
926
  action: (this.canCustomEdit ? 'goToClone' : 'cloneYaml'),
911
927
  label: this.t('action.clone'),
912
- // icon: 'icon icon-copy',
913
- enabled: this.canClone && this.canCreate && (this.canCustomEdit || this.canYaml)&& this.schema.id!=='event',
928
+ icon: 'icon icon-copy',
929
+ enabled: this.canClone && this.canCreate && (this.canCustomEdit || this.canYaml),
930
+ },
931
+ { divider: true },
932
+ {
933
+ action: 'download',
934
+ label: this.t('action.download'),
935
+ icon: 'icon icon-download',
936
+ bulkable: true,
937
+ bulkAction: 'downloadBulk',
938
+ enabled: this.canYaml,
939
+ weight: -9,
940
+ },
941
+ {
942
+ action: 'viewInApi',
943
+ label: this.t('action.viewInApi'),
944
+ icon: 'icon icon-external-link',
945
+ enabled: this.canViewInApi,
914
946
  },
915
- // { divider: true },
916
- // {
917
- // action: 'download',
918
- // label: this.t('action.download'),
919
- // icon: 'icon icon-download',
920
- // bulkable: true,
921
- // bulkAction: 'downloadBulk',
922
- // enabled: this.canYaml,
923
- // weight: -9,
924
- // },
925
- // {
926
- // action: 'viewInApi',
927
- // label: this.t('action.viewInApi'),
928
- // icon: 'icon icon-external-link',
929
- // enabled: this.canViewInApi,
930
- // },
931
947
  {
932
948
  action: 'promptRemove',
933
949
  altAction: 'remove',
934
950
  label: this.t('action.remove'),
935
- // icon: 'icon icon-trash',
951
+ icon: 'icon icon-trash',
936
952
  bulkable: true,
937
953
  enabled: this.canDelete,
938
954
  bulkAction: 'promptRemove',
@@ -1180,7 +1196,9 @@ export default class Resource {
1180
1196
  }
1181
1197
 
1182
1198
  // @TODO remove this once the API maps steve _type <-> k8s type in both directions
1183
- opt.data = this.toSave() || { ...this };
1199
+ // `JSON.parse(JSON.stringify` - Completely disconnect the object we're going to send and `this`. This ensures that properties
1200
+ // removed from opt.data before sending (as part of cleanForSave) are not stripped from where they're still needed (`this`)
1201
+ opt.data = this.toSave() || JSON.parse(JSON.stringify(this));
1184
1202
 
1185
1203
  if (opt.data._type) {
1186
1204
  opt.data.type = opt.data._type;
@@ -1247,7 +1265,18 @@ export default class Resource {
1247
1265
 
1248
1266
  const res = await this.$dispatch('request', { opt, type: this.type } );
1249
1267
 
1250
- if ( res?._status === 204 ) {
1268
+ // In theory...
1269
+ // 200 - resource could have finalizer (could hang around, keep resource to show deleting state)
1270
+ // 204 - resource should be gone gone (so remove immediately)
1271
+ // However...
1272
+ // 200 - this is the only status code returned
1273
+ if ( res?._status === 200 ) {
1274
+ // Show state (probably terminating) immediately, don't wait for resource.change or debounced resource.changes update
1275
+ // It would be neater to only do this in the debounced resource.changes world, but there's no neat / complete way to do this (paginationUtils will cause dep issues if imported)
1276
+ await this.$dispatch('load', {
1277
+ data: res, existing: this, invalidatePageCache: false
1278
+ });
1279
+ } else if ( res?._status === 204 ) {
1251
1280
  // If there's no body, assume the resource was immediately deleted
1252
1281
  // and drop it from the store as if a remove event happened.
1253
1282
  await this.$dispatch('ws.resource.remove', { data: this });
@@ -1293,8 +1322,7 @@ export default class Resource {
1293
1322
  }
1294
1323
 
1295
1324
  get detailLocation() {
1296
- let location = this._detailLocation;
1297
- return location;
1325
+ return this._detailLocation;
1298
1326
  }
1299
1327
 
1300
1328
  goToDetail() {
@@ -1320,9 +1348,7 @@ export default class Resource {
1320
1348
  this.currentRouter().push(location);
1321
1349
  }
1322
1350
 
1323
- goToEdit(moreQuery = {}) {
1324
- const location = this.detailLocation;
1325
-
1351
+ goToEdit(moreQuery = {}, location = this.detailLocation) {
1326
1352
  location.query = {
1327
1353
  ...location.query,
1328
1354
  [MODE]: _EDIT,
@@ -1505,11 +1531,11 @@ export default class Resource {
1505
1531
  }
1506
1532
  }
1507
1533
 
1508
- async saveYaml(yaml) {
1509
- await this._saveYaml(yaml);
1534
+ async saveYaml(yaml, initialYaml) {
1535
+ await this._saveYaml(yaml, initialYaml);
1510
1536
  }
1511
1537
 
1512
- async _saveYaml(yaml) {
1538
+ async _saveYaml(yaml, initialYaml, depth = 0) {
1513
1539
  /* Multipart support, but need to know the right cluster and work for management store
1514
1540
  and "apply" seems to only work for create, not update.
1515
1541
 
@@ -1547,20 +1573,56 @@ export default class Resource {
1547
1573
  data: yaml
1548
1574
  });
1549
1575
  } else {
1550
- res = await this.followLink('update', {
1551
- method: 'PUT',
1552
- headers,
1553
- data: yaml
1554
- });
1576
+ try {
1577
+ res = await this.followLink('update', {
1578
+ method: 'PUT',
1579
+ headers,
1580
+ data: yaml
1581
+ });
1582
+ } catch (err) {
1583
+ const IS_ERR_409 = err.status === 409 || err._status === 409;
1584
+
1585
+ // Conflict, the resource being edited has changed since starting editing
1586
+ if (IS_ERR_409 && depth === 0 && initialYaml) {
1587
+ const inStore = this.$rootGetters['currentStore'](this.type);
1588
+
1589
+ const initialValue = jsyaml.load(initialYaml);
1590
+ const value = jsyaml.load(yaml);
1591
+ const liveValue = this.$rootGetters[`${ inStore }/byId`](this.type, this.id);
1592
+
1593
+ const handledConflictErr = await handleConflict(
1594
+ initialValue,
1595
+ value,
1596
+ liveValue,
1597
+ {
1598
+ dispatch: this.$dispatch,
1599
+ getters: this.$rootGetters
1600
+ },
1601
+ this.$rootGetters['currentStore'](this.type),
1602
+ (v) => v.toJSON ? v.toJSON() : v
1603
+ );
1604
+
1605
+ if (handledConflictErr === false) {
1606
+ // It was automatically figured out, save again
1607
+ await this._saveYaml(jsyaml.dump(value), null, depth + 1);
1608
+ } else {
1609
+ throw handledConflictErr;
1610
+ }
1611
+ } else {
1612
+ throw err;
1613
+ }
1614
+ }
1555
1615
  }
1556
1616
 
1557
- await this.$dispatch(`load`, {
1558
- data: res,
1559
- existing: (isCreate ? this : undefined)
1560
- });
1617
+ if (res) {
1618
+ await this.$dispatch(`load`, {
1619
+ data: res,
1620
+ existing: (isCreate ? this : undefined)
1621
+ });
1561
1622
 
1562
- if (this.isSpoofed) {
1563
- await this.$dispatch('cluster/findAll', { type: this.type, opt: { force: true } }, { root: true });
1623
+ if (this.isSpoofed) {
1624
+ await this.$dispatch('cluster/findAll', { type: this.type, opt: { force: true } }, { root: true });
1625
+ }
1564
1626
  }
1565
1627
  }
1566
1628
 
@@ -1793,6 +1855,7 @@ export default class Resource {
1793
1855
  }
1794
1856
 
1795
1857
  if ( r.selector ) {
1858
+ // A selector is a stringified version of a matchLabel (https://github.com/kubernetes/apimachinery/blob/master/pkg/labels/selector.go#L1010)
1796
1859
  addObjects(out.selectors, {
1797
1860
  type: r.toType,
1798
1861
  namespace: r.toNamespace,
@@ -1836,15 +1899,35 @@ export default class Resource {
1836
1899
  }
1837
1900
 
1838
1901
  async _findRelationship(rel, direction) {
1902
+ // Find resources for this resource's metadata.relationships (steve prop)
1903
+ // These will either reference a selector (stringified matchLabels) OR specific resources (ids)
1839
1904
  const { selectors, ids } = this._relationshipsFor(rel, direction);
1840
1905
  const out = [];
1841
1906
 
1907
+ // Find all the resources that match the selector
1842
1908
  for ( const sel of selectors ) {
1843
- const matching = await this.$dispatch('findMatching', sel);
1909
+ const {
1910
+ type,
1911
+ selector,
1912
+ namespace,
1913
+ opt,
1914
+ } = sel;
1915
+ const matching = await this.$dispatch('findLabelSelector', {
1916
+ type,
1917
+ matching: {
1918
+ namespace,
1919
+ labelSelector: { matchExpressions: parse(selector) }
1920
+ },
1921
+ opts: {
1922
+ transient: true,
1923
+ ...opt,
1924
+ },
1925
+ });
1844
1926
 
1845
1927
  addObjects(out, matching.data);
1846
1928
  }
1847
1929
 
1930
+ // Find all the resources that match the required id's
1848
1931
  for ( const obj of ids ) {
1849
1932
  const { type, id } = obj;
1850
1933
  let matching = this.$getters['byId'](type, id);
@@ -1,6 +1,8 @@
1
1
  import _getters from '@shell/plugins/steve/getters';
2
2
 
3
- const { urlFor, urlOptions, pathExistsInSchema } = _getters;
3
+ const {
4
+ urlFor, urlOptions, pathExistsInSchema, isSteveUrl
5
+ } = _getters;
4
6
 
5
7
  describe('steve: getters:', () => {
6
8
  describe('urlFor', () => {
@@ -66,18 +68,17 @@ describe('steve: getters:', () => {
66
68
  });
67
69
 
68
70
  describe('urlOptions', () => {
69
- // we're not testing function output based off of state or getter inputs here since they are dependencies
70
- const state = { config: { baseUrl: 'protocol' } };
71
- const getters = {
72
- normalizeType: (type) => type,
73
- // this has its own tests so it just returns the input string
74
- urlOptions: (string) => string
75
- };
76
-
77
- const urlOptionsGetter = urlOptions();
71
+ const urlOptionsGetter = urlOptions(undefined, {
72
+ isSteveUrl: isSteveUrl(),
73
+ isSteveCacheUrl: () => false,
74
+ });
75
+ const urlOptionsGetterVaiOn = urlOptions(undefined, {
76
+ isSteveUrl: isSteveUrl(),
77
+ isSteveCacheUrl: () => true,
78
+ });
78
79
 
79
80
  it('expects urlOptions to return a function', () => {
80
- expect(typeof urlOptions(state, getters)).toBe('function');
81
+ expect(typeof urlOptions()).toBe('function');
81
82
  });
82
83
  it('returns undefined when called without params', () => {
83
84
  expect(urlOptionsGetter()).toBeUndefined();
@@ -103,6 +104,12 @@ describe('steve: getters:', () => {
103
104
  it('returns a string with a multiple filter statements applied and formatted for steve if a single filter statement is applied and the url starts with "/v1"', () => {
104
105
  expect(urlOptionsGetter('/v1/foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?filter=bar=baz&far=faz&exclude=metadata.managedFields');
105
106
  });
107
+ it('returns a string with correct equality for vai off', () => {
108
+ expect(urlOptionsGetter('/v1/foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?filter=bar=baz&far=faz&exclude=metadata.managedFields');
109
+ });
110
+ it('returns a string with correct equality for vai on', () => {
111
+ expect(urlOptionsGetterVaiOn('/v1/foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?filter=bar~baz&far~faz&exclude=metadata.managedFields');
112
+ });
106
113
  it('returns a string with a labelSelector and formatted for steve if the url starts with "/v1"', () => {
107
114
  expect(urlOptionsGetter('/v1/foo', { labelSelector: 'a=b' })).toBe('/v1/foo?labelSelector=a=b&exclude=metadata.managedFields');
108
115
  });
@@ -113,7 +120,7 @@ describe('steve: getters:', () => {
113
120
  expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar');
114
121
  });
115
122
  it('returns a string without an exclude statement for "managedFields" if omitExcludeFields includes it and the url starts with "/v1/"', () => {
116
- expect(urlOptionsGetter('/v1/foo', { omitExcludeFields: ['metadata.managedFields'] })).toBe('/v1/foo?');
123
+ expect(urlOptionsGetter('/v1/foo', { omitExcludeFields: ['metadata.managedFields'] })).toBe('/v1/foo');
117
124
  });
118
125
  it('returns a string without an exclude statement if excludeFields is set but the url does not start with "/v1/"', () => {
119
126
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
@@ -32,6 +32,7 @@ describe('class: Steve', () => {
32
32
  clusterName: 'whatever',
33
33
  deletionGracePeriodSeconds: 'whatever',
34
34
  generateName: 'whatever',
35
+ ownerReferences: 'whatever',
35
36
  },
36
37
  spec: { versions: {} }
37
38
  };