@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,265 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { _EDIT } from '@shell/config/query-params';
3
+ import FleetGitRepoPaths, { Subpath, getRelevantPrefixes } from '@shell/components/fleet/FleetGitRepoPaths.vue';
4
+
5
+ describe('fx: getRelevantPrefixes', () => {
6
+ it('should return an empty array for an empty input array', () => {
7
+ const paths: string[] = [];
8
+
9
+ expect(getRelevantPrefixes(paths)).toStrictEqual([]);
10
+ });
11
+
12
+ it('should return the single path if only one is provided', () => {
13
+ const paths: string[] = ['aaa'];
14
+
15
+ expect(getRelevantPrefixes(paths)).toStrictEqual(['aaa']);
16
+ });
17
+
18
+ it('should return only 2nd level prefixes', () => {
19
+ const paths: string[] = [
20
+ 'folderA/aaa',
21
+ 'folderA/subfolderB/bbb',
22
+ 'folderC/ccc'
23
+ ];
24
+
25
+ const res = getRelevantPrefixes(paths);
26
+
27
+ expect(res).toStrictEqual([
28
+ 'folderC',
29
+ 'folderA/subfolderB',
30
+ 'folderA'
31
+ ]);
32
+ });
33
+
34
+ it('should return common prefix between 2 paths with same prefix', () => {
35
+ const paths: string[] = [
36
+ 'level1/level2',
37
+ 'level1/level2/aaa'
38
+ ];
39
+
40
+ const res = getRelevantPrefixes(paths);
41
+
42
+ expect(res).toStrictEqual([
43
+ 'level1/level2'
44
+ ]);
45
+ });
46
+
47
+ it('should return common prefix between 2 paths with same low level prefix', () => {
48
+ const paths: string[] = [
49
+ 'aaa/bbb/ccc',
50
+ 'aaa/bbb/eee/fff'
51
+ ];
52
+
53
+ const res = getRelevantPrefixes(paths);
54
+
55
+ expect(res).toStrictEqual([
56
+ 'aaa/bbb/eee',
57
+ 'aaa/bbb'
58
+ ]);
59
+ });
60
+
61
+ it('should return all original paths if they are leaves or satisfy the one-child condition', () => {
62
+ const paths: string[] = [
63
+ 'aaa',
64
+ 'bbb',
65
+ 'ccc'
66
+ ];
67
+
68
+ const res = getRelevantPrefixes(paths);
69
+
70
+ expect(res).toStrictEqual(['ccc', 'bbb', 'aaa']);
71
+ });
72
+
73
+ it('should handle multiple prefixes', () => {
74
+ const paths: string[] = [
75
+ 'root/file1.txt',
76
+ 'root/file2.txt',
77
+ 'root/file3.txt'
78
+ ];
79
+
80
+ const res = getRelevantPrefixes(paths);
81
+
82
+ expect(res).toStrictEqual([
83
+ 'root'
84
+ ]);
85
+ });
86
+
87
+ it('should add leaf nodes and single-child original paths, not grouping parents', () => {
88
+ const paths: string[] = [
89
+ 'driven/kustomize/path1',
90
+ 'driven/kustomize/path2',
91
+ 'driven/kustomize',
92
+ 'driven/simple',
93
+ 'driven/helm'
94
+ ];
95
+
96
+ const res = getRelevantPrefixes(paths);
97
+
98
+ expect(res).toStrictEqual([
99
+ 'driven/kustomize',
100
+ 'driven',
101
+ ].sort((a, b) => b.localeCompare(a)));
102
+ });
103
+ });
104
+
105
+ describe('decode spec.targets to build UI source data', () => {
106
+ describe('mode: edit', () => {
107
+ const mode = _EDIT;
108
+
109
+ it('should build empty rows from empty paths and empty bundles', async() => {
110
+ const paths: string[] = [];
111
+ const bundles: Subpath[] = [];
112
+
113
+ const wrapper = mount(FleetGitRepoPaths, {
114
+ props: {
115
+ value: { paths, bundles },
116
+ mode,
117
+ touched: {}
118
+ },
119
+ });
120
+
121
+ const { rows } = wrapper.vm;
122
+
123
+ expect(rows).toStrictEqual([]);
124
+ });
125
+
126
+ it('should build 1 row from 1 path', async() => {
127
+ const paths: string[] = ['path1'];
128
+ const bundles: Subpath[] = [];
129
+
130
+ const wrapper = mount(FleetGitRepoPaths, {
131
+ props: {
132
+ value: { paths, bundles },
133
+ mode,
134
+ touched: {}
135
+ },
136
+ });
137
+
138
+ const { rows } = wrapper.vm;
139
+
140
+ expect(rows).toStrictEqual([{ path: 'path1' }]);
141
+ });
142
+
143
+ it('should build empty rows from empty subpaths', async() => {
144
+ const paths: string[] = [];
145
+ const bundles: any[] = [{}];
146
+
147
+ const wrapper = mount(FleetGitRepoPaths, {
148
+ props: {
149
+ value: { paths, bundles },
150
+ mode,
151
+ touched: {}
152
+ },
153
+ });
154
+
155
+ const { rows } = wrapper.vm;
156
+
157
+ expect(rows).toStrictEqual([]);
158
+ });
159
+
160
+ it('should build empty rows from bundles with empty key', async() => {
161
+ const paths: string[] = [];
162
+ const bundles: Subpath[] = [{ base: '', options: 'dev.yaml' }];
163
+
164
+ const wrapper = mount(FleetGitRepoPaths, {
165
+ props: {
166
+ value: { paths, bundles },
167
+ mode,
168
+ touched: {}
169
+ },
170
+ });
171
+
172
+ const { rows } = wrapper.vm;
173
+
174
+ expect(rows).toStrictEqual([]);
175
+ });
176
+
177
+ it('should build 1 path from bundles with empty options', async() => {
178
+ const paths: string[] = [];
179
+ const bundles: Subpath[] = [{ base: 'aaa', options: '' }];
180
+
181
+ const wrapper = mount(FleetGitRepoPaths, {
182
+ props: {
183
+ value: { paths, bundles },
184
+ mode,
185
+ touched: {}
186
+ },
187
+ });
188
+
189
+ const { rows } = wrapper.vm;
190
+
191
+ expect(rows).toStrictEqual([{
192
+ isBundles: true,
193
+ path: 'aaa',
194
+ subpaths: []
195
+ }]);
196
+ });
197
+
198
+ it('should build 1 row from bundles', async() => {
199
+ const paths: string[] = [];
200
+ const bundles: Subpath[] = [{ base: 'dev', options: 'dev.yaml' }];
201
+
202
+ const wrapper = mount(FleetGitRepoPaths, {
203
+ props: {
204
+ value: { paths, bundles },
205
+ mode,
206
+ touched: {}
207
+ },
208
+ });
209
+
210
+ const { rows } = wrapper.vm;
211
+
212
+ expect(rows).toStrictEqual([{
213
+ isBundles: true,
214
+ path: 'dev',
215
+ subpaths: [{
216
+ base: '',
217
+ options: 'dev.yaml'
218
+ }]
219
+ }]);
220
+ });
221
+
222
+ it('should build rows from mixed paths and bundles', async() => {
223
+ const paths: string[] = ['folderC', 'folderA/subfolderB', 'folderA'];
224
+ const bundles: Subpath[] = [{
225
+ base: 'folderA',
226
+ options: 'dev.yaml'
227
+ }, {
228
+ base: 'vvv',
229
+ options: 'vvv.yaml'
230
+ }];
231
+
232
+ const wrapper = mount(FleetGitRepoPaths, {
233
+ props: {
234
+ value: { paths, bundles },
235
+ mode,
236
+ touched: {}
237
+ },
238
+ });
239
+
240
+ const { rows } = wrapper.vm;
241
+
242
+ expect(rows).toStrictEqual([
243
+ {
244
+ path: 'vvv',
245
+ subpaths: [{
246
+ base: '',
247
+ options: 'vvv.yaml'
248
+ }],
249
+ isBundles: true
250
+ },
251
+ {
252
+ path: 'folderA',
253
+ subpaths: [{
254
+ base: '',
255
+ options: 'dev.yaml'
256
+ }],
257
+ isBundles: true
258
+ },
259
+ { path: 'folderC' },
260
+ { path: 'folderA/subfolderB' },
261
+ { path: 'folderA' }
262
+ ]);
263
+ });
264
+ });
265
+ });
@@ -79,11 +79,11 @@ describe('component: FleetOCIStorageSecret', () => {
79
79
  const wrapper = mount(FleetOCIStorageSecret, {
80
80
  props: {
81
81
  workspace: 'fleet-local',
82
- secret: null,
82
+ secret: '',
83
83
  mode,
84
84
  },
85
85
  data() {
86
- return { secrets: [], workspaces };
86
+ return { secrets: [], workspaces } as any;
87
87
  },
88
88
  });
89
89
 
@@ -95,11 +95,11 @@ describe('component: FleetOCIStorageSecret', () => {
95
95
  const wrapper = mount(FleetOCIStorageSecret, {
96
96
  props: {
97
97
  workspace: 'fleet-local',
98
- secret: null,
98
+ secret: '',
99
99
  mode,
100
100
  },
101
101
  data() {
102
- return { secrets, workspaces };
102
+ return { secrets, workspaces } as any;
103
103
  },
104
104
  });
105
105
 
@@ -114,11 +114,11 @@ describe('component: FleetOCIStorageSecret', () => {
114
114
  const wrapper = mount(FleetOCIStorageSecret, {
115
115
  props: {
116
116
  workspace: 'fleet-default',
117
- secret: null,
117
+ secret: '',
118
118
  mode,
119
119
  },
120
120
  data() {
121
- return { secrets, workspaces };
121
+ return { secrets, workspaces } as any;
122
122
  },
123
123
  });
124
124
 
@@ -134,11 +134,11 @@ describe('component: FleetOCIStorageSecret', () => {
134
134
  const wrapper = mount(FleetOCIStorageSecret, {
135
135
  props: {
136
136
  workspace: 'fleet-custom-workspace',
137
- secret: null,
137
+ secret: '',
138
138
  mode,
139
139
  },
140
140
  data() {
141
- return { secrets, workspaces };
141
+ return { secrets, workspaces } as any;
142
142
  },
143
143
  });
144
144
 
@@ -156,11 +156,11 @@ describe('component: FleetOCIStorageSecret', () => {
156
156
  const wrapper = mount(FleetOCIStorageSecret, {
157
157
  props: {
158
158
  workspace: '',
159
- secret: null,
159
+ secret: '',
160
160
  mode,
161
161
  },
162
162
  data() {
163
- return { secrets, workspaces };
163
+ return { secrets, workspaces } as any;
164
164
  },
165
165
  });
166
166
 
@@ -174,11 +174,11 @@ describe('component: FleetOCIStorageSecret', () => {
174
174
  const wrapper = mount(FleetOCIStorageSecret, {
175
175
  props: {
176
176
  workspace: '',
177
- secret: null,
177
+ secret: '',
178
178
  mode,
179
179
  },
180
180
  data() {
181
- return { secrets, workspaces };
181
+ return { secrets, workspaces } as any;
182
182
  },
183
183
  });
184
184
 
@@ -200,7 +200,7 @@ describe('component: FleetOCIStorageSecret', () => {
200
200
  mode,
201
201
  },
202
202
  data() {
203
- return { secrets, workspaces };
203
+ return { secrets, workspaces } as any;
204
204
  },
205
205
  });
206
206
 
@@ -0,0 +1,300 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import flushPromises from 'flush-promises';
3
+ import { _CREATE, _EDIT } from '@shell/config/query-params';
4
+ import FleetValuesFrom from '@shell/components/fleet/FleetValuesFrom.vue';
5
+
6
+ const requiredSetup = () => {
7
+ return { global: { mocks: { $store: { getters: { namespaces: () => ['fleet-default', 'fleet-local'] } } } } };
8
+ };
9
+
10
+ const allConfigMaps = [
11
+ {
12
+ id: 'fleet-local/configmap-1',
13
+ name: 'configmap-1',
14
+ metadata: {
15
+ namespace: 'fleet-local',
16
+ name: 'configmap-1'
17
+ },
18
+ data: { foo0: 'bar0' }
19
+ },
20
+ {
21
+ id: 'fleet-default/configmap-2',
22
+ name: 'configmap-2',
23
+ metadata: {
24
+ namespace: 'fleet-default',
25
+ name: 'configmap-2'
26
+ },
27
+ data: { foo1: 'bar1' }
28
+ }
29
+ ];
30
+
31
+ const allSecrets = [
32
+ {
33
+ id: 'fleet-local/secret-1',
34
+ name: 'secret-1',
35
+ metadata: {
36
+ namespace: 'fleet-local',
37
+ name: 'secret-1'
38
+ },
39
+ data: { foo2: 'bar2' }
40
+ },
41
+ {
42
+ id: 'fleet-default/secret-2',
43
+ name: 'secret-2',
44
+ metadata: {
45
+ namespace: 'fleet-default',
46
+ name: 'secret-2'
47
+ },
48
+ data: { foo3: 'bar3' }
49
+ }
50
+ ];
51
+
52
+ describe('component: FleetValuesFrom', () => {
53
+ describe.each([
54
+ _CREATE,
55
+ _EDIT
56
+ ])('mode: %p', (mode) => {
57
+ it('should show loading label when secrets or configMaps are empty', async() => {
58
+ const wrapper = mount(FleetValuesFrom, {
59
+ ...requiredSetup(),
60
+ props: {
61
+ value: [],
62
+ namespace: 'fleet-default',
63
+ mode,
64
+ },
65
+ });
66
+
67
+ await flushPromises();
68
+
69
+ const loading = wrapper.find('[data-testid="fleet-values-from-loading"]');
70
+ const itemsContainer = wrapper.find('[data-testid="fleet-values-from-list"]');
71
+
72
+ expect(itemsContainer.exists()).toBe(false);
73
+ expect(loading.exists()).toBe(true);
74
+ });
75
+
76
+ it('should decode spec.helm.valuesFrom to build UI form', async() => {
77
+ const wrapper = mount(FleetValuesFrom, {
78
+ ...requiredSetup(),
79
+ props: {
80
+ value: [
81
+ {
82
+ configMapKeyRef: {
83
+ key: 'foo0',
84
+ name: 'configmap-2',
85
+ namespace: 'fleet-default'
86
+ }
87
+ },
88
+ {
89
+ secretKeyRef: {
90
+ key: 'foo3',
91
+ name: 'secret-2',
92
+ namespace: 'fleet-default'
93
+ }
94
+ }
95
+ ],
96
+ namespace: 'fleet-default',
97
+ mode,
98
+ },
99
+ data: () => ({
100
+ allSecrets,
101
+ allConfigMaps
102
+ })
103
+ });
104
+
105
+ await flushPromises();
106
+
107
+ const configMapRef = wrapper.find('[data-testid="fleet-values-from-item-0"]').element;
108
+ const secretRef = wrapper.find('[data-testid="fleet-values-from-item-1"]').element;
109
+
110
+ expect(configMapRef.textContent).toContain('configMapKeyRef'); // Type column
111
+ expect(configMapRef.textContent).toContain('configmap-2'); // ConfigMap column
112
+ expect(configMapRef.textContent).toContain('foo0'); // Key column
113
+
114
+ expect(secretRef.textContent).toContain('secretKeyRef'); // Type column
115
+ expect(secretRef.textContent).toContain('secret-2'); // Secret column
116
+ expect(secretRef.textContent).toContain('foo3'); // Key column
117
+ });
118
+
119
+ it.each([
120
+ 'fleet-default',
121
+ 'fleet-local'
122
+ ])('should encode UI rows to spec.helm.valuesFrom having namespace %p', async(namespace) => {
123
+ const wrapper = mount(FleetValuesFrom, {
124
+ ...requiredSetup(),
125
+ props: {
126
+ value: [],
127
+ namespace,
128
+ mode,
129
+ },
130
+ });
131
+
132
+ wrapper.setData({
133
+ valuesFrom: [
134
+ {
135
+ id: 0,
136
+ valueFrom: {
137
+ configMapKeyRef: {
138
+ key: 'foo0',
139
+ name: 'configmap-2'
140
+ }
141
+ }
142
+ },
143
+ {
144
+ id: 1,
145
+ valueFrom: {
146
+ secretKeyRef: {
147
+ key: 'foo2',
148
+ name: 'secret-2'
149
+ }
150
+ }
151
+ }
152
+ ]
153
+ });
154
+
155
+ wrapper.vm.update();
156
+
157
+ await flushPromises();
158
+
159
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
160
+ configMapKeyRef: {
161
+ key: 'foo0', name: 'configmap-2', namespace,
162
+ }
163
+ }, {
164
+ secretKeyRef: {
165
+ key: 'foo2', name: 'secret-2', namespace,
166
+ }
167
+ }]);
168
+ });
169
+
170
+ it('should reset ConfigMap/Secret and Key columns on Type change', async() => {
171
+ const wrapper = mount(FleetValuesFrom, {
172
+ ...requiredSetup(),
173
+ props: {
174
+ value: [
175
+ {
176
+ configMapKeyRef: {
177
+ key: 'foo0',
178
+ name: 'configmap-2',
179
+ namespace: 'fleet-default'
180
+ }
181
+ },
182
+ {
183
+ secretKeyRef: {
184
+ key: 'foo3',
185
+ name: 'secret-2',
186
+ namespace: 'fleet-default'
187
+ }
188
+ }
189
+ ],
190
+ namespace: 'fleet-default',
191
+ mode,
192
+ },
193
+ data: () => ({
194
+ allSecrets,
195
+ allConfigMaps
196
+ })
197
+ });
198
+
199
+ await flushPromises();
200
+
201
+ // Change Type from ConfigMap Key to Secret Key
202
+ wrapper.vm.updateValueFrom(0, {
203
+ name: 'configmap-2',
204
+ valueFrom: {
205
+ secretKeyRef: {
206
+ key: 'foo0',
207
+ name: 'configmap-2',
208
+ optional: false
209
+ }
210
+ }
211
+ } as any);
212
+
213
+ await flushPromises();
214
+
215
+ const exConfigMapRef = wrapper.find('[data-testid="fleet-values-from-item-0"]').element;
216
+
217
+ // Type column is changed to Secret
218
+ expect(exConfigMapRef.textContent).toContain('secretKeyRef'); // Type column
219
+
220
+ // Config Map and Key fields are deleted from row 1
221
+ expect(exConfigMapRef.textContent).not.toContain('configmap-2'); // ConfigMap column
222
+ expect(exConfigMapRef.textContent).not.toContain('foo0'); // Key column
223
+
224
+ // excluding row 1 from emit
225
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
226
+ secretKeyRef: {
227
+ key: 'foo3', name: 'secret-2', namespace: 'fleet-default'
228
+ }
229
+ }]);
230
+ });
231
+
232
+ it('should reset Key column on Ref change', async() => {
233
+ const wrapper = mount(FleetValuesFrom, {
234
+ ...requiredSetup(),
235
+ props: {
236
+ value: [
237
+ {
238
+ configMapKeyRef: {
239
+ key: 'foo0',
240
+ name: 'configmap-2',
241
+ namespace: 'fleet-default'
242
+ }
243
+ },
244
+ {
245
+ secretKeyRef: {
246
+ key: 'foo3',
247
+ name: 'secret-2',
248
+ namespace: 'fleet-default'
249
+ }
250
+ }
251
+ ],
252
+ namespace: 'fleet-default',
253
+ mode,
254
+ },
255
+ data: () => ({
256
+ allSecrets,
257
+ allConfigMaps
258
+ })
259
+ });
260
+
261
+ await flushPromises();
262
+
263
+ // Change Config Map ref
264
+ wrapper.vm.updateValueFrom(0, {
265
+ name: 'configmap-3',
266
+ valueFrom: {
267
+ configMapKeyRef: {
268
+ key: 'foo4',
269
+ name: 'configmap-3',
270
+ optional: false
271
+ }
272
+ }
273
+ } as any);
274
+
275
+ await flushPromises();
276
+
277
+ const configMapRef = wrapper.find('[data-testid="fleet-values-from-item-0"]').element;
278
+
279
+ // Type column is not changed
280
+ expect(configMapRef.textContent).toContain('configMapKeyRef'); // Type column
281
+
282
+ // Config Map column is now configmap-3
283
+ expect(configMapRef.textContent).toContain('configmap-3'); // ConfigMap column
284
+
285
+ // Key column is empty
286
+ expect(configMapRef.textContent).toContain('workload.container.command.fromResource.key.label%Loading'); // Key column
287
+
288
+ // Emit empty Key
289
+ expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
290
+ configMapKeyRef: {
291
+ key: '', name: 'configmap-3', namespace: 'fleet-default'
292
+ }
293
+ }, {
294
+ secretKeyRef: {
295
+ key: 'foo3', name: 'secret-2', namespace: 'fleet-default'
296
+ }
297
+ }]);
298
+ });
299
+ });
300
+ });
@@ -170,6 +170,7 @@ export default {
170
170
  <style lang="scss" scoped>
171
171
  .dashboard-resource-card {
172
172
  margin: 1px;
173
+ height: 100%;
173
174
  }
174
175
 
175
176
  .icon-lg {
@@ -89,7 +89,7 @@ export default {
89
89
  >
90
90
  <span
91
91
  v-clean-tooltip="value.stateDescription"
92
- class="label wrap-text fixed-height"
92
+ class="label wrap-text"
93
93
  :class="{ 'text-error' : value.stateObj.error }"
94
94
  >
95
95
  {{ value.stateDescription }}
@@ -192,8 +192,4 @@ export default {
192
192
  -webkit-line-clamp: 5;
193
193
  -webkit-box-orient: vertical;
194
194
  }
195
-
196
- .fixed-height {
197
- height: 80px;
198
- }
199
195
  </style>