@rancher/shell 3.0.5-rc.5 → 3.0.5-rc.6

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 (312) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/images/key.svg +17 -0
  3. package/assets/styles/base/_spacing.scss +2 -2
  4. package/assets/styles/global/_form.scss +1 -1
  5. package/assets/styles/global/_labeled-input.scss +1 -1
  6. package/assets/styles/themes/_dark.scss +3 -0
  7. package/assets/styles/themes/_light.scss +3 -0
  8. package/assets/styles/vendor/vue-select.scss +1 -1
  9. package/assets/translations/en-us.yaml +404 -64
  10. package/assets/translations/zh-hans.yaml +3 -4
  11. package/cloud-credential/gcp.vue +9 -1
  12. package/components/AppModal.vue +2 -0
  13. package/components/CodeMirror.vue +1 -1
  14. package/components/ConfigMapSettings/Settings.vue +377 -0
  15. package/components/ConfigMapSettings/index.vue +354 -0
  16. package/components/CruResource.vue +1 -2
  17. package/components/DetailText.vue +61 -11
  18. package/components/Drawer/Chrome.vue +116 -0
  19. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  20. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  21. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  22. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  23. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +82 -0
  24. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  25. package/components/Drawer/ResourceDetailDrawer/composables.ts +50 -0
  26. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  27. package/components/Drawer/ResourceDetailDrawer/index.vue +110 -0
  28. package/components/GrowlManager.vue +16 -15
  29. package/components/IconOrSvg.vue +5 -0
  30. package/components/KeyValueView.vue +1 -1
  31. package/components/LocaleSelector.vue +9 -1
  32. package/components/ProgressBarMulti.vue +1 -0
  33. package/components/PromptModal.vue +6 -1
  34. package/components/RelatedResources.vue +4 -12
  35. package/components/Resource/Detail/Additional.vue +46 -0
  36. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
  37. package/components/Resource/Detail/Metadata/Annotations/index.vue +5 -0
  38. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  39. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +37 -254
  40. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +298 -0
  41. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +27 -5
  42. package/components/Resource/Detail/Metadata/KeyValue.vue +25 -17
  43. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -1
  44. package/components/Resource/Detail/Metadata/Labels/index.vue +4 -0
  45. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +1 -1
  46. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +1 -1
  47. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  48. package/components/Resource/Detail/Metadata/composables.ts +60 -11
  49. package/components/Resource/Detail/Metadata/index.vue +12 -5
  50. package/components/Resource/Detail/Page.vue +15 -0
  51. package/components/Resource/Detail/ResourceRow.vue +37 -18
  52. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  53. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  54. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  55. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  56. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  57. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  58. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  59. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  60. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  61. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  62. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  63. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  64. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  65. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  66. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  67. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  68. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  69. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  70. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  71. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  72. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  73. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  74. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  75. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  76. package/components/Resource/Detail/TitleBar/Title.vue +2 -1
  77. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +1 -1
  78. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +1 -1
  79. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  80. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
  81. package/components/Resource/Detail/TitleBar/composables.ts +44 -0
  82. package/components/Resource/Detail/TitleBar/index.vue +83 -11
  83. package/components/Resource/Detail/composables.ts +45 -0
  84. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  85. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  86. package/components/ResourceDetail/Masthead/index.vue +65 -0
  87. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  88. package/components/ResourceDetail/__tests__/index.test.ts +26 -5
  89. package/components/ResourceDetail/index.vue +30 -16
  90. package/components/ResourceDetail/legacy.vue +18 -1
  91. package/components/ResourceList/Masthead.vue +6 -0
  92. package/components/ResourceYaml.vue +14 -1
  93. package/components/SlideInPanelManager.vue +46 -7
  94. package/components/StateDot/index.vue +28 -0
  95. package/components/Tabbed/index.vue +11 -15
  96. package/components/Wizard.vue +4 -2
  97. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  98. package/components/__tests__/GrowlManager.test.ts +0 -25
  99. package/components/auth/login/ldap.vue +1 -1
  100. package/components/fleet/FleetApplications.vue +0 -7
  101. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  102. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  103. package/components/fleet/FleetClusters.vue +25 -6
  104. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  105. package/components/fleet/FleetHelmOps.vue +8 -0
  106. package/components/fleet/FleetRepos.vue +1 -6
  107. package/components/fleet/FleetResources.vue +4 -5
  108. package/components/fleet/FleetValuesFrom.vue +295 -0
  109. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  110. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  111. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +13 -13
  112. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  113. package/components/fleet/dashboard/ResourceCard.vue +1 -0
  114. package/components/fleet/dashboard/ResourceCardSummary.vue +1 -5
  115. package/components/fleet/dashboard/ResourceDetails.vue +8 -10
  116. package/components/fleet/dashboard/ResourcePanel.vue +15 -8
  117. package/components/form/ArrayList.vue +13 -2
  118. package/components/form/ChangePassword.vue +3 -1
  119. package/components/form/Footer.vue +10 -4
  120. package/components/form/KeyValue.vue +81 -43
  121. package/components/form/LabeledSelect.vue +56 -16
  122. package/components/form/Labels.vue +90 -17
  123. package/components/form/MatchExpressions.vue +46 -5
  124. package/components/form/NameNsDescription.vue +1 -1
  125. package/components/form/ResourceSelector.vue +1 -0
  126. package/components/form/ResourceTabs/index.vue +5 -0
  127. package/components/form/SecretSelector.vue +9 -2
  128. package/components/form/Select.vue +57 -19
  129. package/components/form/SimpleSecretSelector.vue +9 -2
  130. package/components/form/Taints.vue +21 -2
  131. package/components/form/UnitInput.vue +8 -0
  132. package/components/form/ValueFromResource.vue +1 -1
  133. package/components/form/__tests__/LabeledSelect.test.ts +8 -4
  134. package/components/form/__tests__/Labels.test.ts +360 -0
  135. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  136. package/components/form/__tests__/Select.test.ts +5 -2
  137. package/components/formatter/FleetApplicationSource.vue +1 -1
  138. package/components/formatter/WorkloadHealthScale.vue +1 -1
  139. package/components/google/AccountAccess.vue +211 -0
  140. package/components/google/types/gcp.d.ts +136 -0
  141. package/components/google/types/index.d.ts +101 -0
  142. package/components/google/util/__mocks__/gcp.ts +465 -0
  143. package/components/google/util/formatter.ts +82 -0
  144. package/components/google/util/gcp.ts +134 -0
  145. package/components/google/util/index.d.ts +11 -0
  146. package/components/nav/Favorite.vue +1 -1
  147. package/components/nav/Group.vue +70 -47
  148. package/components/nav/Header.vue +5 -1
  149. package/components/nav/NamespaceFilter.vue +13 -1
  150. package/components/nav/NotificationCenter/Notification.vue +510 -0
  151. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  152. package/components/nav/NotificationCenter/index.vue +148 -0
  153. package/composables/drawer.ts +26 -0
  154. package/composables/resources.test.ts +63 -0
  155. package/composables/resources.ts +38 -0
  156. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  157. package/config/labels-annotations.js +6 -0
  158. package/config/product/auth.js +16 -1
  159. package/config/product/{cis.js → compliance.js} +23 -26
  160. package/config/product/explorer.js +5 -1
  161. package/config/product/fleet.js +7 -0
  162. package/config/product/settings.js +22 -11
  163. package/config/query-params.js +3 -0
  164. package/config/roles.ts +1 -1
  165. package/config/router/navigation-guards/authentication.js +51 -2
  166. package/config/router/routes.js +27 -31
  167. package/config/settings.ts +21 -3
  168. package/config/store.js +2 -0
  169. package/config/system-namespaces.js +1 -1
  170. package/config/table-headers.js +2 -2
  171. package/config/types.js +15 -6
  172. package/core/plugin.ts +32 -7
  173. package/core/types.ts +18 -1
  174. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  175. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  176. package/detail/management.cattle.io.oidcclient.vue +369 -0
  177. package/detail/node.vue +2 -2
  178. package/detail/pod.vue +2 -2
  179. package/detail/service.vue +10 -1
  180. package/detail/workload/index.vue +8 -2
  181. package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
  182. package/dialog/GenericPrompt.vue +1 -1
  183. package/dialog/ImportDialog.vue +8 -8
  184. package/dialog/OidcClientSecretDialog.vue +117 -0
  185. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  186. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +5 -2
  187. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  188. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  189. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  190. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  191. package/edit/configmap.vue +4 -1
  192. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  193. package/edit/fleet.cattle.io.gitrepo.vue +44 -222
  194. package/edit/fleet.cattle.io.helmop.vue +44 -269
  195. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  196. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  197. package/edit/logging-flow/index.vue +1 -0
  198. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  199. package/edit/management.cattle.io.fleetworkspace.vue +1 -0
  200. package/edit/management.cattle.io.oidcclient.vue +162 -0
  201. package/edit/management.cattle.io.project.vue +4 -1
  202. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  203. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  204. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  205. package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
  206. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  207. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  208. package/edit/monitoring.coreos.com.route.vue +1 -0
  209. package/edit/namespace.vue +1 -0
  210. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  211. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  212. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
  213. package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
  214. package/edit/node.vue +1 -0
  215. package/edit/persistentvolume/index.vue +4 -1
  216. package/edit/provisioning.cattle.io.cluster/rke2.vue +418 -382
  217. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +27 -27
  218. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  219. package/edit/resources.cattle.io.restore.vue +1 -1
  220. package/edit/secret/index.vue +1 -0
  221. package/edit/service.vue +4 -1
  222. package/edit/serviceaccount.vue +4 -1
  223. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  224. package/edit/workload/index.vue +5 -0
  225. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  226. package/list/management.cattle.io.oidcclient.vue +108 -0
  227. package/list/node.vue +2 -0
  228. package/machine-config/amazonec2.vue +3 -24
  229. package/machine-config/components/GCEImage.vue +374 -0
  230. package/machine-config/google.vue +617 -0
  231. package/mixins/__tests__/brand.spec.ts +170 -0
  232. package/mixins/brand.js +16 -17
  233. package/mixins/create-edit-view/index.js +5 -0
  234. package/mixins/resource-fetch-api-pagination.js +16 -0
  235. package/mixins/vue-select-overrides.js +1 -0
  236. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  237. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  238. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  239. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  240. package/models/fleet-application.js +8 -79
  241. package/models/fleet.cattle.io.cluster.js +11 -0
  242. package/models/fleet.cattle.io.gitrepo.js +2 -2
  243. package/models/fleet.cattle.io.helmop.js +9 -39
  244. package/models/management.cattle.io.fleetworkspace.js +2 -1
  245. package/models/management.cattle.io.oidcclient.js +18 -0
  246. package/models/management.cattle.io.registration.js +3 -0
  247. package/models/provisioning.cattle.io.cluster.js +5 -5
  248. package/models/service.js +4 -0
  249. package/models/workload.js +5 -0
  250. package/package.json +1 -1
  251. package/pages/about.vue +4 -58
  252. package/pages/auth/login.vue +1 -1
  253. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +0 -1
  254. package/pages/c/_cluster/apps/charts/index.vue +285 -81
  255. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  256. package/pages/c/_cluster/explorer/index.vue +3 -3
  257. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  258. package/pages/c/_cluster/fleet/application/create.vue +3 -2
  259. package/pages/c/_cluster/fleet/index.vue +94 -56
  260. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  261. package/pages/c/_cluster/longhorn/index.vue +5 -2
  262. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  263. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  264. package/pages/explorer/resource/detail/configmap.vue +30 -7
  265. package/pages/explorer/resource/detail/secret.vue +50 -0
  266. package/pages/home.vue +9 -55
  267. package/pages/support/index.vue +4 -6
  268. package/plugins/dashboard-store/actions.js +19 -5
  269. package/plugins/dashboard-store/getters.js +4 -0
  270. package/plugins/dashboard-store/resource-class.js +16 -2
  271. package/plugins/steve/steve-pagination-utils.ts +26 -18
  272. package/plugins/steve/subscribe.js +6 -1
  273. package/rancher-components/Banner/Banner.vue +13 -0
  274. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -4
  275. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  276. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  277. package/rancher-components/RcItemCard/RcItemCard.vue +8 -3
  278. package/store/auth.js +2 -0
  279. package/store/catalog.js +23 -1
  280. package/store/growl.js +97 -8
  281. package/store/index.js +6 -0
  282. package/store/notifications.ts +426 -0
  283. package/store/prefs.js +0 -1
  284. package/store/type-map.js +19 -16
  285. package/store/uiplugins.ts +15 -1
  286. package/types/fleet.d.ts +24 -0
  287. package/types/notifications/index.ts +74 -0
  288. package/types/shell/index.d.ts +46 -32
  289. package/types/store/dashboard-store.types.ts +16 -0
  290. package/utils/__tests__/fleet.test.ts +148 -0
  291. package/utils/__tests__/object.test.ts +54 -1
  292. package/utils/__tests__/string.test.ts +273 -1
  293. package/utils/__tests__/time.test.ts +31 -0
  294. package/utils/auth.js +9 -2
  295. package/utils/crypto/encryption.ts +103 -0
  296. package/utils/cspAdaptor.ts +51 -0
  297. package/utils/fleet.ts +54 -65
  298. package/utils/object.js +36 -0
  299. package/utils/pagination-utils.ts +1 -1
  300. package/utils/release-notes.ts +48 -0
  301. package/utils/selector-typed.ts +7 -2
  302. package/utils/string.js +24 -0
  303. package/utils/{time.js → time.ts} +25 -6
  304. package/utils/uiplugins.ts +22 -0
  305. package/utils/validators/formRules/index.ts +3 -0
  306. package/components/Resource/Detail/TitleBar/composable.ts +0 -31
  307. package/config/product/legacy.js +0 -62
  308. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  309. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  310. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  311. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
  312. /package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -0
@@ -0,0 +1,52 @@
1
+ import { computed, ComputedRef } from 'vue';
2
+ import { Props } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue';
3
+ import { SECRET_TYPES } from '@shell/config/secret';
4
+ import { useStore } from 'vuex';
5
+ import { useI18n } from '@shell/composables/useI18n';
6
+ import {
7
+ useBasic, useSsh, useTls, useSecretInfo, useDockerRegistry, useServiceAccount, useDockerBasic
8
+ } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types';
9
+
10
+ export const useSecretDataTabDefaultProps = (resource: any): ComputedRef<Props> => {
11
+ const store = useStore();
12
+ const i18n = useI18n(store);
13
+ const secretInfo = useSecretInfo(resource);
14
+
15
+ return computed(() => {
16
+ switch (secretInfo.value.secretType) {
17
+ case SECRET_TYPES.DOCKER_JSON:
18
+ return {
19
+ tabLabel: i18n.t('secret.data'),
20
+ secretData: {
21
+ registry: useDockerRegistry(resource).value,
22
+ basicAuth: useDockerBasic(resource).value
23
+ }
24
+ };
25
+ case SECRET_TYPES.TLS:
26
+ return {
27
+ tabLabel: i18n.t('secret.certificate.certificate'),
28
+ secretData: { certificate: useTls(resource).value }
29
+ };
30
+ case SECRET_TYPES.SERVICE_ACCT:
31
+ return {
32
+ tabLabel: i18n.t('secret.data'),
33
+ secretData: { serviceAccount: useServiceAccount(resource).value }
34
+ };
35
+ case SECRET_TYPES.SSH:
36
+ return {
37
+ tabLabel: i18n.t('secret.ssh.keys'),
38
+ secretData: { ssh: useSsh(resource).value }
39
+ };
40
+ case SECRET_TYPES.BASIC:
41
+ return {
42
+ tabLabel: i18n.t('secret.data'),
43
+ secretData: { basicAuth: useBasic(resource).value }
44
+ };
45
+ default:
46
+ return {
47
+ tabLabel: i18n.t('secret.data'),
48
+ secretData: { basic: useBasic(resource).value }
49
+ };
50
+ }
51
+ });
52
+ };
@@ -0,0 +1,71 @@
1
+ <script lang="ts">
2
+ import Tab from '@shell/components/Tabbed/Tab.vue';
3
+ import Basic, { Props as BasicProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue';
4
+ import Ssh, { Props as SshProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue';
5
+ import ServiceAccountToken, { Props as ServiceAccountTokenProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue';
6
+ import Certificate, { Props as CertificateProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue';
7
+ import BasicAuth, { Props as BasicAuthProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue';
8
+ import Registry, { Props as RegistryProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue';
9
+
10
+ export interface SecretData {
11
+ basic?: BasicProps;
12
+ basicAuth?: BasicAuthProps;
13
+ ssh?: SshProps;
14
+ serviceAccount?: ServiceAccountTokenProps;
15
+ certificate?: CertificateProps;
16
+ registry?: RegistryProps;
17
+ }
18
+
19
+ export interface Props {
20
+ tabLabel: string;
21
+ secretData: SecretData;
22
+
23
+ weight?: number;
24
+ }
25
+ </script>
26
+
27
+ <script lang="ts" setup>
28
+ const props = defineProps<Props>();
29
+ </script>
30
+
31
+ <template>
32
+ <Tab
33
+ class="secret-data-tab"
34
+ name="data"
35
+ :label="props.tabLabel"
36
+ :weight="props.weight"
37
+ >
38
+ <Registry
39
+ v-if="props.secretData.registry"
40
+ v-bind="props.secretData.registry"
41
+ />
42
+ <BasicAuth
43
+ v-if="props.secretData.basicAuth"
44
+ v-bind="props.secretData.basicAuth"
45
+ />
46
+ <Certificate
47
+ v-else-if="props.secretData.certificate"
48
+ v-bind="props.secretData.certificate"
49
+ />
50
+ <ServiceAccountToken
51
+ v-if="props.secretData.serviceAccount"
52
+ v-bind="props.secretData.serviceAccount"
53
+ />
54
+ <Ssh
55
+ v-if="props.secretData.ssh"
56
+ v-bind="props.secretData.ssh"
57
+ />
58
+ <Basic
59
+ v-if="props.secretData.basic"
60
+ v-bind="props.secretData.basic"
61
+ />
62
+ </Tab>
63
+ </template>
64
+
65
+ <style lang="scss" scoped>
66
+ .secret-data-tab {
67
+ :deep() .entry:not(:first-of-type) {
68
+ margin-top: 16px;
69
+ }
70
+ }
71
+ </style>
@@ -8,6 +8,7 @@
8
8
  h1.title {
9
9
  display: inline-block;
10
10
  align-items: center;
11
- line-height: 18px;
11
+ display: flex;
12
+ flex-direction: row;
12
13
  }
13
14
  </style>
@@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
2
2
  import Title from '@shell/components/Resource/Detail/TitleBar/Title.vue';
3
3
 
4
4
  describe('component: TitleBar/Title', () => {
5
- it('shoulder render container with class title', async() => {
5
+ it('should render container with class title', async() => {
6
6
  const wrapper = mount(Title);
7
7
 
8
8
  expect(wrapper.find('.title').exists()).toBeTruthy();
@@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
2
2
  import Top from '@shell/components/Resource/Detail/TitleBar/Top.vue';
3
3
 
4
4
  describe('component: TitleBar/Top', () => {
5
- it('shoulder render container with class top', async() => {
5
+ it('should render container with class top', async() => {
6
6
  const wrapper = mount(Top);
7
7
 
8
8
  expect(wrapper.find('.top').exists()).toBeTruthy();
@@ -0,0 +1,63 @@
1
+ import { useDefaultTitleBarProps } from '@shell/components/Resource/Detail/TitleBar/composables';
2
+ import { ref } from 'vue';
3
+ import { useRoute } from 'vue-router';
4
+
5
+ const mockStore = {
6
+ getters: {
7
+ 'type-map/labelFor': jest.fn(),
8
+ 'type-map/hasGraph': jest.fn(),
9
+ currentStore: jest.fn(),
10
+ 'cluster/schemaFor': jest.fn()
11
+ }
12
+ };
13
+ const mockRoute = { params: { cluster: 'CLUSTER' } };
14
+ const mockDrawer = { openResourceDetailDrawer: jest.fn() };
15
+
16
+ jest.mock('vuex', () => ({ useStore: () => mockStore }));
17
+ jest.mock('vue-router', () => ({ useRoute: () => mockRoute }));
18
+ jest.mock('@shell/components/Drawer/ResourceDetailDrawer/composables', () => ({ useResourceDetailDrawer: () => mockDrawer }));
19
+
20
+ describe('composables: TitleBar', () => {
21
+ const resource = {
22
+ nameDisplay: 'RESOURCE_NAME',
23
+ namespace: 'RESOURCE_NAMESPACE',
24
+ type: 'RESOURCE_TYPE',
25
+ stateBackground: 'RESOURCE_STATE_BACKGROUND',
26
+ stateDisplay: 'RESOURCE_STATE_DISPLAY',
27
+ description: 'RESOURCE_DESCRIPTION',
28
+ };
29
+ const labelFor = 'LABEL_FOR';
30
+ const schema = { type: 'SCHEMA' };
31
+ const hasGraph = true;
32
+
33
+ it('should return the appropriate values based on input', async() => {
34
+ const route = useRoute();
35
+
36
+ mockStore.getters['currentStore'].mockImplementation(() => 'cluster');
37
+ mockStore.getters['cluster/schemaFor'].mockImplementation(() => schema);
38
+ mockStore.getters['type-map/labelFor'].mockImplementation(() => labelFor);
39
+ mockStore.getters['type-map/hasGraph'].mockImplementation(() => hasGraph);
40
+
41
+ const props = useDefaultTitleBarProps(resource, ref(undefined));
42
+
43
+ expect(props.value.resourceTypeLabel).toStrictEqual(labelFor);
44
+ expect(mockStore.getters['type-map/labelFor']).toHaveBeenLastCalledWith(schema);
45
+ expect(mockStore.getters['type-map/hasGraph']).toHaveBeenLastCalledWith(resource.type);
46
+ expect(mockStore.getters['currentStore']).toHaveBeenLastCalledWith(resource.type);
47
+ expect(mockStore.getters['cluster/schemaFor']).toHaveBeenLastCalledWith(resource.type);
48
+ expect(props.value.resourceTo?.params.product).toStrictEqual('explorer');
49
+ expect(props.value.resourceTo?.params.cluster).toStrictEqual(route.params.cluster);
50
+ expect(props.value.resourceTo?.params.namespace).toStrictEqual(resource.namespace);
51
+ expect(props.value.resourceTo?.params.resource).toStrictEqual(resource.type);
52
+ expect(props.value.resourceName).toStrictEqual(resource.nameDisplay);
53
+
54
+ expect(props.value.actionMenuResource).toStrictEqual(resource);
55
+ expect(props.value.badge?.color).toStrictEqual(resource.stateBackground);
56
+ expect(props.value.badge?.label).toStrictEqual(resource.stateDisplay);
57
+ expect(props.value.description).toStrictEqual(resource.description);
58
+ expect(props.value.showViewOptions).toStrictEqual(hasGraph);
59
+
60
+ props.value.onShowConfiguration?.('callback');
61
+ expect(mockDrawer.openResourceDetailDrawer).toHaveBeenCalledTimes(1);
62
+ });
63
+ });
@@ -11,7 +11,7 @@ describe('component: TitleBar/index', () => {
11
11
  const resourceName = 'RESOURCE_NAME';
12
12
  const store = createStore({});
13
13
 
14
- it('shoulder render container with class title-bar', async() => {
14
+ it('should render container with class title-bar', async() => {
15
15
  const wrapper = mount(TitleBar, {
16
16
  props: {
17
17
  resourceTypeLabel,
@@ -0,0 +1,44 @@
1
+ import { useResourceDetailDrawer } from '@shell/components/Drawer/ResourceDetailDrawer/composables';
2
+ import { TitleBarProps } from '@shell/components/Resource/Detail/TitleBar/index.vue';
3
+ import { computed, Ref, toValue } from 'vue';
4
+ import { useRoute } from 'vue-router';
5
+ import { useStore } from 'vuex';
6
+
7
+ export const useDefaultTitleBarProps = (resource: any, resourceSubtype?: Ref<string | undefined>): Ref<TitleBarProps> => {
8
+ const route = useRoute();
9
+ const store = useStore();
10
+ const { openResourceDetailDrawer } = useResourceDetailDrawer();
11
+ const resourceValue = toValue(resource);
12
+
13
+ return computed(() => {
14
+ const resourceSubtypeValue = toValue(resourceSubtype);
15
+ const currentStore = store.getters['currentStore'](resourceValue.type);
16
+ const schema = store.getters[`${ currentStore }/schemaFor`](resourceValue.type);
17
+ const resourceTypeLabel = resourceValue.parentNameOverride || store.getters['type-map/labelFor'](schema);
18
+ const resourceName = resourceSubtypeValue ? `${ resourceSubtypeValue } - ${ resourceValue.nameDisplay }` : resourceValue.nameDisplay;
19
+ const resourceTo = resourceValue.listLocation || {
20
+ name: 'c-cluster-product-resource',
21
+ params: {
22
+ product: 'explorer',
23
+ cluster: route?.params.cluster,
24
+ namespace: resourceValue.namespace,
25
+ resource: resourceValue.type
26
+ }
27
+ };
28
+ const hasGraph = !!store.getters['type-map/hasGraph'](resourceValue.type);
29
+
30
+ return {
31
+ resourceTypeLabel,
32
+ resourceTo,
33
+ resourceName,
34
+ actionMenuResource: resourceValue,
35
+ badge: {
36
+ color: resourceValue.stateBackground,
37
+ label: resourceValue.stateDisplay
38
+ },
39
+ description: resourceValue.description,
40
+ showViewOptions: hasGraph,
41
+ onShowConfiguration: (returnFocusSelector: string) => openResourceDetailDrawer(resourceValue, returnFocusSelector)
42
+ };
43
+ });
44
+ };
@@ -1,12 +1,16 @@
1
1
  <script lang="ts">
2
- import BadgeState from '@pkg/rancher-components/src/components/BadgeState/BadgeState.vue';
3
- import { RouteLocationRaw } from 'vue-router';
2
+ import BadgeState from '@components/BadgeState/BadgeState.vue';
3
+ import { RouteLocationRaw, useRouter } from 'vue-router';
4
4
  import Title from '@shell/components/Resource/Detail/TitleBar/Title.vue';
5
5
  import Top from '@shell/components/Resource/Detail/TitleBar/Top.vue';
6
6
  import ActionMenu from '@shell/components/ActionMenuShell.vue';
7
7
  import { useStore } from 'vuex';
8
8
  import { useI18n } from '@shell/composables/useI18n';
9
- import RcButton from '~/pkg/rancher-components/src/components/RcButton/RcButton.vue';
9
+ import RcButton from '@components/RcButton/RcButton.vue';
10
+ import TabTitle from '@shell/components/TabTitle';
11
+ import { computed, ref, watch } from 'vue';
12
+ import { _CONFIG, _GRAPH, AS } from '@shell/config/query-params';
13
+ import ButtonGroup from '@shell/components/ButtonGroup';
10
14
 
11
15
  export interface Badge {
12
16
  color: 'bg-success' | 'bg-error' | 'bg-warning' | 'bg-info';
@@ -25,7 +29,10 @@ export interface TitleBarProps {
25
29
  // I don't have the time right now to swap this out though.
26
30
  actionMenuResource?: any;
27
31
 
28
- onShowConfiguration?: () => void;
32
+ // Please don't expand this pattern, this was a quick fix to resolve a conflict between the new masthead and fleet.
33
+ showViewOptions?: boolean;
34
+
35
+ onShowConfiguration?: (returnFocusSelector: string) => void;
29
36
  }
30
37
 
31
38
  const showConfigurationIcon = require(`@shell/assets/images/icons/document.svg`);
@@ -33,19 +40,50 @@ const showConfigurationIcon = require(`@shell/assets/images/icons/document.svg`)
33
40
 
34
41
  <script setup lang="ts">
35
42
  const {
36
- resourceTypeLabel, resourceTo, resourceName, description, badge, onShowConfiguration
43
+ resourceTypeLabel, resourceTo, resourceName, description, badge, showViewOptions, onShowConfiguration,
37
44
  } = defineProps<TitleBarProps>();
38
45
 
39
46
  const store = useStore();
40
47
  const i18n = useI18n(store);
48
+ const router = useRouter();
41
49
 
42
50
  const emit = defineEmits(['show-configuration']);
51
+ const showConfigurationDataTestId = 'show-configuration-cta';
52
+ const showConfigurationReturnFocusSelector = computed(() => `[data-testid="${ showConfigurationDataTestId }"]`);
53
+
54
+ const currentView = ref(router?.currentRoute?.value?.query?.as || _CONFIG);
55
+ const viewOptions = computed(() => {
56
+ if (!showViewOptions) {
57
+ return;
58
+ }
59
+
60
+ return [
61
+ {
62
+ labelKey: 'resourceDetail.masthead.config',
63
+ value: _CONFIG,
64
+ },
65
+ {
66
+ labelKey: 'resourceDetail.masthead.graph',
67
+ value: _GRAPH,
68
+ }
69
+ ];
70
+ });
71
+
72
+ watch(
73
+ () => currentView.value,
74
+ () => {
75
+ router.push({ query: { [AS]: currentView.value } });
76
+ }
77
+ );
43
78
  </script>
44
79
 
45
80
  <template>
46
81
  <div class="title-bar">
47
82
  <Top>
48
- <Title>
83
+ <Title class="title">
84
+ <TabTitle :show-child="false">
85
+ {{ resourceTypeLabel }}
86
+ </TabTitle>
49
87
  <router-link
50
88
  v-if="resourceTo"
51
89
  :to="resourceTo"
@@ -59,35 +97,44 @@ const emit = defineEmits(['show-configuration']);
59
97
  >
60
98
  {{ resourceTypeLabel }}:
61
99
  </span>
62
- <span class="resource-name">
100
+ <span class="resource-name masthead-resource-title">
63
101
  {{ resourceName }}
64
102
  </span>
65
103
  <BadgeState
66
104
  v-if="badge"
105
+ class="badge-state"
67
106
  :color="badge.color"
68
107
  :label="badge.label"
69
108
  />
70
109
  </Title>
71
110
  <div class="actions">
111
+ <!-- Please don't expand this pattern, this was a quick fix to resolve a conflict between the new masthead and fleet. -->
112
+ <ButtonGroup
113
+ v-if="viewOptions"
114
+ v-model:value="currentView"
115
+ :options="viewOptions"
116
+ />
72
117
  <RcButton
73
118
  v-if="onShowConfiguration"
119
+ :data-testid="showConfigurationDataTestId"
74
120
  class="show-configuration"
75
121
  :primary="true"
76
122
  :aria-label="i18n.t('component.resource.detail.titleBar.ariaLabel.showConfiguration', { resource: resourceName })"
77
- @click="emit('show-configuration')"
123
+ @click="() => emit('show-configuration', showConfigurationReturnFocusSelector)"
78
124
  >
79
125
  <img
80
126
  :src="showConfigurationIcon"
81
127
  class="mmr-3"
128
+ aria-hidden="true"
82
129
  >
83
130
  {{ i18n.t('component.resource.detail.titleBar.showConfiguration') }}
84
131
  </RcButton>
85
132
  <ActionMenu
86
133
  v-if="actionMenuResource"
87
- class="title-bar-action-menu"
88
134
  button-role="multiAction"
89
135
  :resource="actionMenuResource"
90
136
  data-testid="masthead-action-menu"
137
+ :button-aria-label="i18n.t('component.resource.detail.titleBar.ariaLabel.actionMenu', { resource: resourceName })"
91
138
  />
92
139
  </div>
93
140
  </Top>
@@ -102,13 +149,18 @@ const emit = defineEmits(['show-configuration']);
102
149
 
103
150
  <style lang="scss" scoped>
104
151
  .title-bar {
105
- &:deep() .badge-state {
152
+ min-width: 740px;
153
+
154
+ .badge-state {
106
155
  font-size: 16px;
107
156
  margin-left: 4px;
108
- top: -4px;
109
157
  position: relative;
110
158
  }
111
159
 
160
+ .show-configuration {
161
+ margin-left: 16px;
162
+ }
163
+
112
164
  &:deep() button[data-testid="masthead-action-menu"] {
113
165
  border-radius: 4px;
114
166
  width: 35px;
@@ -120,5 +172,25 @@ const emit = defineEmits(['show-configuration']);
120
172
  justify-content: center;
121
173
  align-items: center;
122
174
  }
175
+
176
+ .description {
177
+ max-width: 60%;
178
+ }
179
+
180
+ // This prevents the title from overlapping with the actions
181
+ .title {
182
+ max-width: calc(100% - 260px);
183
+ }
184
+
185
+ // We want the resource name to be what collaspes wh
186
+ .resource-name {
187
+ display: inline-block;
188
+ flex: 1;
189
+ white-space: nowrap;
190
+ overflow-x: hidden;
191
+ overflow-y: clip;
192
+ text-overflow: ellipsis;
193
+ margin-left: 4px;
194
+ }
123
195
  }
124
196
  </style>
@@ -0,0 +1,45 @@
1
+ import { computed, Ref, toValue } from 'vue';
2
+ import { useStore } from 'vuex';
3
+ import { Props as BannerProps } from '@components/Banner/Banner.vue';
4
+ import { useI18n } from '@shell/composables/useI18n';
5
+
6
+ export const useResourceDetailBannerProps = (resource: any): Ref<BannerProps | undefined> => {
7
+ const store = useStore();
8
+ const i18n = useI18n(store);
9
+ const resourceValue = toValue(resource);
10
+
11
+ return computed(() => {
12
+ const options = store.getters[`type-map/optionsFor`](resourceValue.type);
13
+
14
+ if (options.hideBanner) {
15
+ return;
16
+ }
17
+
18
+ if (resourceValue?.stateObj?.error) {
19
+ const defaultErrorMessage = i18n.t('resourceDetail.masthead.defaultBannerMessage.error', undefined, true);
20
+
21
+ return {
22
+ color: 'error',
23
+ label: resourceValue.stateObj.message || defaultErrorMessage
24
+ };
25
+ }
26
+
27
+ if (resourceValue?.spec?.paused) {
28
+ return {
29
+ color: 'info',
30
+ label: i18n.t('asyncButton.pause.description')
31
+ };
32
+ }
33
+
34
+ if (resourceValue?.stateObj?.transitioning) {
35
+ const defaultTransitioningMessage = i18n.t('resourceDetail.masthead.defaultBannerMessage.transitioning', undefined, true);
36
+
37
+ return {
38
+ color: 'info',
39
+ label: resourceValue.stateObj.message || defaultTransitioningMessage
40
+ };
41
+ }
42
+
43
+ return undefined;
44
+ });
45
+ };
@@ -0,0 +1,70 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { _VIEW } from '@shell/config/query-params';
3
+ import Index from '@shell/components/ResourceDetail/Masthead/index.vue';
4
+ import * as PageEnabled from '@shell/composables/useIsNewDetailPageEnabled';
5
+ import { computed } from 'vue';
6
+
7
+ jest.mock('@shell/composables/useIsNewDetailPageEnabled');
8
+ jest.mock('@shell/components/ResourceDetail/Masthead/latest.vue', () => ({
9
+ name: 'Latest',
10
+ template: `<div>Latest</div>`,
11
+ props: ['value', 'resourceSubtype']
12
+ }));
13
+ jest.mock('@shell/components/ResourceDetail/Masthead/legacy.vue', () => ({
14
+ name: 'Legacy',
15
+ template: `<div>Legacy</div>`
16
+ }));
17
+
18
+ describe('component: Masthead/index', () => {
19
+ const useIsNewDetailPageEnabledSpy = jest.spyOn(PageEnabled, 'useIsNewDetailPageEnabled');
20
+
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ it('should render Latest if useIsNewDetailPageEnabled is true and mode is _VIEW', () => {
26
+ useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => true));
27
+ const props = {
28
+ value: { type: 'VALUE' },
29
+ mode: _VIEW,
30
+ resourceSubtype: 'SUBTYPE'
31
+ };
32
+
33
+ const wrapper = mount(Index, { props });
34
+
35
+ const component = wrapper.getComponent({ name: 'Latest' });
36
+
37
+ expect(component.props('value')).toStrictEqual(props.value);
38
+ expect(component.props('resourceSubtype')).toStrictEqual(props.resourceSubtype);
39
+ });
40
+
41
+ it('should render Legacy if useIsNewDetailPageEnabled is false and mode is _VIEW', () => {
42
+ useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => false));
43
+ const props = {
44
+ value: { type: 'VALUE' },
45
+ mode: _VIEW,
46
+ resourceSubtype: 'SUBTYPE'
47
+ };
48
+
49
+ const wrapper = mount(Index, { props });
50
+
51
+ const component = wrapper.getComponent({ name: 'Legacy' });
52
+
53
+ expect(component).toBeDefined();
54
+ });
55
+
56
+ it('should render Legacy if useIsNewDetailPageEnabled is true and mode is not _VIEW', () => {
57
+ useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => true));
58
+ const props = {
59
+ value: { type: 'VALUE' },
60
+ mode: 'ANYTHING',
61
+ resourceSubtype: 'SUBTYPE'
62
+ };
63
+
64
+ const wrapper = mount(Index, { props });
65
+
66
+ const component = wrapper.getComponent({ name: 'Legacy' });
67
+
68
+ expect(component).toBeDefined();
69
+ });
70
+ });
@@ -1,6 +1,6 @@
1
1
  import { mount, RouterLinkStub } from '@vue/test-utils';
2
2
  import { _VIEW } from '@shell/config/query-params';
3
- import Masthead from '@shell/components/ResourceDetail/Masthead.vue';
3
+ import Legacy from '@shell/components/ResourceDetail/Masthead/legacy.vue';
4
4
  import { createStore } from 'vuex';
5
5
 
6
6
  const mockedStore = () => {
@@ -30,7 +30,7 @@ const requiredSetup = () => {
30
30
  };
31
31
  };
32
32
 
33
- describe('component: Masthead', () => {
33
+ describe('component: Masthead/legacy', () => {
34
34
  it.each([
35
35
  ['hidden', '', false, { displayName: 'admin', location: { id: 'resource-id' } }, false, false],
36
36
  ['plain-text', 'admin', true, { displayName: 'admin', location: null }, false, true],
@@ -43,7 +43,7 @@ describe('component: Masthead', () => {
43
43
  showLink,
44
44
  showPlainText,
45
45
  ) => {
46
- const wrapper = mount(Masthead, {
46
+ const wrapper = mount(Legacy, {
47
47
  props: {
48
48
  mode: _VIEW,
49
49
  value: {
@@ -0,0 +1,65 @@
1
+ <script lang="ts">
2
+ import { _VIEW, _YAML } from '@shell/config/query-params';
3
+ import Latest from '@shell/components/ResourceDetail/Masthead/latest.vue';
4
+ import Legacy from '@shell/components/ResourceDetail/Masthead/legacy.vue';
5
+ import { useIsNewDetailPageEnabled } from '@shell/composables/useIsNewDetailPageEnabled';
6
+ import { computed } from 'vue';
7
+
8
+ export interface Props {
9
+ value?: Object;
10
+ mode?: string;
11
+ realMode?: string;
12
+ as?: string;
13
+ hasGraph?: boolean;
14
+ hasDetail?: boolean;
15
+ hasEdit?: boolean;
16
+ storeOverride?: string;
17
+ resource?: string;
18
+ resourceSubtype?: string;
19
+ parentRouteOverride?: string;
20
+ canViewYaml?: boolean;
21
+ }
22
+
23
+ </script>
24
+ <script lang="ts" setup>
25
+
26
+ const props = withDefaults(defineProps<Props>(), {
27
+ value: () => ({}),
28
+ mode: 'create',
29
+ realMode: 'create',
30
+ as: _YAML,
31
+ hasGraph: false,
32
+ hasDetail: false,
33
+ hasEdit: false,
34
+ storeOverride: undefined,
35
+ resource: undefined,
36
+ resourceSubtype: undefined,
37
+ parentRouteOverride: undefined,
38
+ canViewYaml: false
39
+ });
40
+
41
+ const isNewDetailPageEnabled = useIsNewDetailPageEnabled();
42
+ const isView = computed(() => props.mode === _VIEW);
43
+ const showLatestMasthead = computed(() => isNewDetailPageEnabled.value && isView.value );
44
+ </script>
45
+
46
+ <template>
47
+ <Latest
48
+ v-if="showLatestMasthead"
49
+ :value="props.value"
50
+ :resourceSubtype="props.resourceSubtype"
51
+ />
52
+ <Legacy
53
+ v-else
54
+ v-bind="props"
55
+ >
56
+ <slot name="default" />
57
+ </Legacy>
58
+ </template>
59
+
60
+ <style lang="scss" scoped>
61
+ .new.state-banner {
62
+ margin: 0;
63
+ margin-top: 16px;
64
+ }
65
+ </style>