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

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 (315) hide show
  1. package/assets/styles/global/_button.scss +1 -1
  2. package/assets/styles/global/_layout.scss +4 -0
  3. package/assets/translations/en-us.yaml +183 -51
  4. package/assets/translations/zh-hans.yaml +1 -7
  5. package/chart/monitoring/ClusterSelector.vue +0 -21
  6. package/chart/monitoring/prometheus/index.vue +6 -3
  7. package/components/ActionDropdownShell.vue +5 -3
  8. package/components/ButtonGroup.vue +26 -1
  9. package/components/CruResource.vue +212 -16
  10. package/components/ExplorerMembers.vue +8 -4
  11. package/components/ExplorerProjectsNamespaces.vue +10 -6
  12. package/components/GrowlManager.vue +4 -0
  13. package/components/MgmtNodeList.vue +184 -0
  14. package/components/PromptRestore.vue +93 -32
  15. package/components/Questions/index.vue +1 -0
  16. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  17. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  18. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  19. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  20. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
  21. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  22. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  23. package/components/ResourceDetail/index.vue +1 -1
  24. package/components/ResourceList/Masthead.vue +7 -1
  25. package/components/ResourceList/index.vue +82 -1
  26. package/components/ResourceTable.vue +1 -0
  27. package/components/RichTranslation.vue +5 -2
  28. package/components/Setting.vue +1 -0
  29. package/components/SortableTable/index.vue +4 -3
  30. package/components/SubtleLink.vue +31 -6
  31. package/components/Tabbed/Tab.vue +29 -3
  32. package/components/Tabbed/index.vue +25 -3
  33. package/components/TableOfContents/TableOfContents.vue +109 -0
  34. package/components/TableOfContents/composables.ts +258 -0
  35. package/components/Window/ContainerShell.vue +21 -11
  36. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  37. package/components/Wizard.vue +23 -5
  38. package/components/__tests__/ButtonGroup.test.ts +56 -0
  39. package/components/__tests__/PromptRestore.test.ts +169 -19
  40. package/components/fleet/AppCoChartGrid.vue +401 -0
  41. package/components/fleet/AppCoEmptyState.vue +127 -0
  42. package/components/fleet/AppCoPageHeader.vue +119 -0
  43. package/components/fleet/AppCoVersionSelect.vue +70 -0
  44. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  45. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  46. package/components/fleet/FleetClusterTargets/index.vue +189 -146
  47. package/components/fleet/FleetIntro.vue +7 -3
  48. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  49. package/components/fleet/FleetSecretSelector.vue +5 -3
  50. package/components/fleet/FleetValuesFrom.vue +8 -2
  51. package/components/fleet/GitRepoAdvancedTab.vue +1 -0
  52. package/components/fleet/GitRepoMetadataTab.vue +5 -0
  53. package/components/fleet/GitRepoTargetTab.vue +0 -2
  54. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  55. package/components/fleet/HelmOpAppCoConfigTab.vue +597 -0
  56. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  57. package/components/fleet/HelmOpMetadataTab.vue +5 -0
  58. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  59. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  60. package/components/fleet/HelmOpTargetTab.vue +64 -60
  61. package/components/fleet/HelmOpValuesTab.vue +129 -105
  62. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  63. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  64. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  65. package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
  66. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  67. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  68. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  69. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  70. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  71. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  72. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  73. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  74. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  75. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  76. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  77. package/components/fleet/dashboard/Empty.vue +8 -4
  78. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  79. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  80. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  81. package/components/form/ArrayList.vue +61 -4
  82. package/components/form/FileSelector.vue +39 -1
  83. package/components/form/KeyValue.vue +23 -2
  84. package/components/form/LabeledSelect.vue +39 -1
  85. package/components/form/Labels.vue +22 -3
  86. package/components/form/NameNsDescription.vue +13 -5
  87. package/components/form/PrivateRegistry.constants.ts +7 -0
  88. package/components/form/PrivateRegistry.vue +253 -18
  89. package/components/form/ResourceTabs/index.vue +1 -0
  90. package/components/form/SelectOrCreateAuthSecret.vue +140 -17
  91. package/components/form/__tests__/FileSelector.test.ts +23 -0
  92. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  93. package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
  94. package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
  95. package/components/formatter/EtcdSnapshotName.vue +73 -0
  96. package/components/formatter/InternalExternalIP.vue +10 -4
  97. package/components/formatter/ServiceTargets.vue +26 -7
  98. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  99. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  100. package/components/nav/Header.vue +12 -1
  101. package/components/nav/TopLevelMenu.vue +7 -2
  102. package/components/nav/__tests__/Header.test.ts +15 -0
  103. package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
  104. package/components/templates/default.vue +16 -4
  105. package/components/templates/home.vue +9 -4
  106. package/components/templates/plain.vue +9 -4
  107. package/composables/useHelmOpResources.test.ts +56 -0
  108. package/composables/useHelmOpResources.ts +32 -0
  109. package/composables/useStateColor.test.ts +325 -0
  110. package/composables/useStateColor.ts +128 -0
  111. package/config/features.js +1 -0
  112. package/config/home-links.js +1 -1
  113. package/config/labels-annotations.js +3 -0
  114. package/config/product/explorer.js +17 -4
  115. package/config/product/manager.js +8 -0
  116. package/config/router/index.js +16 -0
  117. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  118. package/config/router/navigation-guards/authentication.js +10 -4
  119. package/config/router/routes.js +20 -6
  120. package/config/secret.ts +10 -0
  121. package/config/settings.ts +6 -4
  122. package/config/table-headers.js +3 -4
  123. package/config/types.js +16 -0
  124. package/core/plugin-products-base.ts +3 -3
  125. package/core/plugin-types.ts +83 -30
  126. package/core/plugin.ts +3 -0
  127. package/core/types-provisioning.ts +34 -1
  128. package/core/types.ts +15 -2
  129. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  130. package/detail/__tests__/workload.test.ts +3 -152
  131. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  132. package/detail/provisioning.cattle.io.cluster.vue +109 -7
  133. package/detail/workload/index.vue +12 -55
  134. package/dialog/RotateEncryptionKeyDialog.vue +33 -9
  135. package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
  136. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  137. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
  138. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +206 -0
  139. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  140. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  141. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  142. package/edit/auth/__tests__/azuread.test.ts +34 -9
  143. package/edit/auth/__tests__/github.test.ts +234 -0
  144. package/edit/auth/__tests__/oidc.test.ts +26 -6
  145. package/edit/auth/__tests__/saml.test.ts +196 -0
  146. package/edit/auth/azuread.vue +128 -95
  147. package/edit/auth/github.vue +72 -13
  148. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  149. package/edit/auth/ldap/config.vue +8 -0
  150. package/edit/auth/ldap/index.vue +75 -1
  151. package/edit/auth/oidc.vue +119 -73
  152. package/edit/auth/saml.vue +76 -12
  153. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  154. package/edit/compliance.cattle.io.clusterscanprofile.vue +39 -41
  155. package/edit/fleet.cattle.io.gitrepo.vue +70 -16
  156. package/edit/fleet.cattle.io.helmop.vue +542 -141
  157. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  158. package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
  159. package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
  160. package/edit/management.cattle.io.user.vue +5 -2
  161. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
  162. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
  163. package/edit/provisioning.cattle.io.cluster/rke2.vue +89 -11
  164. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  165. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
  166. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
  167. package/list/group.principal.vue +5 -4
  168. package/list/harvesterhci.io.management.cluster.vue +8 -9
  169. package/list/management.cattle.io.user.vue +12 -9
  170. package/list/provisioning.cattle.io.cluster.vue +16 -10
  171. package/mixins/__tests__/auth-config.test.ts +90 -0
  172. package/mixins/__tests__/chart.test.ts +94 -0
  173. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  174. package/mixins/auth-config.js +7 -0
  175. package/mixins/chart.js +11 -2
  176. package/mixins/child-hook.js +12 -6
  177. package/mixins/create-edit-view/impl.js +5 -3
  178. package/mixins/resource-fetch-api-pagination.js +21 -1
  179. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  180. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  181. package/models/__tests__/fleet-application.test.ts +175 -0
  182. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  183. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  184. package/models/__tests__/management.cattle.io.node.ts +22 -0
  185. package/models/__tests__/namespace.test.ts +36 -0
  186. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +205 -0
  187. package/models/__tests__/secret.test.ts +68 -1
  188. package/models/__tests__/workload.test.ts +401 -26
  189. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  190. package/models/compliance.cattle.io.clusterscan.js +39 -4
  191. package/models/fleet-application.js +4 -0
  192. package/models/fleet.cattle.io.helmop.js +20 -1
  193. package/models/management.cattle.io.cluster.js +39 -5
  194. package/models/management.cattle.io.node.js +44 -3
  195. package/models/namespace.js +1 -1
  196. package/models/pod.js +46 -3
  197. package/models/provisioning.cattle.io.cluster.js +64 -14
  198. package/models/rke.cattle.io.etcdsnapshot.js +17 -9
  199. package/models/secret.js +19 -0
  200. package/models/workload.js +120 -20
  201. package/models/workload.service.js +5 -0
  202. package/package.json +14 -13
  203. package/pages/about.vue +5 -6
  204. package/pages/auth/login.vue +0 -35
  205. package/pages/auth/setup.vue +11 -0
  206. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  207. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  208. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  209. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +485 -107
  210. package/pages/c/_cluster/apps/charts/chart.vue +2 -1
  211. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  212. package/pages/c/_cluster/apps/charts/install.vue +236 -144
  213. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  214. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  215. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  216. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  217. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  218. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  219. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  220. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  221. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  222. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  223. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  224. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  225. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  226. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  227. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  228. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  229. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  230. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  231. package/pages/c/_cluster/fleet/index.vue +2 -2
  232. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
  233. package/pages/c/_cluster/uiplugins/index.vue +15 -0
  234. package/pages/fail-whale.vue +16 -11
  235. package/pages/home.vue +16 -46
  236. package/pkg/require-asset.lib.js +25 -0
  237. package/pkg/vue.config.js +7 -0
  238. package/plugins/clean-html.d.ts +9 -0
  239. package/plugins/dashboard-store/__tests__/resource-class.test.ts +177 -0
  240. package/plugins/dashboard-store/getters.js +0 -1
  241. package/plugins/dashboard-store/resource-class.js +114 -19
  242. package/plugins/steve/__tests__/actions.test.ts +212 -0
  243. package/plugins/steve/actions.js +96 -0
  244. package/plugins/steve/steve-pagination-utils.ts +1 -1
  245. package/rancher-components/Accordion/Accordion.vue +53 -9
  246. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  247. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  248. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  249. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
  250. package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
  251. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  252. package/rancher-components/RcButton/RcButton.test.ts +103 -0
  253. package/rancher-components/RcButton/RcButton.vue +94 -15
  254. package/rancher-components/RcButton/index.ts +1 -1
  255. package/rancher-components/RcButton/types.ts +3 -0
  256. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
  257. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  258. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  259. package/rancher-components/RcSection/RcSection.vue +28 -3
  260. package/scripts/extension/helm/package/Dockerfile +1 -1
  261. package/scripts/test-plugins-build.sh +2 -1
  262. package/store/__tests__/features.test.ts +131 -0
  263. package/store/__tests__/growl.test.ts +374 -0
  264. package/store/__tests__/modal.test.ts +131 -0
  265. package/store/__tests__/notifications.test.ts +434 -0
  266. package/store/__tests__/slideInPanel.test.ts +88 -0
  267. package/store/__tests__/type-map.utils.test.ts +433 -0
  268. package/store/catalog.js +57 -0
  269. package/store/features.js +4 -0
  270. package/store/plugins.js +7 -4
  271. package/types/components/buttonGroup.ts +5 -0
  272. package/types/shell/index.d.ts +166 -70
  273. package/utils/__tests__/auth.test.ts +273 -0
  274. package/utils/__tests__/computed.test.ts +193 -0
  275. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  276. package/utils/__tests__/dom.test.ts +81 -0
  277. package/utils/__tests__/duration.test.ts +37 -1
  278. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  279. package/utils/__tests__/fleet-appco.test.ts +312 -0
  280. package/utils/__tests__/monitoring.test.ts +130 -0
  281. package/utils/__tests__/object.test.ts +22 -0
  282. package/utils/__tests__/operation-cr.test.ts +34 -0
  283. package/utils/__tests__/platform.test.ts +91 -0
  284. package/utils/__tests__/position.test.ts +237 -0
  285. package/utils/__tests__/provider.test.ts +51 -1
  286. package/utils/__tests__/queue.test.ts +232 -0
  287. package/utils/__tests__/release-notes.test.ts +221 -0
  288. package/utils/__tests__/router.test.js +254 -1
  289. package/utils/__tests__/select.test.ts +208 -0
  290. package/utils/__tests__/time.test.ts +265 -1
  291. package/utils/__tests__/title.test.ts +47 -0
  292. package/utils/__tests__/width.test.ts +53 -0
  293. package/utils/__tests__/window.test.ts +158 -0
  294. package/utils/__tests__/xccdf.test.ts +126 -6
  295. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  296. package/utils/crypto/__tests__/index.test.ts +144 -0
  297. package/utils/duration.ts +104 -0
  298. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  299. package/utils/dynamic-content/info.ts +2 -1
  300. package/utils/error.js +13 -0
  301. package/utils/fleet-appco.ts +323 -0
  302. package/utils/object.js +22 -2
  303. package/utils/operation-cr.js +19 -0
  304. package/utils/provider.ts +12 -0
  305. package/utils/require-asset.ts +7 -0
  306. package/utils/validators/__tests__/container-images.test.ts +104 -0
  307. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  308. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  309. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  310. package/utils/validators/__tests__/private-registry.test.ts +27 -15
  311. package/utils/validators/private-registry.ts +15 -4
  312. package/utils/xccdf.ts +39 -42
  313. package/vue.config.js +1 -1
  314. package/pages/support/index.vue +0 -264
  315. package/utils/duration.js +0 -43
@@ -12,6 +12,7 @@ import { RadioGroup } from '@components/Form/Radio';
12
12
  import { set } from '@shell/utils/object';
13
13
  import { simplify, convert } from '@shell/utils/selector';
14
14
  import { POD } from '@shell/config/types';
15
+ import { RcButton } from '@components/RcButton';
15
16
 
16
17
  export default {
17
18
  components: {
@@ -22,6 +23,7 @@ export default {
22
23
  MatchExpressions,
23
24
  RadioGroup,
24
25
  StorageClassSelector,
26
+ RcButton,
25
27
  },
26
28
 
27
29
  props: {
@@ -190,12 +192,13 @@ export default {
190
192
  :key="i"
191
193
  class="mt-10"
192
194
  >
193
- <router-link
195
+ <rc-button
196
+ size="large"
197
+ variant="tertiary"
194
198
  :to="wl.link"
195
- class="btn role-tertiary"
196
199
  >
197
200
  {{ wl.label }}
198
- </router-link>
201
+ </rc-button>
199
202
  </div>
200
203
  </template>
201
204
  </Banner>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { RcDropdown, RcDropdownTrigger, RcDropdownItem } from '@components/RcDropdown';
3
+ import { ButtonSize } from '@components/RcButton';
3
4
  type HiddenAction = {
4
5
  action: string;
5
6
  enabled: boolean;
@@ -11,11 +12,12 @@ type HiddenAction = {
11
12
  anyEnabled: boolean;
12
13
  }
13
14
 
14
- defineProps<{
15
+ withDefaults(defineProps<{
15
16
  disabled: boolean,
16
17
  hiddenActions: HiddenAction[],
17
18
  actionTooltip: unknown,
18
- }>();
19
+ size?: ButtonSize,
20
+ }>(), { size: 'large' });
19
21
 
20
22
  const emit = defineEmits(['click', 'mouseover', 'mouseleave']);
21
23
 
@@ -35,7 +37,7 @@ const setBulkActionOfInterest = (act: HiddenAction | null, event: 'mouseover' |
35
37
  >
36
38
  <rc-dropdown-trigger
37
39
  class="bulk-actions-dropdown"
38
- size="large"
40
+ :size="size"
39
41
  :disabled="disabled"
40
42
  >
41
43
  <template #before>
@@ -31,11 +31,25 @@ export default {
31
31
  disabled: {
32
32
  type: Boolean,
33
33
  default: false,
34
- }
34
+ },
35
+
36
+ size: {
37
+ type: String,
38
+ default: 'large',
39
+ validator: (value) => ['small', 'medium', 'large'].includes(value),
40
+ },
35
41
 
36
42
  },
37
43
 
38
44
  computed: {
45
+ sizeClass() {
46
+ return {
47
+ small: 'btn-sm',
48
+ medium: 'btn-md',
49
+ large: null,
50
+ }[this.size];
51
+ },
52
+
39
53
  optionObjects() {
40
54
  const value = this.value;
41
55
 
@@ -52,6 +66,7 @@ export default {
52
66
 
53
67
  out.class = {
54
68
  btn: true,
69
+ [this.sizeClass]: !!this.sizeClass,
55
70
  [this.inactiveClass]: !active,
56
71
  [this.activeClass]: active,
57
72
  };
@@ -122,3 +137,13 @@ export default {
122
137
  </button>
123
138
  </div>
124
139
  </template>
140
+
141
+ <style lang="scss" scoped>
142
+ .btn-group {
143
+ .btn-md {
144
+ padding: 0 12px;
145
+ min-height: 32px;
146
+ line-height: 32px;
147
+ }
148
+ }
149
+ </style>
@@ -1,5 +1,6 @@
1
1
  <script>
2
2
  import isEmpty from 'lodash/isEmpty';
3
+ import throttle from 'lodash/throttle';
3
4
  import { createYamlWithOptions } from '@shell/utils/create-yaml';
4
5
  import { clone, get } from '@shell/utils/object';
5
6
  import { SCHEMA, NAMESPACE } from '@shell/config/types';
@@ -11,6 +12,10 @@ import { stringify, exceptionToErrorsArray } from '@shell/utils/error';
11
12
  import CruResourceFooter from '@shell/components/CruResourceFooter';
12
13
  import { useResourceCreatePageProvider, useResourceEditPageProvider } from '@shell/composables/cruResource';
13
14
 
15
+ import { useFormSummary } from '@shell/components/TableOfContents/composables';
16
+ import { useTemplateRef } from 'vue';
17
+ import TableOfContents from '@shell/components/TableOfContents/TableOfContents.vue';
18
+
14
19
  import {
15
20
  _EDIT, _VIEW, AS, _YAML, _UNFLAG, SUB_TYPE, _CREATE
16
21
  } from '@shell/config/query-params';
@@ -31,7 +36,8 @@ export default {
31
36
  Banner,
32
37
  CruResourceFooter,
33
38
  ResourceYaml,
34
- Wizard
39
+ Wizard,
40
+ TableOfContents
35
41
  },
36
42
 
37
43
  props: {
@@ -121,6 +127,12 @@ export default {
121
127
  default: () => []
122
128
  },
123
129
 
130
+ // Used to be called before going to the next step in the wizard.
131
+ beforeNext: {
132
+ type: Function,
133
+ default: null
134
+ },
135
+
124
136
  stepsOptions: {
125
137
  type: Object,
126
138
  default: () => ({ editFirstStep: true })
@@ -162,9 +174,22 @@ export default {
162
174
  yamlModifiers: {
163
175
  type: Object,
164
176
  default: undefined
177
+ },
178
+
179
+ showToc: {
180
+ type: Boolean,
181
+ default: false
165
182
  }
166
183
  },
167
184
 
185
+ setup() {
186
+ const cruFormRef = useTemplateRef('cru-form');
187
+ const { locatedComponents } = useFormSummary(cruFormRef);
188
+ const accordions = locatedComponents;
189
+
190
+ return { accordions };
191
+ },
192
+
168
193
  data(props) {
169
194
  const inStore = this.$store.getters['currentStore'](this.resource);
170
195
  const schema = this.$store.getters[`${ inStore }/schemaFor`](this.resource.type);
@@ -176,27 +201,31 @@ export default {
176
201
  }
177
202
 
178
203
  return {
179
- isCancelModal: false,
180
- showAsForm: this.$route.query[AS] !== _YAML,
204
+ isCancelModal: false,
205
+ showAsForm: this.$route.query[AS] !== _YAML,
206
+ tocContainerHeight: 0,
207
+ mainLayoutEl: null,
208
+ throttledComputeTocContainerHeight: null,
209
+ nextValidating: false,
181
210
  /**
182
211
  * Initialised on demand (given that it needs to make a request to fetch schema definition)
183
212
  */
184
- resourceYaml: null,
213
+ resourceYaml: null,
185
214
  /**
186
215
  * Initialised on demand (given that it needs to make a request to fetch schema definition)
187
216
  */
188
- initialYaml: null,
217
+ initialYaml: null,
189
218
  /**
190
219
  * Save a copy of the initial resource. This is used to calc the initial yaml later on
191
220
  */
192
- initialResource: clone(this.resource),
193
- abbrSizes: {
221
+ initialResource: clone(this.resource),
222
+ abbrSizes: {
194
223
  3: '24px',
195
224
  4: '18px',
196
225
  5: '16px',
197
226
  6: '14px'
198
227
  },
199
- schema
228
+ schema,
200
229
  };
201
230
  },
202
231
 
@@ -276,10 +305,11 @@ export default {
276
305
  icon: null
277
306
  }
278
307
  }), {});
279
- },
308
+ }
280
309
  },
281
310
 
282
311
  created() {
312
+ this.throttledComputeTocContainerHeight = throttle(this.computeTocContainerHeight, 20);
283
313
  if ( this._selectedSubtype ) {
284
314
  this.$emit('select-type', this._selectedSubtype);
285
315
  }
@@ -290,12 +320,42 @@ export default {
290
320
  },
291
321
 
292
322
  beforeUnmount() {
323
+ this.mainLayoutEl?.removeEventListener('scroll', this.throttledComputeTocContainerHeight);
324
+ window.removeEventListener('resize', this.throttledComputeTocContainerHeight);
325
+ this.throttledComputeTocContainerHeight?.cancel?.();
293
326
  this.$store.dispatch('cru-resource/setCreateNamespace', false);
294
327
  },
295
328
 
296
329
  methods: {
297
330
  stringify,
298
331
 
332
+ // as the user scrolls past the CruResource Masthead, the amount of vertical space available to the table of contents changes
333
+ computeTocContainerHeight() {
334
+ const root = this.$el;
335
+
336
+ if (!root) {
337
+ this.tocContainerHeight = 0;
338
+
339
+ return 0;
340
+ }
341
+
342
+ const tocEl = root.querySelector('.cru__toc');
343
+ const footerEl = root.querySelector('.cru__footer');
344
+
345
+ if (!tocEl || !footerEl) {
346
+ this.tocContainerHeight = 0;
347
+
348
+ return 0;
349
+ }
350
+
351
+ const tocTop = tocEl.getBoundingClientRect().top;
352
+ const footerTop = footerEl.getBoundingClientRect().top;
353
+ const gapLgValue = getComputedStyle(root).getPropertyValue('--gap-lg').trim();
354
+ const gapLg = Number.parseFloat(gapLgValue) || 0;
355
+
356
+ this.tocContainerHeight = Math.max(0, Math.round((footerTop - tocTop) - gapLg));
357
+ },
358
+
299
359
  confirmCancel(isCancelNotBack = true) {
300
360
  if (isCancelNotBack) {
301
361
  this.emitOrRoute();
@@ -435,6 +495,47 @@ export default {
435
495
  return slot !== 'default' && typeof this.$slots[slot] === 'function';
436
496
  },
437
497
 
498
+ async wizardBeforeGoToStep(fromStep, toStep) {
499
+ if (!this.beforeNext) {
500
+ return;
501
+ }
502
+
503
+ const fromIdx = this.steps.findIndex((s) => s.name === fromStep.name);
504
+ const toIdx = this.steps.findIndex((s) => s.name === toStep.name);
505
+
506
+ if (toIdx <= fromIdx) {
507
+ return;
508
+ }
509
+
510
+ try {
511
+ await this.beforeNext(fromStep);
512
+ this.$emit('error', []);
513
+ } catch (err) {
514
+ this.$emit('error', exceptionToErrorsArray(err));
515
+ throw err;
516
+ }
517
+ },
518
+
519
+ async handleNext(nextFn, activeStep) {
520
+ if (!this.beforeNext) {
521
+ nextFn();
522
+
523
+ return;
524
+ }
525
+
526
+ this.nextValidating = true;
527
+
528
+ try {
529
+ await this.beforeNext(activeStep);
530
+ this.$emit('error', []);
531
+ nextFn();
532
+ } catch (err) {
533
+ this.$emit('error', exceptionToErrorsArray(err));
534
+ } finally {
535
+ this.nextValidating = false;
536
+ }
537
+ },
538
+
438
539
  formatError(err) {
439
540
  if ( typeof err === 'string') {
440
541
  return err;
@@ -532,13 +633,38 @@ export default {
532
633
  this.initialYaml = await this.createResourceYaml(undefined, this.initialResource);
533
634
  }
534
635
  }
636
+ },
637
+
638
+ showToc: {
639
+ handler(neu, old) {
640
+ if (neu) {
641
+ // Compute height on first render
642
+ this.$nextTick(() => {
643
+ this.throttledComputeTocContainerHeight?.();
644
+ });
645
+ // Add event listeners for computeTocContainerHeight on scroll
646
+ this.mainLayoutEl = document.querySelector('.main-layout');
647
+ this.mainLayoutEl?.addEventListener('scroll', this.throttledComputeTocContainerHeight, { passive: true });
648
+ // Add event listener for computeTocContainerHeight on window resize
649
+ window.addEventListener('resize', this.throttledComputeTocContainerHeight, { passive: true });
650
+ } else if (old) {
651
+ // Remove event listeners for computeTocContainerHeight when TOC is hidden
652
+ this.mainLayoutEl?.removeEventListener('scroll', this.throttledComputeTocContainerHeight);
653
+ window.removeEventListener('resize', this.throttledComputeTocContainerHeight);
654
+ }
655
+ },
656
+ immediate: true
535
657
  }
536
658
  }
537
659
  };
538
660
  </script>
539
661
 
540
662
  <template>
541
- <section class="cru">
663
+ <section
664
+ ref="cru-form"
665
+ :class="{'show-toc':showToc}"
666
+ class="cru"
667
+ >
542
668
  <slot name="noticeBanner" />
543
669
  <p
544
670
  v-if="description"
@@ -548,6 +674,7 @@ export default {
548
674
  </p>
549
675
  <component
550
676
  :is="(isView? 'div' : 'form')"
677
+
551
678
  :value="resource"
552
679
  data-testid="cru-form"
553
680
  class="create-resource-container cru__form"
@@ -672,6 +799,7 @@ export default {
672
799
  :edit-first-step="stepsOptions.editFirstStep"
673
800
  :errors="errors"
674
801
  :finish-mode="finishMode"
802
+ :before-go-to-step="wizardBeforeGoToStep"
675
803
  class="wizard"
676
804
  @error="e=>errors = e"
677
805
  >
@@ -755,10 +883,10 @@ export default {
755
883
  name="next"
756
884
  >
757
885
  <button
758
- :disabled="!canNext"
886
+ :disabled="!canNext || nextValidating"
759
887
  type="button"
760
888
  class="btn role-primary"
761
- @click="next()"
889
+ @click="handleNext(next, activeStep)"
762
890
  >
763
891
  <t k="wizard.next" />
764
892
  </button>
@@ -771,15 +899,23 @@ export default {
771
899
  </template>
772
900
  <!------ SINGLE PROCESS ------>
773
901
  <template v-else-if="showAsForm">
902
+ <TableOfContents
903
+ v-if="showToc"
904
+ class="cru__toc"
905
+ :style="tocContainerHeight ? { '--toc-container-height': `${tocContainerHeight}px` } : {}"
906
+ :accordions="accordions"
907
+ />
774
908
  <div
775
909
  v-if="_selectedSubtype || !subtypes.length"
776
- class="resource-container cru__content"
910
+ class="cru__content resource-container"
911
+
777
912
  :style="[minHeight ? { 'min-height': minHeight } : {}]"
778
913
  >
779
914
  <slot name="single">
780
915
  <slot />
781
916
  </slot>
782
917
  </div>
918
+
783
919
  <slot name="form-footer">
784
920
  <CruResourceFooter
785
921
  v-if="!isView"
@@ -912,6 +1048,11 @@ export default {
912
1048
  </template>
913
1049
 
914
1050
  <style lang='scss' scoped>
1051
+ $logo: 60px;
1052
+ $logo-space: 100px;
1053
+
1054
+ $table-contents-width: 250px;
1055
+
915
1056
  .cru-resource-yaml-container {
916
1057
  .resource-yaml {
917
1058
  .yaml-editor {
@@ -937,9 +1078,6 @@ export default {
937
1078
  }
938
1079
  }
939
1080
 
940
- $logo: 60px;
941
- $logo-space: 100px;
942
-
943
1081
  .title {
944
1082
  margin-top: 20px;
945
1083
 
@@ -992,10 +1130,26 @@ form.create-resource-container .cru {
992
1130
  display: flex;
993
1131
  flex-direction: column;
994
1132
  flex-grow: 1;
1133
+
1134
+ }
1135
+
1136
+ &__toc {
1137
+ width: $table-contents-width;
1138
+ margin: 20px var(--gap-lg) 20px var(--gap-lg);
1139
+ min-width: $table-contents-width;
1140
+ max-width: $table-contents-width;
1141
+ position: sticky;
1142
+ top: 24px;
1143
+ align-self: flex-start;
1144
+ max-height: var(--toc-container-height, calc(100vh - 24px - $footer-height - calc( 2 * var(--gap-lg)) - 125px));
1145
+ transition: max-height 50ms ease-in-out;
1146
+ overflow-y: auto;
1147
+ overflow-x: hidden;
995
1148
  }
996
1149
 
997
1150
  &__content {
998
1151
  flex-grow: 1;
1152
+
999
1153
  &-wizard {
1000
1154
  display: flex;
1001
1155
  }
@@ -1025,6 +1179,48 @@ form.create-resource-container .cru {
1025
1179
  }
1026
1180
  }
1027
1181
 
1182
+ .show-toc.cru{
1183
+ &>.cru__form{
1184
+ display: grid;
1185
+ grid-template-columns: [content] 1fr [toc] calc(#{$table-contents-width} + var(--gap-lg));
1186
+ grid-template-rows: [errors] auto [content] 1fr [footer] min-content;
1187
+
1188
+ &>.cru__errors {
1189
+ grid-column: content;
1190
+ grid-row: errors;
1191
+ }
1192
+
1193
+ &>.cru__toc {
1194
+ grid-column: toc;
1195
+ grid-row: errors / footer;
1196
+ }
1197
+
1198
+ &>.cru__content {
1199
+ grid-column: content;
1200
+ grid-row: content;
1201
+ }
1202
+
1203
+ &>.cru__footer {
1204
+ grid-column: content / 3;
1205
+ grid-row: footer;
1206
+ }
1207
+ }
1208
+ }
1209
+
1210
+ @media (max-width: map-get($breakpoints, '--viewport-9')) {
1211
+ .show-toc.cru {
1212
+ & > .cru__form {
1213
+ display: flex;
1214
+ grid-template-columns: none;
1215
+ grid-template-rows: none;
1216
+
1217
+ & > .cru__toc {
1218
+ display: none;
1219
+ }
1220
+ }
1221
+ }
1222
+ }
1223
+
1028
1224
  .description {
1029
1225
  margin-bottom: 15px;
1030
1226
  margin-top: 5px;
@@ -12,6 +12,7 @@ import { mapGetters } from 'vuex';
12
12
  import { canViewProjectMembershipEditor } from '@shell/components/form/Members/ProjectMembershipEditor.vue';
13
13
  import { allHash } from '@shell/utils/promise';
14
14
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
15
+ import { RcButton } from '@components/RcButton';
15
16
 
16
17
  /**
17
18
  * Explorer members page.
@@ -26,7 +27,8 @@ export default {
26
27
  ResourceTable,
27
28
  Tabbed,
28
29
  Tab,
29
- SortableTable
30
+ SortableTable,
31
+ RcButton,
30
32
  },
31
33
 
32
34
  props: {
@@ -308,12 +310,14 @@ export default {
308
310
  v-if="canEditClusterMembers"
309
311
  class="row mb-10 cluster-add"
310
312
  >
311
- <router-link
313
+ <rc-button
314
+ size="large"
315
+ class="pull-right"
316
+ data-testid="button-cluster-member-add"
312
317
  :to="createLocation"
313
- class="btn role-primary pull-right"
314
318
  >
315
319
  {{ t('members.createActionLabel') }}
316
- </router-link>
320
+ </rc-button>
317
321
  </div>
318
322
  <ResourceTable
319
323
  :schema="schema"
@@ -20,6 +20,7 @@ import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
20
20
  import perfSettingsUtils from '@shell/utils/perf-setting.utils';
21
21
  import ActionMenu from '@shell/components/ActionMenuShell.vue';
22
22
  import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
23
+ import { RcButton } from '@components/RcButton';
23
24
 
24
25
  export default {
25
26
  name: 'ListProjectNamespace',
@@ -29,6 +30,7 @@ export default {
29
30
  ResourceTable,
30
31
  ButtonMultiAction,
31
32
  ActionMenu,
33
+ RcButton
32
34
  },
33
35
  mixins: [ResourceFetch],
34
36
 
@@ -445,13 +447,14 @@ export default {
445
447
  v-if="showCreateNsButton"
446
448
  #extraActions
447
449
  >
448
- <router-link
450
+ <rc-button
451
+ size="large"
452
+ class="mr-10"
449
453
  :to="createNamespaceLocationFlatList()"
450
- class="btn role-primary mr-10"
451
454
  data-testid="create_project_namespaces"
452
455
  >
453
456
  {{ t('projectNamespaces.createNamespace') }}
454
- </router-link>
457
+ </rc-button>
455
458
  </template>
456
459
  </Masthead>
457
460
  <!-- Extensions area -->
@@ -495,13 +498,14 @@ export default {
495
498
  </div>
496
499
  </div>
497
500
  <div class="right mr-10">
498
- <router-link
501
+ <rc-button
499
502
  v-if="isNamespaceCreatable && (canSeeProjectlessNamespaces || group.group.key !== notInProjectKey)"
500
- class="create-namespace btn btn-sm role-secondary mr-5"
503
+ variant="secondary"
504
+ class="mr-5"
501
505
  :to="createNamespaceLocation(group.group)"
502
506
  >
503
507
  {{ t('projectNamespaces.createNamespace') }}
504
- </router-link>
508
+ </rc-button>
505
509
  <template v-if="featureDropdownMenu">
506
510
  <ActionMenu
507
511
  v-if="showProjectActionButton(group.group)"
@@ -204,6 +204,10 @@ export default {
204
204
  > P {
205
205
  padding-top: 2px;
206
206
 
207
+ // Limit size of message and scroll just the message, not the entire growl, so that the title and icon are always visible
208
+ max-height: 200px;
209
+ overflow-y: scroll;
210
+
207
211
  &.has-title {
208
212
  margin-top: 5px;
209
213
  }