@rancher/shell 3.0.12-rc.1 → 3.0.12-rc.3

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 (376) hide show
  1. package/apis/impl/apis.ts +6 -0
  2. package/apis/index.ts +26 -0
  3. package/apis/intf/resources-api/cluster-api.ts +18 -0
  4. package/apis/intf/resources-api/mgmt-api.ts +15 -0
  5. package/apis/intf/resources-api/resource-base.ts +107 -0
  6. package/apis/intf/resources-api/resource-constants.ts +147 -0
  7. package/apis/intf/resources-api/resources-api.ts +143 -0
  8. package/apis/intf/resources.ts +49 -0
  9. package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
  10. package/apis/intf/shell-api/proxy.ts +216 -0
  11. package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
  12. package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
  13. package/apis/intf/shell.ts +12 -6
  14. package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
  15. package/apis/resources/index.ts +22 -0
  16. package/apis/resources/resources-api-class.ts +187 -0
  17. package/apis/shell/__tests__/proxy.test.ts +369 -0
  18. package/apis/shell/index.ts +8 -1
  19. package/apis/shell/modal.ts +4 -1
  20. package/apis/shell/notifications.ts +9 -6
  21. package/apis/shell/proxy.ts +256 -0
  22. package/apis/shell/slide-in.ts +4 -1
  23. package/apis/vue-shim.d.ts +2 -1
  24. package/assets/data/aws-regions.json +4 -0
  25. package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
  26. package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
  27. package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
  28. package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
  29. package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
  30. package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
  31. package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
  32. package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
  33. package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
  34. package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
  35. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
  36. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
  37. package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
  38. package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
  39. package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
  40. package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
  41. package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
  42. package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
  43. package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
  44. package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
  45. package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
  46. package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
  47. package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
  48. package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
  49. package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
  50. package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
  51. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
  52. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
  53. package/assets/images/providers/entraid-black.svg +4 -0
  54. package/assets/images/providers/entraid.svg +9 -0
  55. package/assets/images/vendor/entraid.svg +9 -0
  56. package/assets/styles/app.scss +0 -1
  57. package/assets/styles/base/_variables.scss +2 -0
  58. package/assets/styles/fonts/_fontstack.scss +132 -8
  59. package/assets/translations/en-us.yaml +41 -22
  60. package/assets/translations/zh-hans.yaml +4 -8
  61. package/chart/__tests__/S3.test.ts +10 -3
  62. package/chart/monitoring/index.vue +10 -1
  63. package/components/ActionDropdownShell.vue +2 -1
  64. package/components/CountBox.vue +20 -0
  65. package/components/CreateDriver.vue +0 -12
  66. package/components/CruResourceFooter.vue +9 -5
  67. package/components/DetailText.vue +12 -3
  68. package/components/ExplorerProjectsNamespaces.vue +1 -1
  69. package/components/InstallHelmCharts.vue +2 -2
  70. package/components/LandingPagePreference.vue +14 -5
  71. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
  72. package/components/Resource/Detail/Metadata/index.vue +6 -0
  73. package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
  74. package/components/Resource/Detail/SpacedRow.vue +3 -1
  75. package/components/Resource/Detail/TitleBar/index.vue +10 -11
  76. package/components/ResourceList/Masthead.vue +12 -8
  77. package/components/SelectIconGrid.vue +5 -10
  78. package/components/SingleClusterInfo.vue +1 -0
  79. package/components/SortableTable/__tests__/sorting.test.ts +126 -0
  80. package/components/SortableTable/index.vue +6 -9
  81. package/components/SortableTable/selection.js +23 -5
  82. package/components/SortableTable/sorting.js +6 -3
  83. package/components/Wizard.vue +14 -13
  84. package/components/__tests__/CountBox.test.ts +72 -0
  85. package/components/__tests__/DetailText.test.ts +113 -0
  86. package/components/fleet/FleetBundles.vue +100 -12
  87. package/components/fleet/FleetClusterTargets/index.vue +54 -15
  88. package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
  89. package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
  90. package/components/form/InputWithSelect.vue +18 -10
  91. package/components/form/KeyValue.vue +17 -1
  92. package/components/form/LabeledSelect.vue +101 -26
  93. package/components/form/NameNsDescription.vue +11 -0
  94. package/components/form/Security.vue +6 -2
  95. package/components/form/Select.vue +73 -56
  96. package/components/form/ServiceNameSelect.vue +13 -11
  97. package/components/form/WorkloadPorts.vue +2 -7
  98. package/components/form/__tests__/KeyValue.test.ts +66 -0
  99. package/components/form/__tests__/NodeScheduling.test.ts +9 -0
  100. package/components/form/__tests__/Security.test.ts +76 -0
  101. package/components/form/labeled-select-utils/useLabeledSelectPagination.ts +138 -0
  102. package/components/formatter/Autoscaler.vue +4 -4
  103. package/components/formatter/ClusterKubeVersion.vue +27 -0
  104. package/components/formatter/ClusterLink.vue +1 -7
  105. package/components/formatter/ClusterProvider.vue +6 -10
  106. package/components/formatter/FleetSummaryGraph.vue +0 -3
  107. package/components/formatter/MachineSummaryGraph.vue +1 -1
  108. package/components/formatter/PodsUsage.vue +2 -2
  109. package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
  110. package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
  111. package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
  112. package/components/nav/Group.vue +7 -6
  113. package/components/nav/Header.vue +24 -3
  114. package/components/nav/NamespaceFilter.vue +2 -2
  115. package/components/nav/NotificationCenter/Notification.vue +4 -1
  116. package/components/nav/NotificationCenter/NotificationHeader.vue +20 -8
  117. package/components/nav/NotificationCenter/__tests__/NotificationHeader.test.ts +80 -0
  118. package/components/nav/TopLevelMenu.helper.ts +15 -3
  119. package/components/nav/TopLevelMenu.vue +16 -5
  120. package/components/nav/Type.vue +8 -7
  121. package/components/nav/WindowManager/index.vue +2 -1
  122. package/components/nav/WorkspaceSwitcher.vue +13 -0
  123. package/components/nav/__tests__/Group.test.ts +67 -0
  124. package/components/nav/__tests__/Header.test.ts +235 -0
  125. package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
  126. package/components/nav/__tests__/Type.test.ts +20 -3
  127. package/components/templates/default.vue +34 -4
  128. package/components/templates/home.vue +30 -25
  129. package/components/templates/plain.vue +31 -26
  130. package/components/templates/standalone.vue +17 -0
  131. package/composables/useFormValidation.ts +93 -0
  132. package/composables/useLabeledFormElement.ts +10 -2
  133. package/composables/useLabeledSelect.ts +60 -0
  134. package/composables/useUserRetentionValidation.ts +1 -49
  135. package/composables/useVeeValidateField.test.ts +159 -0
  136. package/composables/useVeeValidateField.ts +67 -0
  137. package/config/cookies.js +0 -1
  138. package/config/labels-annotations.js +1 -0
  139. package/config/pagination-table-headers.js +18 -1
  140. package/config/product/manager.js +82 -21
  141. package/config/query-params.js +1 -0
  142. package/config/router/routes.js +6 -8
  143. package/config/table-headers.js +20 -1
  144. package/config/types.js +2 -1
  145. package/core/__tests__/plugin-products.test.ts +1505 -30
  146. package/core/plugin-products-base.ts +137 -20
  147. package/core/plugin-products-helpers.ts +5 -4
  148. package/core/plugin-products.ts +4 -0
  149. package/core/plugin-types.ts +129 -4
  150. package/core/plugin.ts +15 -7
  151. package/core/productDebugger.js +9 -4
  152. package/core/types-provisioning.ts +43 -30
  153. package/core/types.ts +58 -19
  154. package/detail/__tests__/management.cattle.io.fleetworkspace.test.ts +128 -0
  155. package/detail/__tests__/pod.test.ts +41 -0
  156. package/detail/harvesterhci.io.management.cluster.vue +6 -2
  157. package/detail/management.cattle.io.fleetworkspace.vue +49 -0
  158. package/detail/pod.vue +1 -1
  159. package/detail/provisioning.cattle.io.cluster.vue +4 -10
  160. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +9 -0
  161. package/edit/__tests__/kontainerDriver.test.ts +0 -13
  162. package/edit/__tests__/nodeDriver.test.ts +5 -11
  163. package/edit/__tests__/resources.cattle.io.restore.test.ts +9 -0
  164. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  165. package/edit/auth/__tests__/azuread.test.ts +217 -34
  166. package/edit/auth/__tests__/oidc.test.ts +54 -0
  167. package/edit/auth/azuread.vue +123 -15
  168. package/edit/auth/oidc.vue +10 -2
  169. package/edit/kontainerDriver.vue +1 -2
  170. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
  171. package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
  172. package/edit/networking.k8s.io.ingress/index.vue +75 -20
  173. package/edit/nodeDriver.vue +0 -2
  174. package/edit/provisioning.cattle.io.cluster/AgentEnv.vue +1 -0
  175. package/edit/provisioning.cattle.io.cluster/__tests__/AgentEnv.test.ts +25 -0
  176. package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
  177. package/edit/provisioning.cattle.io.cluster/index.vue +81 -106
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -4
  179. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  180. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
  181. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
  182. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
  183. package/edit/secret/__tests__/ssh.test.ts +5 -6
  184. package/edit/secret/basic.vue +31 -0
  185. package/edit/secret/index.vue +68 -17
  186. package/edit/secret/registry.vue +38 -0
  187. package/edit/secret/ssh.vue +29 -0
  188. package/edit/secret/tls.vue +30 -0
  189. package/edit/service.vue +4 -4
  190. package/edit/workload/Upgrading.vue +3 -3
  191. package/edit/workload/__tests__/Upgrading.test.ts +6 -9
  192. package/edit/workload/mixins/workload.js +2 -1
  193. package/initialize/App.vue +29 -2
  194. package/initialize/install-plugins.js +0 -2
  195. package/list/__tests__/management.cattle.io.feature.test.ts +105 -0
  196. package/list/catalog.cattle.io.app.vue +25 -5
  197. package/list/fleet.cattle.io.bundle.vue +7 -104
  198. package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
  199. package/list/management.cattle.io.feature.vue +1 -1
  200. package/list/management.cattle.io.fleetworkspace.vue +8 -0
  201. package/list/provisioning.cattle.io.cluster.vue +262 -180
  202. package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
  203. package/machine-config/amazonec2.vue +1 -0
  204. package/mixins/__tests__/chart.test.ts +112 -0
  205. package/mixins/brand.js +2 -1
  206. package/mixins/chart.js +50 -15
  207. package/mixins/resource-fetch-api-pagination.js +41 -5
  208. package/models/__tests__/catalog.cattle.io.app.test.ts +15 -1
  209. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +84 -0
  210. package/models/__tests__/chart.test.ts +99 -6
  211. package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
  212. package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
  213. package/models/__tests__/management.cattle.io.feature.test.ts +131 -0
  214. package/models/__tests__/management.cattle.io.node.ts +6 -5
  215. package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
  216. package/models/__tests__/monitoring.coreos.com.alertmanagerconfig.test.ts +98 -0
  217. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
  218. package/models/base-cluster.x-k8s.io.js +26 -0
  219. package/models/catalog.cattle.io.app.js +21 -17
  220. package/models/catalog.cattle.io.clusterrepo.js +39 -11
  221. package/models/chart.js +33 -19
  222. package/models/cluster.js +1 -1
  223. package/models/cluster.x-k8s.io.machine.js +4 -22
  224. package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
  225. package/models/cluster.x-k8s.io.machineset.js +2 -20
  226. package/models/compliance.cattle.io.clusterscan.js +130 -2
  227. package/models/ext.cattle.io.kubeconfig.ts +4 -7
  228. package/models/fleet-application.js +4 -2
  229. package/models/fleet.cattle.io.bundle.js +1 -1
  230. package/models/kontainerdriver.js +11 -0
  231. package/models/management.cattle.io.authconfig.js +5 -1
  232. package/models/management.cattle.io.cluster.js +402 -78
  233. package/models/management.cattle.io.feature.js +3 -3
  234. package/models/management.cattle.io.kontainerdriver.js +1 -26
  235. package/models/management.cattle.io.node.js +6 -4
  236. package/models/management.cattle.io.nodepool.js +1 -1
  237. package/models/monitoring.coreos.com.alertmanagerconfig.js +31 -17
  238. package/models/networking.k8s.io.ingress.js +12 -4
  239. package/models/nodedriver.js +7 -0
  240. package/models/provisioning.cattle.io.cluster.js +47 -330
  241. package/models/rke.cattle.io.etcdsnapshot.js +1 -2
  242. package/package.json +20 -37
  243. package/pages/__tests__/readme.test.ts +49 -0
  244. package/pages/auth/setup.vue +2 -3
  245. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +265 -0
  246. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +55 -0
  247. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +53 -0
  248. package/pages/c/_cluster/apps/charts/chart.vue +275 -39
  249. package/pages/c/_cluster/apps/charts/index.vue +2 -2
  250. package/pages/c/_cluster/apps/charts/install.vue +18 -10
  251. package/pages/c/_cluster/auth/user.retention/index.vue +55 -22
  252. package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
  253. package/pages/c/_cluster/explorer/index.vue +5 -49
  254. package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
  255. package/pages/c/_cluster/istio/index.vue +21 -6
  256. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -7
  257. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +40 -2
  258. package/pages/c/_cluster/uiplugins/__tests__/PluginInfoPanel.test.ts +61 -0
  259. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +735 -13
  260. package/pages/c/_cluster/uiplugins/index.vue +226 -222
  261. package/pages/diagnostic.vue +13 -17
  262. package/pages/fail-whale.vue +18 -0
  263. package/pages/home.vue +77 -260
  264. package/pages/readme.vue +88 -0
  265. package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
  266. package/plugins/dashboard-store/actions.js +40 -18
  267. package/plugins/dashboard-store/resource-class.js +5 -2
  268. package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
  269. package/plugins/steve/steve-pagination-utils.ts +11 -3
  270. package/plugins/steve/subscribe.js +35 -5
  271. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +211 -1
  272. package/rancher-components/Form/LabeledInput/LabeledInput.vue +37 -4
  273. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -1
  274. package/rancher-components/RcButton/RcButton.test.ts +37 -1
  275. package/rancher-components/RcButton/RcButton.vue +38 -8
  276. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
  277. package/scripts/test-plugins-build.sh +5 -2
  278. package/server/server-middleware.js +2 -2
  279. package/static/humans.txt +1 -0
  280. package/static/robots.txt +34 -0
  281. package/static/welcome-cow.svg +18 -0
  282. package/store/__tests__/catalog.test.ts +276 -12
  283. package/store/__tests__/type-map.test.ts +556 -1
  284. package/store/action-menu.js +8 -3
  285. package/store/auth.js +1 -4
  286. package/store/aws.js +27 -16
  287. package/store/catalog.js +87 -11
  288. package/store/digitalocean.js +20 -38
  289. package/store/index.js +2 -0
  290. package/store/linode.js +25 -40
  291. package/store/pnap.js +1 -0
  292. package/store/type-map.js +111 -29
  293. package/tsconfig.paths.json +8 -8
  294. package/types/kube/kube-api.ts +14 -1
  295. package/types/rancher/steve.api.ts +12 -12
  296. package/types/resources/settings.d.ts +2 -1
  297. package/types/shell/index.d.ts +128 -24
  298. package/types/store/dashboard-store.types.ts +108 -11
  299. package/types/store/pagination.types.ts +6 -3
  300. package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
  301. package/utils/__tests__/async.test.ts +87 -0
  302. package/utils/__tests__/aws.test.ts +140 -0
  303. package/utils/__tests__/banners.test.ts +176 -0
  304. package/utils/__tests__/chart.test.ts +64 -1
  305. package/utils/__tests__/color.test.ts +226 -0
  306. package/utils/__tests__/duration.test.ts +140 -0
  307. package/utils/__tests__/fleet.test.ts +340 -0
  308. package/utils/__tests__/git.test.ts +270 -0
  309. package/utils/__tests__/inactivity.test.ts +316 -0
  310. package/utils/__tests__/ingress.test.ts +553 -0
  311. package/utils/__tests__/kube.test.ts +68 -0
  312. package/utils/__tests__/namespace-filter.test.ts +109 -0
  313. package/utils/__tests__/object.test.ts +77 -0
  314. package/utils/__tests__/pagination-utils.test.ts +361 -0
  315. package/utils/__tests__/parse-externalid.test.ts +137 -0
  316. package/utils/__tests__/perf-setting.utils.test.ts +98 -0
  317. package/utils/__tests__/poller-sequential.test.ts +177 -0
  318. package/utils/__tests__/poller.test.ts +170 -0
  319. package/utils/__tests__/promise.test.ts +346 -0
  320. package/utils/__tests__/settings.test.ts +140 -0
  321. package/utils/__tests__/sort-utils.test.ts +301 -0
  322. package/utils/__tests__/string-utils.test.ts +798 -0
  323. package/utils/__tests__/string.test.ts +23 -1
  324. package/utils/__tests__/style.test.ts +154 -0
  325. package/utils/__tests__/svg-filter.test.ts +184 -0
  326. package/utils/__tests__/time.test.ts +14 -1
  327. package/utils/__tests__/units.test.ts +417 -0
  328. package/utils/__tests__/url.test.ts +246 -0
  329. package/utils/__tests__/versions.test.ts +128 -0
  330. package/utils/__tests__/xccdf.test.ts +391 -0
  331. package/utils/chart.js +36 -0
  332. package/utils/fleet.ts +13 -3
  333. package/utils/gatekeeper/__tests__/util.test.ts +174 -0
  334. package/utils/gc/__tests__/gc-interval.test.ts +119 -0
  335. package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
  336. package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
  337. package/utils/gc/__tests__/gc.test.ts +487 -0
  338. package/utils/ingress.ts +9 -1
  339. package/utils/object.js +33 -2
  340. package/utils/pagination-utils.ts +2 -1
  341. package/utils/string.js +25 -2
  342. package/utils/time.ts +5 -0
  343. package/utils/uiplugins.ts +5 -5
  344. package/utils/validators/__tests__/cluster-name.test.ts +110 -0
  345. package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
  346. package/utils/validators/__tests__/index.test.ts +481 -0
  347. package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
  348. package/utils/validators/__tests__/misc-validators.test.ts +246 -0
  349. package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
  350. package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
  351. package/utils/validators/__tests__/role-template.test.ts +149 -0
  352. package/utils/validators/__tests__/service.test.ts +283 -0
  353. package/utils/validators/__tests__/setting.test.js +32 -0
  354. package/utils/validators/formRules/__tests__/index.test.ts +50 -0
  355. package/utils/validators/formRules/index.ts +5 -5
  356. package/utils/validators/machine-pool.ts +1 -1
  357. package/utils/validators/setting.js +18 -3
  358. package/utils/xccdf.ts +418 -0
  359. package/vue.config.js +0 -9
  360. package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
  361. package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
  362. package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
  363. package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
  364. package/assets/images/providers/azuread-black.svg +0 -22
  365. package/assets/images/providers/azuread.svg +0 -25
  366. package/assets/images/vendor/azuread.svg +0 -18
  367. package/assets/styles/fonts/_dots.scss +0 -18
  368. package/components/EmberPage.vue +0 -622
  369. package/components/EmberPageView.vue +0 -39
  370. package/components/form/labeled-select-utils/labeled-select-pagination.ts +0 -116
  371. package/mixins/labeled-form-element.ts +0 -225
  372. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -28
  373. package/pages/c/_cluster/manager/pages/_page.vue +0 -22
  374. package/pages/c/_cluster/mcapps/pages/_page.vue +0 -22
  375. package/plugins/ember-cookie.js +0 -17
  376. package/utils/ember-page.js +0 -30
@@ -159,23 +159,20 @@ const showAdditionalActionButtons = computed(() => isArray(additionalActions));
159
159
 
160
160
  <style lang="scss" scoped>
161
161
  .title-bar {
162
- min-width: 740px;
162
+ min-width: $resource-detail-min-width;
163
163
 
164
164
  .badge-state {
165
165
  font-size: 16px;
166
166
  margin-left: 12px;
167
167
  position: relative;
168
- }
169
-
170
- .icon-document {
171
- width: 15px;
172
- font-size: 16px;
173
- margin-right: 10px;
168
+ flex: 0 0 auto;
174
169
  }
175
170
 
176
171
  .actions {
177
172
  display: flex;
178
173
  align-items: center;
174
+ flex: 0 0 auto;
175
+ margin-left: 16px;
179
176
  }
180
177
 
181
178
  .show-configuration, &:deep() .actions > button {
@@ -198,15 +195,17 @@ const showAdditionalActionButtons = computed(() => isArray(additionalActions));
198
195
  max-width: 60%;
199
196
  }
200
197
 
201
- // This prevents the title from overlapping with the actions
198
+ // Title takes the remaining row space; min-width: 0 lets its children
199
+ // (resource-name) shrink so the action buttons stay visible on narrow viewports.
202
200
  .title {
203
- max-width: calc(100% - 260px);
201
+ flex: 1 1 auto;
202
+ min-width: 0;
204
203
  }
205
204
 
206
- // We want the resource name to be what collaspes wh
207
205
  .resource-name {
208
206
  display: inline-block;
209
- flex: 1;
207
+ flex: 0 1 auto;
208
+ min-width: 0;
210
209
  white-space: nowrap;
211
210
  overflow-x: hidden;
212
211
  overflow-y: clip;
@@ -2,6 +2,7 @@
2
2
  import { mapGetters } from 'vuex';
3
3
  import Favorite from '@shell/components/nav/Favorite';
4
4
  import TypeDescription from '@shell/components/TypeDescription';
5
+ import { RcButton } from '@components/RcButton';
5
6
  import { get } from '@shell/utils/object';
6
7
  import { AS, _YAML } from '@shell/config/query-params';
7
8
  import ResourceLoadingIndicator from './ResourceLoadingIndicator';
@@ -16,6 +17,7 @@ export default {
16
17
 
17
18
  components: {
18
19
  Favorite,
20
+ RcButton,
19
21
  TypeDescription,
20
22
  ResourceLoadingIndicator,
21
23
  TabTitle
@@ -221,22 +223,24 @@ export default {
221
223
  <slot name="extraActions" />
222
224
 
223
225
  <slot name="createButton">
224
- <router-link
226
+ <RcButton
225
227
  v-if="hasEditComponent && _isCreatable"
226
- :to="_createLocation"
227
- class="btn role-primary"
228
+ variant="primary"
229
+ size="large"
228
230
  :data-testid="componentTestid+'-create'"
231
+ :to="_createLocation"
229
232
  >
230
233
  {{ _createButtonlabel }}
231
- </router-link>
232
- <router-link
234
+ </RcButton>
235
+ <RcButton
233
236
  v-else-if="_isYamlCreatable"
234
- :to="_yamlCreateLocation"
235
- class="btn role-primary"
237
+ variant="primary"
238
+ size="large"
236
239
  :data-testid="componentTestid+'-create-yaml'"
240
+ :to="_yamlCreateLocation"
237
241
  >
238
242
  {{ t("resourceList.head.createFromYaml") }}
239
- </router-link>
243
+ </RcButton>
240
244
  </slot>
241
245
  </div>
242
246
  </slot>
@@ -38,6 +38,10 @@ export default {
38
38
  type: String,
39
39
  default: 'disabled',
40
40
  },
41
+ tooltipField: {
42
+ type: String,
43
+ default: 'tooltip',
44
+ },
41
45
 
42
46
  asLink: {
43
47
  type: Boolean,
@@ -104,6 +108,7 @@ export default {
104
108
  :is="asLink ? 'a' : 'div'"
105
109
  v-for="(r, idx) in rows"
106
110
  :key="get(r, keyField)"
111
+ v-clean-tooltip="get(r, tooltipField) || null"
107
112
  :role="asLink ? 'link' : null"
108
113
  :aria-disabled="asLink && get(r, disabledField) === true ? true : null"
109
114
  :aria-label="get(r, nameField)"
@@ -126,16 +131,6 @@ export default {
126
131
  class="side-label"
127
132
  :class="{'indicator': true }"
128
133
  />
129
- <div v-if="r.deploysOnWindows">
130
- <label class="deploys-os-label">
131
- {{ t('catalog.charts.deploysOnWindows') }}
132
- </label>
133
- </div>
134
- <div v-if="r.windowsIncompatible">
135
- <label class="os-incompatible-label">
136
- {{ t('catalog.charts.windowsIncompatible') }}
137
- </label>
138
- </div>
139
134
  <div
140
135
  v-if="get(r, sideLabelField)"
141
136
  class="side-label"
@@ -13,6 +13,7 @@ export default {
13
13
  },
14
14
 
15
15
  async fetch() {
16
+ // There's only one cluster, might as well fetch them all...
16
17
  this.clusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
17
18
  },
18
19
 
@@ -0,0 +1,126 @@
1
+ import sorting from '@shell/components/SortableTable/sorting';
2
+
3
+ const { arrangedRows } = sorting.computed;
4
+
5
+ describe('sorting mixin', () => {
6
+ describe('arrangedRows', () => {
7
+ function createContext({
8
+ rows = [] as any[],
9
+ sortFields = ['id'],
10
+ descending = false,
11
+ sortGeneration = undefined as string | undefined,
12
+ sortGenerationFn = (() => 'gen1') as (() => string) | undefined,
13
+ externalPaginationEnabled = false,
14
+ cacheKey = null as string | null,
15
+ cachedRows = null as any[] | null,
16
+ cachedRowsRef = null as any[] | null,
17
+ } = {}) {
18
+ return {
19
+ rows,
20
+ sortFields,
21
+ descending,
22
+ sortGeneration,
23
+ sortGenerationFn,
24
+ externalPaginationEnabled,
25
+ cacheKey,
26
+ cachedRows,
27
+ cachedRowsRef,
28
+ };
29
+ }
30
+
31
+ it('should return undefined when externalPaginationEnabled is true', () => {
32
+ const ctx = createContext({ externalPaginationEnabled: true });
33
+
34
+ expect(arrangedRows.call(ctx)).toBeUndefined();
35
+ });
36
+
37
+ it('should sort rows by the given sort fields', () => {
38
+ const rows = [{ id: 'b' }, { id: 'a' }, { id: 'c' }];
39
+ const ctx = createContext({ rows, sortGenerationFn: undefined });
40
+
41
+ const result = arrangedRows.call(ctx);
42
+
43
+ expect(result.map((r: any) => r.id)).toStrictEqual(['a', 'b', 'c']);
44
+ });
45
+
46
+ it('should cache results when sortGenerationFn is provided', () => {
47
+ const rows = [{ id: 'b' }, { id: 'a' }];
48
+ const ctx = createContext({ rows });
49
+
50
+ const result1 = arrangedRows.call(ctx);
51
+
52
+ expect(ctx.cacheKey).not.toBeNull();
53
+ expect(ctx.cachedRows).toStrictEqual(result1);
54
+
55
+ const result2 = arrangedRows.call(ctx);
56
+
57
+ expect(result2).toBe(ctx.cachedRows);
58
+ });
59
+
60
+ it('should invalidate cache when rows change to different items with the same count', () => {
61
+ const rowsA = [{ id: 'alpha' }];
62
+ const rowsB = [{ id: 'beta' }];
63
+ const ctx = createContext({ rows: rowsA });
64
+
65
+ const resultA = arrangedRows.call(ctx);
66
+
67
+ expect(resultA.map((r: any) => r.id)).toStrictEqual(['alpha']);
68
+
69
+ ctx.rows = rowsB;
70
+ const resultB = arrangedRows.call(ctx);
71
+
72
+ expect(resultB.map((r: any) => r.id)).toStrictEqual(['beta']);
73
+ });
74
+
75
+ it('should return cached rows when same rows are passed again', () => {
76
+ const rows = [{ id: 'x' }, { id: 'y' }];
77
+ const ctx = createContext({ rows });
78
+
79
+ arrangedRows.call(ctx);
80
+ const cached = ctx.cachedRows;
81
+
82
+ const result = arrangedRows.call(ctx);
83
+
84
+ expect(result).toBe(cached);
85
+ });
86
+
87
+ it('should invalidate cache when descending changes', () => {
88
+ const rows = [{ id: 'a' }, { id: 'b' }];
89
+ const ctx = createContext({ rows });
90
+
91
+ arrangedRows.call(ctx);
92
+
93
+ ctx.descending = true;
94
+ const result = arrangedRows.call(ctx);
95
+
96
+ expect(result.map((r: any) => r.id)).toStrictEqual(['b', 'a']);
97
+ });
98
+
99
+ it('should not cache when there is no sortGenerationFn or sortGeneration', () => {
100
+ const rows = [{ id: 'a' }];
101
+ const ctx = createContext({ rows });
102
+
103
+ ctx.sortGenerationFn = undefined;
104
+ ctx.sortGeneration = undefined;
105
+
106
+ arrangedRows.call(ctx);
107
+
108
+ expect(ctx.cacheKey).toBeNull();
109
+ expect(ctx.cachedRows).toBeNull();
110
+ });
111
+
112
+ it('should use sortGeneration over sortGenerationFn when provided', () => {
113
+ const rows = [{ id: 'a' }];
114
+ const ctx = createContext({
115
+ rows,
116
+ sortGeneration: 'custom-gen',
117
+ sortGenerationFn: () => 'fn-gen',
118
+ });
119
+
120
+ arrangedRows.call(ctx);
121
+
122
+ expect(ctx.cacheKey).toContain('custom-gen');
123
+ expect(ctx.cacheKey).not.toContain('fn-gen');
124
+ });
125
+ });
126
+ });
@@ -26,6 +26,7 @@ import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
26
26
  import ActionMenu from '@shell/components/ActionMenuShell.vue';
27
27
  import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
28
28
  import ActionDropdownShell from '@shell/components/ActionDropdownShell.vue';
29
+ import { RcButton } from '@components/RcButton';
29
30
  import { useTabCountUpdater } from '@shell/components/form/ResourceTabs/composable';
30
31
 
31
32
  // Uncomment for table performance debugging
@@ -65,6 +66,7 @@ export default {
65
66
  ButtonMultiAction,
66
67
  ActionMenu,
67
68
  ActionDropdownShell,
69
+ RcButton,
68
70
  },
69
71
 
70
72
  mixins: [
@@ -1116,17 +1118,17 @@ export default {
1116
1118
  >
1117
1119
  <slot name="header-left">
1118
1120
  <template v-if="tableActions">
1119
- <button
1121
+ <RcButton
1120
1122
  v-for="(act) in availableActions"
1121
1123
  :id="act.action"
1122
1124
  :key="act.action"
1123
1125
  v-clean-tooltip="actionTooltip"
1124
1126
  type="button"
1125
- class="btn role-primary"
1127
+ variant="primary"
1128
+ size="large"
1126
1129
  :class="{[bulkActionClass]:true}"
1127
1130
  :disabled="!act.enabled"
1128
1131
  :data-testid="componentTestid + '-' + act.action"
1129
- role="button"
1130
1132
  :aria-label="act.label"
1131
1133
  @click="applyTableAction(act, null, $event)"
1132
1134
  @keydown.enter.stop
@@ -1138,7 +1140,7 @@ export default {
1138
1140
  :class="act.icon"
1139
1141
  />
1140
1142
  <span v-clean-html="act.label" />
1141
- </button>
1143
+ </RcButton>
1142
1144
  <template v-if="featureDropdownMenu">
1143
1145
  <ActionDropdownShell
1144
1146
  :disabled="!selectedRows.length"
@@ -2154,11 +2156,6 @@ export default {
2154
2156
  }
2155
2157
  }
2156
2158
 
2157
- .bulk-action {
2158
- .icon {
2159
- vertical-align: -10%;
2160
- }
2161
- }
2162
2159
  }
2163
2160
 
2164
2161
  .middle {
@@ -626,27 +626,45 @@ function _execute(resources, action, args, opts = {}, ctx) {
626
626
  return action.invoke.apply(ctx, [actionOpts, resources || [], args]);
627
627
  }
628
628
 
629
+ /**
630
+ * for the given resource find it's action matching the target action. if that target action has an alt resource return it
631
+ */
632
+ const findResourceFromAction = (r) => {
633
+ const actualAction = r.availableActions.find((aa) => aa.action === action.action);
634
+
635
+ return actualAction?.altResource || r;
636
+ };
637
+
638
+ // if there there are multiple resources and a bulk action, use it and pass in the resources
639
+ // for example cluster management cluster list Download KubeConfig
629
640
  if ( resources.length > 1 && action.bulkAction && !opts.alt ) {
630
- const fn = resources[0][action.bulkAction];
641
+ const applyResource = findResourceFromAction(resources[0]);
642
+ const fn = applyResource[action.bulkAction];
631
643
 
632
644
  if ( fn ) {
633
- return fn.call(resources[0], resources, ...args);
645
+ const applyResources = resources.map(findResourceFromAction);
646
+
647
+ return fn.call(applyResource, applyResources, ...args);
634
648
  }
635
649
  }
636
650
 
637
651
  const promises = [];
638
652
 
653
+ // if there is a single resource or no bulk action, for each resource execute it's action
654
+ // for example delete when only one row is selected
639
655
  for ( const resource of resources ) {
640
656
  let fn;
641
657
 
658
+ const applyResource = findResourceFromAction(resource);
659
+
642
660
  if (opts.alt && action.altAction) {
643
- fn = resource[action.altAction];
661
+ fn = applyResource[action.altAction];
644
662
  } else {
645
- fn = resource[action.action];
663
+ fn = applyResource[action.action];
646
664
  }
647
665
 
648
666
  if ( fn ) {
649
- promises.push(fn.apply(resource, args));
667
+ promises.push(fn.apply(applyResource, args));
650
668
  }
651
669
  }
652
670
 
@@ -50,7 +50,8 @@ export default {
50
50
 
51
51
  if ( sortGenerationKey) {
52
52
  key = `${ sortGenerationKey }/${ this.rows.length }/${ this.descending }/${ this.sortFields.join(',') }`;
53
- if ( this.cacheKey === key ) {
53
+
54
+ if ( this.cacheKey === key && this.cachedRowsRef === this.rows ) {
54
55
  return this.cachedRows;
55
56
  }
56
57
  }
@@ -60,6 +61,7 @@ export default {
60
61
  if ( key ) {
61
62
  this.cacheKey = key;
62
63
  this.cachedRows = out;
64
+ this.cachedRowsRef = this.rows;
63
65
  }
64
66
 
65
67
  return out;
@@ -104,8 +106,9 @@ export default {
104
106
  return {
105
107
  sortBy,
106
108
  descending,
107
- cachedRows: null,
108
- cacheKey: null,
109
+ cachedRows: null,
110
+ cachedRowsRef: null,
111
+ cacheKey: null,
109
112
  };
110
113
  },
111
114
 
@@ -2,6 +2,7 @@
2
2
  import { _CREATE, _VIEW } from '@shell/config/query-params';
3
3
  import AsyncButton from '@shell/components/AsyncButton';
4
4
  import { Banner } from '@components/Banner';
5
+ import { RcButton } from '@components/RcButton';
5
6
  import Loading from '@shell/components/Loading';
6
7
  import { stringify } from '@shell/utils/error';
7
8
  import LazyImage from '@shell/components/LazyImage';
@@ -28,6 +29,7 @@ export default {
28
29
  components: {
29
30
  AsyncButton,
30
31
  Banner,
32
+ RcButton,
31
33
  Loading,
32
34
  LazyImage,
33
35
  },
@@ -44,7 +46,6 @@ export default {
44
46
  loading: Wizard will block until all steps are not loading
45
47
  nextButton?: {
46
48
  labelKey?: default to `wizard.next`
47
- style?: defaults to `btn role-primary`
48
49
  },
49
50
  previousButton: {
50
51
  disable: defaults to false
@@ -185,9 +186,6 @@ export default {
185
186
  return this.steps.filter((step) => !step.hidden);
186
187
  },
187
188
 
188
- nextButtonStyle() {
189
- return this.activeStep.nextButton?.style || `btn role-primary`;
190
- },
191
189
  nextButtonLabel() {
192
190
  return this.activeStep.nextButton?.labelKey || `wizard.next`;
193
191
  }
@@ -444,13 +442,14 @@ export default {
444
442
  name="cancel"
445
443
  :cancel="cancel"
446
444
  >
447
- <button
445
+ <RcButton
448
446
  type="button"
449
- class="btn role-secondary"
447
+ variant="secondary"
448
+ size="large"
450
449
  @click="cancel"
451
450
  >
452
451
  <t k="generic.cancel" />
453
- </button>
452
+ </RcButton>
454
453
  </slot>
455
454
  <div class="controls-steps">
456
455
  <slot
@@ -458,14 +457,15 @@ export default {
458
457
  name="back"
459
458
  :back="back"
460
459
  >
461
- <button
460
+ <RcButton
462
461
  :disabled="!canPrevious || (!editFirstStep && activeStepIndex===1)"
463
462
  type="button"
464
- class="btn role-secondary"
463
+ variant="secondary"
464
+ size="large"
465
465
  @click="back()"
466
466
  >
467
467
  <t k="wizard.previous" />
468
- </button>
468
+ </RcButton>
469
469
  </slot>
470
470
  <slot
471
471
  v-if="activeStepIndex === visibleSteps.length-1"
@@ -484,14 +484,15 @@ export default {
484
484
  name="next"
485
485
  :next="next"
486
486
  >
487
- <button
487
+ <RcButton
488
488
  :disabled="!canNext"
489
489
  type="button"
490
- :class="nextButtonStyle"
490
+ variant="primary"
491
+ size="large"
491
492
  @click="next()"
492
493
  >
493
494
  <t :k="nextButtonLabel" />
494
- </button>
495
+ </RcButton>
495
496
  </slot>
496
497
  </div>
497
498
  </div>
@@ -0,0 +1,72 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import CountBox from '@shell/components/CountBox.vue';
3
+
4
+ describe('component: CountBox', () => {
5
+ const defaultProps = {
6
+ name: 'Test',
7
+ count: 5,
8
+ primaryColorVar: '--sizzle-1',
9
+ };
10
+
11
+ describe('when clickable is false', () => {
12
+ it('should render as a div', () => {
13
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
14
+
15
+ expect(wrapper.element.tagName).toBe('DIV');
16
+ });
17
+
18
+ it('should not have the clickable class', () => {
19
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
20
+
21
+ expect(wrapper.classes()).not.toContain('clickable');
22
+ });
23
+
24
+ it('should not emit click event when clicked', async() => {
25
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
26
+
27
+ await wrapper.trigger('click');
28
+
29
+ expect(wrapper.emitted('click')).toBeUndefined();
30
+ });
31
+ });
32
+
33
+ describe('when clickable is true', () => {
34
+ it('should have the clickable class', () => {
35
+ const wrapper = shallowMount(CountBox, {
36
+ props: {
37
+ ...defaultProps,
38
+ clickable: true,
39
+ },
40
+ });
41
+
42
+ expect(wrapper.classes()).toContain('clickable');
43
+ });
44
+
45
+ it('should emit click event when clicked', async() => {
46
+ const wrapper = shallowMount(CountBox, {
47
+ props: {
48
+ ...defaultProps,
49
+ clickable: true,
50
+ },
51
+ });
52
+
53
+ await wrapper.trigger('click');
54
+
55
+ expect(wrapper.emitted('click')).toHaveLength(1);
56
+ });
57
+ });
58
+
59
+ describe('display', () => {
60
+ it('should display the count', () => {
61
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
62
+
63
+ expect(wrapper.find('h1').text()).toBe('5');
64
+ });
65
+
66
+ it('should display the name', () => {
67
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
68
+
69
+ expect(wrapper.find('label').text()).toBe('Test');
70
+ });
71
+ });
72
+ });
@@ -0,0 +1,113 @@
1
+ import { mount } from '@vue/test-utils';
2
+
3
+ import DetailText from '@shell/components/DetailText.vue';
4
+
5
+ jest.mock('@shell/utils/clipboard', () => ({ copyTextToClipboard: jest.fn() }));
6
+
7
+ describe('component: DetailText', () => {
8
+ const defaultMocks = {
9
+ $store: {
10
+ getters: {
11
+ 'i18n/t': jest.fn((key: string) => `%${ key }%`),
12
+ 'prefs/get': jest.fn(() => true),
13
+ }
14
+ }
15
+ };
16
+
17
+ describe('concealment', () => {
18
+ it('should not render the actual secret value in the content area when concealed', () => {
19
+ const secretValue = 'super-secret-password-xyz';
20
+ const wrapper = mount(DetailText, {
21
+ props: {
22
+ value: secretValue,
23
+ conceal: true,
24
+ label: 'Password',
25
+ },
26
+
27
+ global: {
28
+ mocks: defaultMocks,
29
+ directives: {
30
+ 'clean-html': () => {},
31
+ 'clean-tooltip': () => {},
32
+ t: () => {},
33
+ },
34
+ stubs: {
35
+ CopyToClipboard: true,
36
+ CodeMirror: true,
37
+ },
38
+ },
39
+ });
40
+
41
+ const concealedSpan = wrapper.find('[data-testid="detail-top_html"]');
42
+
43
+ expect(concealedSpan.exists()).toBe(true);
44
+ expect(concealedSpan.classes()).toContain('conceal');
45
+ expect(concealedSpan.text()).not.toContain(secretValue);
46
+ });
47
+
48
+ it('should render the actual value when not concealed', () => {
49
+ const visibleValue = 'visible-value-123';
50
+ const wrapper = mount(DetailText, {
51
+ props: {
52
+ value: visibleValue,
53
+ conceal: false,
54
+ label: 'Data',
55
+ },
56
+
57
+ global: {
58
+ mocks: defaultMocks,
59
+ directives: {
60
+ 'clean-html': (el: HTMLElement, binding: { value: string }) => {
61
+ el.innerHTML = binding.value;
62
+ },
63
+ 'clean-tooltip': () => {},
64
+ t: () => {},
65
+ },
66
+ stubs: {
67
+ CopyToClipboard: true,
68
+ CodeMirror: true,
69
+ },
70
+ },
71
+ });
72
+
73
+ const contentSpan = wrapper.find('[data-testid="detail-top_html"]');
74
+
75
+ expect(contentSpan.exists()).toBe(true);
76
+ expect(contentSpan.classes()).not.toContain('conceal');
77
+ });
78
+
79
+ it('should not render JSON secret values in CodeMirror when concealed', () => {
80
+ const jsonSecret = '{"api_key": "secret-key-123"}';
81
+ const wrapper = mount(DetailText, {
82
+ props: {
83
+ value: jsonSecret,
84
+ conceal: true,
85
+ label: 'Config',
86
+ },
87
+
88
+ global: {
89
+ mocks: defaultMocks,
90
+ directives: {
91
+ 'clean-html': () => {},
92
+ 'clean-tooltip': () => {},
93
+ t: () => {},
94
+ },
95
+ stubs: {
96
+ CopyToClipboard: true,
97
+ CodeMirror: true,
98
+ },
99
+ },
100
+ });
101
+
102
+ const codeMirror = wrapper.findComponent({ name: 'CodeMirror' });
103
+
104
+ expect(codeMirror.exists()).toBe(false);
105
+
106
+ const concealedSpan = wrapper.find('[data-testid="detail-top_html"]');
107
+
108
+ expect(concealedSpan.exists()).toBe(true);
109
+ expect(concealedSpan.classes()).toContain('conceal');
110
+ expect(concealedSpan.text()).not.toContain('secret-key-123');
111
+ });
112
+ });
113
+ });