dashboard-shell-shell 3.0.5-test.9 → 3.0.5-tsh-rh01

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 (212) hide show
  1. package/assets/brand/csp/favicon.png +0 -0
  2. package/assets/icons/iconfont.css +4 -1
  3. package/assets/iconsNew/demo.css +539 -0
  4. package/assets/iconsNew/demo.css:Zone.Identifier +0 -0
  5. package/assets/iconsNew/demo_index.html +303 -0
  6. package/assets/iconsNew/demo_index.html:Zone.Identifier +0 -0
  7. package/assets/iconsNew/iconfont.css +43 -0
  8. package/assets/iconsNew/iconfont.css:Zone.Identifier +0 -0
  9. package/assets/iconsNew/iconfont.js +1 -0
  10. package/assets/iconsNew/iconfont.js:Zone.Identifier +0 -0
  11. package/assets/iconsNew/iconfont.json +44 -0
  12. package/assets/iconsNew/iconfont.json:Zone.Identifier +0 -0
  13. package/assets/iconsNew/iconfont.ttf +0 -0
  14. package/assets/iconsNew/iconfont.ttf:Zone.Identifier +0 -0
  15. package/assets/iconsNew/iconfont.woff +0 -0
  16. package/assets/iconsNew/iconfont.woff2 +0 -0
  17. package/assets/iconsNew/iconfont.woff2:Zone.Identifier +0 -0
  18. package/assets/iconsNew/iconfont.woff:Zone.Identifier +0 -0
  19. package/assets/images/login-logo.svg +9 -19
  20. package/assets/images/login-logo1.svg +9 -0
  21. package/assets/images/pl/dark/logo.png +0 -0
  22. package/assets/images/pl/logo.svg +11 -0
  23. package/assets/styles/all.scss +23 -3
  24. package/assets/styles/app.scss +1 -0
  25. package/assets/styles/base/_helpers.scss +1 -1
  26. package/assets/styles/base/_variables.scss +2 -2
  27. package/assets/styles/fonts/_icons.scss +3 -2
  28. package/assets/styles/global/_button.scss +1 -1
  29. package/assets/styles/global/_form.scss +1 -0
  30. package/assets/styles/global/_select.scss +1 -1
  31. package/assets/styles/global/_tooltip.scss +5 -1
  32. package/assets/styles/themes/_light.scss +3 -3
  33. package/assets/styles/vendor/vue-select.scss +2 -1
  34. package/assets/translations/en-us.yaml +67 -0
  35. package/assets/translations/zh-hans.yaml +226 -24
  36. package/components/ButtonDropdown.vue +3 -1
  37. package/components/ClusterIconMenu.vue +1 -1
  38. package/components/CodeMirror.vue +6 -4
  39. package/components/ConsumptionGauge.vue +1 -1
  40. package/components/ContainerResourceLimit.vue +2 -2
  41. package/components/CruResource.vue +3 -2
  42. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +22 -19
  43. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -3
  44. package/components/ExplorerMembers.vue +10 -1
  45. package/components/GlobalRoleBindings.vue +69 -114
  46. package/components/PodSecurityAdmission.vue +1 -1
  47. package/components/PromptRemove.vue +23 -1
  48. package/components/RelatedResources.vue +3 -0
  49. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  50. package/components/Resource/Detail/TitleBar/index.vue +37 -24
  51. package/components/ResourceDetail/Masthead/index.vue +1 -1
  52. package/components/ResourceDetail/Masthead/latest.vue +1 -1
  53. package/components/ResourceDetail/Masthead/legacy.vue +8 -7
  54. package/components/ResourceDetail/legacy.vue +15 -15
  55. package/components/ResourceList/Masthead.vue +16 -15
  56. package/components/ResourceTable.vue +16 -0
  57. package/components/SideNav.vue +21 -21
  58. package/components/SingleClusterInfo.vue +2 -1
  59. package/components/SortableTable/THead.vue +46 -1
  60. package/components/SortableTable/index.vue +54 -18
  61. package/components/Tabbed/index.vue +6 -1
  62. package/components/actionButton/index.vue +649 -0
  63. package/components/auth/Principal.vue +16 -8
  64. package/components/auth/RoleDetailEdit.vue +11 -7
  65. package/components/breadcrumb/index.vue +13 -210
  66. package/components/form/ArrayList.vue +164 -147
  67. package/components/form/ArrayListGrouped.vue +5 -3
  68. package/components/form/ChangePassword.vue +1 -1
  69. package/components/form/ClusterAppearance.vue +4 -3
  70. package/components/form/Command.vue +4 -5
  71. package/components/form/Conditions.vue +15 -1
  72. package/components/form/Footer.vue +1 -0
  73. package/components/form/HealthCheck.vue +0 -2
  74. package/components/form/HookOption.vue +87 -58
  75. package/components/form/InputWithSelect.vue +8 -7
  76. package/components/form/KeyValue.vue +20 -2
  77. package/components/form/LabeledSelect.vue +3 -1
  78. package/components/form/Labels.vue +2 -2
  79. package/components/form/MatchExpressions.vue +4 -4
  80. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  81. package/components/form/Members/ClusterPermissionsEditor.vue +60 -41
  82. package/components/form/Members/MembershipEditor.vue +4 -4
  83. package/components/form/Members/ProjectMembershipEditor.vue +1 -1
  84. package/components/form/NameNsDescription.vue +3 -2
  85. package/components/form/Networking.vue +6 -9
  86. package/components/form/NodeAffinity.vue +29 -28
  87. package/components/form/PodAffinity.vue +23 -23
  88. package/components/form/Probe.vue +15 -11
  89. package/components/form/ProjectMemberEditor.vue +66 -48
  90. package/components/form/ResourceQuota/Namespace.vue +4 -4
  91. package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
  92. package/components/form/ResourceQuota/Project.vue +4 -4
  93. package/components/form/ResourceQuota/ProjectRow.vue +36 -30
  94. package/components/form/ResourceSelector.vue +1 -1
  95. package/components/form/SecretSelector.vue +24 -23
  96. package/components/form/Security.vue +1 -3
  97. package/components/form/Select.vue +7 -1
  98. package/components/form/ServiceNameSelect.vue +2 -5
  99. package/components/form/ServicePorts.vue +149 -75
  100. package/components/form/Tolerations.vue +13 -9
  101. package/components/form/ValueFromResource.vue +110 -96
  102. package/components/formatter/WorkloadHealthScale.vue +4 -3
  103. package/components/nav/Group.vue +8 -1
  104. package/components/nav/Header.vue +51 -174
  105. package/components/nav/NamespaceFilter.vue +14 -19
  106. package/components/nav/TopLevelMenu.vue +101 -134
  107. package/components/nav/Type.vue +11 -3
  108. package/config/menuRouteMap.js +10 -0
  109. package/config/product/explorer.js +32 -10
  110. package/config/product/manager.js +28 -17
  111. package/config/product/uiplugins.js +13 -10
  112. package/config/router/navigation-guards/index.js +61 -3
  113. package/detail/node.vue +28 -23
  114. package/dialog/AddCustomBadgeDialog.vue +17 -9
  115. package/dialog/RollbackWorkloadDialog.vue +1 -1
  116. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  117. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  118. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  119. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  120. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  121. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  122. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  123. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  124. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  125. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  126. package/edit/configmap.vue +4 -0
  127. package/edit/logging-flow/index.vue +1 -2
  128. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +3 -3
  129. package/edit/logging.banzaicloud.io.output/providers/azurestorage.vue +19 -19
  130. package/edit/logging.banzaicloud.io.output/providers/cloudwatch.vue +23 -23
  131. package/edit/logging.banzaicloud.io.output/providers/datadog.vue +19 -19
  132. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +14 -14
  133. package/edit/logging.banzaicloud.io.output/providers/forward.vue +12 -12
  134. package/edit/logging.banzaicloud.io.output/providers/gcs.vue +23 -23
  135. package/edit/logging.banzaicloud.io.output/providers/gelf.vue +6 -6
  136. package/edit/logging.banzaicloud.io.output/providers/kafka.vue +10 -10
  137. package/edit/logging.banzaicloud.io.output/providers/kinesisStream.vue +8 -8
  138. package/edit/logging.banzaicloud.io.output/providers/logdna.vue +17 -17
  139. package/edit/logging.banzaicloud.io.output/providers/logz.vue +7 -7
  140. package/edit/logging.banzaicloud.io.output/providers/loki.vue +12 -12
  141. package/edit/logging.banzaicloud.io.output/providers/newrelic.vue +3 -3
  142. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +14 -14
  143. package/edit/logging.banzaicloud.io.output/providers/redis.vue +6 -6
  144. package/edit/logging.banzaicloud.io.output/providers/s3.vue +23 -23
  145. package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +13 -13
  146. package/edit/logging.banzaicloud.io.output/providers/sumologic.vue +2 -2
  147. package/edit/logging.banzaicloud.io.output/providers/syslog.vue +54 -54
  148. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +32 -8
  149. package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +32 -0
  150. package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +52 -0
  151. package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +45 -0
  152. package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +31 -0
  153. package/edit/networking.k8s.io.ingress/Certificate.vue +14 -5
  154. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  155. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  156. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  157. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  158. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  159. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  160. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  161. package/edit/persistentvolume/index.vue +3 -1
  162. package/edit/persistentvolumeclaim.vue +2 -0
  163. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -1
  164. package/edit/secret/index.vue +2 -2
  165. package/edit/service.vue +4 -1
  166. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  167. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  168. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  169. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  170. package/edit/workload/Job.vue +31 -34
  171. package/edit/workload/Upgrading.vue +5 -5
  172. package/edit/workload/index.vue +19 -15
  173. package/edit/workload/storage/Mount.vue +1 -0
  174. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  175. package/edit/workload/storage/azureDisk.vue +14 -10
  176. package/edit/workload/storage/azureFile.vue +9 -7
  177. package/edit/workload/storage/csi/index.vue +6 -9
  178. package/edit/workload/storage/emptyDir.vue +7 -5
  179. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  180. package/edit/workload/storage/hostPath.vue +7 -5
  181. package/edit/workload/storage/nfs.vue +8 -6
  182. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  183. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  184. package/edit/workload/storage/secret.vue +9 -6
  185. package/edit/workload/storage/vsphereVolume.vue +11 -7
  186. package/initialize/app-extended.js +7 -1
  187. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +8 -6
  188. package/mixins/create-edit-view/impl.js +10 -0
  189. package/models/provisioning.cattle.io.cluster.js +19 -18
  190. package/models/workload.js +2 -2
  191. package/package.json +1 -1
  192. package/pages/account/index.vue +93 -58
  193. package/pages/auth/setup.vue +36 -17
  194. package/pages/c/_cluster/auth/roles/index.vue +27 -3
  195. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  196. package/pages/c/_cluster/explorer/index.vue +2 -1
  197. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  198. package/pages/home.vue +55 -13
  199. package/plugins/dashboard-store/actions.js +1 -1
  200. package/rancher-components/Banner/Banner.vue +14 -2
  201. package/rancher-components/Form/Radio/RadioGroup.vue +9 -1
  202. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
  203. package/scripts/build-pkg.sh +18 -23
  204. package/scripts/publish-shell.sh +1 -1
  205. package/store/i18n.js +1 -0
  206. package/store/index.js +4 -4
  207. package/store/type-map.js +0 -2
  208. package/types/shell/index.d.ts +8 -0
  209. package/utils/error.js +23 -3
  210. package/utils/errorTranslate.json +402 -8
  211. package/utils/errorTranslateNew.json +39 -0
  212. package/utils/roleFiltering.js +33 -0
@@ -52,10 +52,7 @@ export default {
52
52
  helper.update(args);
53
53
  }
54
54
 
55
- const topLevelPermissions = sessionStorage.getItem('TOPLEVELPERMISSIONS') || ''
56
-
57
55
  return {
58
- topLevelPermissions,
59
56
  shown: false,
60
57
  displayVersion,
61
58
  fullVersion,
@@ -492,10 +489,8 @@ export default {
492
489
  role="navigation"
493
490
  :aria-label="t('nav.ariaLabel.topLevelMenu')"
494
491
  >
495
-
496
492
  <!-- ====================== 菜单头部(Logo + 菜单按钮) ====================== -->
497
493
  <div class="title">
498
-
499
494
  <!-- 菜单按钮(汉堡图标) -->
500
495
  <div
501
496
  data-testid="top-level-menu"
@@ -507,7 +502,6 @@ export default {
507
502
  @keyup.space="toggle()"
508
503
  @click="toggle()"
509
504
  >
510
-
511
505
  <!-- 汉堡菜单SVG图标 -->
512
506
  <svg
513
507
  class="menu-icon"
@@ -523,19 +517,18 @@ export default {
523
517
  </div>
524
518
 
525
519
  <!-- 品牌Logo -->
526
- <div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'" class="side-menu-logo">
520
+ <div class="side-menu-logo">
527
521
  <BrandImage
528
522
  data-testid="side-menu__brand-img"
529
523
  :alt="t('nav.alt.mainMenuRancherLogo')"
530
- file-name="logo.png"
524
+ file-name="logo.svg"
531
525
  />
532
526
  </div>
533
527
  </div>
534
528
 
535
529
  <!-- ====================== 菜单内容区 ====================== -->
536
530
  <div class="body">
537
- <div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
538
-
531
+ <div>
539
532
  <!-- 首页按钮 -->
540
533
  <div @click="hide()">
541
534
  <router-link
@@ -544,7 +537,6 @@ export default {
544
537
  role="link"
545
538
  :aria-label="t('nav.ariaLabel.homePage')"
546
539
  >
547
-
548
540
  <!-- 首页图标 -->
549
541
  <svg
550
542
  v-clean-tooltip="getTooltipConfig(t('nav.home'))"
@@ -562,7 +554,7 @@ export default {
562
554
  </div>
563
555
  </router-link>
564
556
  </div>
565
-
557
+
566
558
  <!-- 集群搜索框 -->
567
559
  <div
568
560
  v-if="showClusterSearch"
@@ -650,7 +642,7 @@ export default {
650
642
  </template>
651
643
 
652
644
  <!-- ====================== 集群列表 ====================== -->
653
- <template v-if="topLevelPermissions && topLevelPermissions === 'superadmin' && !!allClustersCount">
645
+ <template v-if="!!allClustersCount">
654
646
  <div
655
647
  ref="clusterList"
656
648
  class="clusters"
@@ -667,7 +659,6 @@ export default {
667
659
  :data-testid="`pinned-ready-cluster-${index}`"
668
660
  @click="hide()"
669
661
  >
670
-
671
662
  <!-- 可用集群按钮 -->
672
663
  <span
673
664
  v-if="c.ready"
@@ -752,7 +743,6 @@ export default {
752
743
  :data-testid="`top-level-menu-cluster-${index}`"
753
744
  @click="hide()"
754
745
  >
755
-
756
746
  <!-- 可用集群 -->
757
747
  <span
758
748
  v-if="c.ready"
@@ -833,7 +823,7 @@ export default {
833
823
  </div>
834
824
  </div>
835
825
 
836
- <!-- 查看所有集群按钮 -->
826
+ <!-- See all clusters -->
837
827
  <router-link
838
828
  v-if="allClustersCount > maxClustersToShow"
839
829
  class="clusters-all"
@@ -853,129 +843,106 @@ export default {
853
843
  </template>
854
844
 
855
845
  <!-- ====================== 多集群应用区 ====================== -->
856
- <div :style="!(topLevelPermissions && topLevelPermissions === 'superadmin') ? { placeContent: 'flex-start', display: 'flex', flexDirection: 'column' } : {}" class="category">
846
+ <div class="category">
857
847
  <!-- 多集群应用 -->
858
848
  <template v-if="multiClusterApps.length">
859
- <template v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
860
- <div
861
- class="category-title"
849
+ <div
850
+ class="category-title"
851
+ >
852
+ <hr role="none">
853
+ <span>
854
+ {{ t('nav.categories.multiCluster') }}
855
+ </span>
856
+ </div>
857
+ <div
858
+ v-for="(a, i) in appBar.multiClusterApps"
859
+ :key="i"
860
+ @click="hide()"
861
+ >
862
+ <router-link
863
+ v-if="a.value !== 'fleet'"
864
+ class="option"
865
+ :class="{'active-menu-link': a.isMenuActive }"
866
+ :to="a.to"
867
+ role="link"
868
+ :aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
862
869
  >
863
- <hr role="none">
864
- <span>
865
- {{ t('nav.categories.multiCluster') }}
866
- </span>
867
- </div>
868
- <template v-for="(a, i) in appBar.multiClusterApps" :key="i">
869
- <div
870
- v-if="a.value === 'harvesterManager'"
871
- @click="hide()"
872
- >
873
- <router-link
874
- class="option"
875
- :class="{'active-menu-link': a.isMenuActive }"
876
- :to="a.to"
877
- role="link"
878
- :aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
879
- >
880
- <IconOrSvg
881
- v-clean-tooltip="getTooltipConfig(a.label)"
882
- class="app-icon"
883
- :icon="a.icon"
884
- :src="a.svg"
885
- />
886
- <span class="option-link">{{ a.label }}</span>
887
- </router-link>
888
- </div>
889
- </template>
890
- </template>
891
- <template v-else>
892
- <template v-for="(a, i) in appBar.multiClusterApps" :key="i">
893
- <div
894
- v-if="a.value === 'harvesterManager'"
895
- @click="hide()"
896
- >
897
- <router-link
898
- class="option"
899
- :class="{'active-menu-link': a.isMenuActive }"
900
- :to="a.to"
901
- role="link"
902
- :aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
903
- >
904
- <IconOrSvg
905
- v-clean-tooltip="getTooltipConfig(a.label)"
906
- class="app-icon"
907
- :icon="a.icon"
908
- :src="a.svg"
909
- />
910
- <span class="option-link">{{ a.label }}</span>
911
- </router-link>
912
- </div>
913
- </template>
914
- </template>
870
+ <IconOrSvg
871
+ v-clean-tooltip="getTooltipConfig(a.label)"
872
+ class="app-icon"
873
+ :icon="a.icon"
874
+ :src="a.svg"
875
+ />
876
+ <span class="option-link">{{ a.label }}</span>
877
+ </router-link>
878
+ </div>
915
879
  </template>
916
880
 
917
- <!-- 配置类应用 -->
918
- <div>
919
- <template v-if="configurationApps.length">
920
- <template v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
921
- <div
922
- class="category-title"
923
- >
924
- <hr role="none">
925
- <span>
926
- {{ t('nav.categories.configuration') }}
927
- </span>
928
- </div>
929
- <div
930
- v-for="(a, i) in appBar.configurationApps"
931
- :key="i"
932
- @click="hide()"
933
- >
934
- <router-link
935
- class="option"
936
- :class="{'active-menu-link': a.isMenuActive }"
937
- :to="a.to"
938
- role="link"
939
- :aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
940
- >
941
- <IconOrSvg
942
- v-clean-tooltip="getTooltipConfig(a.label)"
943
- class="app-icon"
944
- :icon="a.icon"
945
- :src="a.svg"
946
- />
947
- <div>{{ a.label }}</div>
948
- </router-link>
949
- </div>
950
- </template>
951
- <template v-else>
952
- <template v-for="(a, i) in appBar.configurationApps" :key="i">
953
- <div
954
- v-if="a.value === 'settings' || a.value === 'auth'"
955
- @click="hide()"
956
- >
957
- <router-link
958
- class="option"
959
- :class="{'active-menu-link': a.isMenuActive }"
960
- :to="a.to"
961
- role="link"
962
- :aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
963
- >
964
- <IconOrSvg
965
- v-clean-tooltip="getTooltipConfig(a.label)"
966
- class="app-icon"
967
- :icon="a.icon"
968
- :src="a.svg"
969
- />
970
- <div>{{ a.label }}</div>
971
- </router-link>
972
- </div>
973
- </template>
974
- </template>
975
- <div style="height: 40px;"></div>
976
- </template>
977
- </div>
881
+ <!-- Configuration apps menu -->
882
+ <template v-if="configurationApps.length">
883
+ <div
884
+ class="category-title"
885
+ >
886
+ <hr role="none">
887
+ <span>
888
+ {{ t('nav.categories.configuration') }}
889
+ </span>
890
+ </div>
891
+ <div
892
+ v-for="(a, i) in appBar.configurationApps"
893
+ :key="i"
894
+ @click="hide()"
895
+ >
896
+ <router-link
897
+ class="option"
898
+ :class="{'active-menu-link': a.isMenuActive }"
899
+ :to="a.to"
900
+ role="link"
901
+ :aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
902
+ >
903
+ <IconOrSvg
904
+ v-clean-tooltip="getTooltipConfig(a.label)"
905
+ class="app-icon"
906
+ :icon="a.icon"
907
+ :src="a.svg"
908
+ />
909
+ <div>{{ a.label }}</div>
910
+ </router-link>
911
+ </div>
912
+ </template>
913
+ </div>
914
+ </div>
915
+
916
+ <!-- Footer -->
917
+ <div
918
+ class="footer"
919
+ >
920
+ <!-- <div
921
+ v-if="canEditSettings"
922
+ class="support"
923
+ @click="hide()"
924
+ >
925
+ <router-link
926
+ :to="{name: 'support'}"
927
+ role="link"
928
+ :aria-label="t('nav.ariaLabel.support')"
929
+ >
930
+ {{ t('nav.support', {hasSupport}) }}
931
+ </router-link>
978
932
  </div>
933
+ <div
934
+ class="version"
935
+ :class="{'version-small': largeAboutText}"
936
+ @click="hide()"
937
+ >
938
+ <router-link
939
+ :to="{ name: 'about' }"
940
+ role="link"
941
+ :aria-label="t('nav.ariaLabel.about')"
942
+ >
943
+ {{ aboutText }}
944
+ </router-link>
945
+ </div> -->
979
946
  </div>
980
947
  </div>
981
948
  </transition>
@@ -1644,7 +1611,7 @@ export default {
1644
1611
  }
1645
1612
 
1646
1613
  :deep() .v-popper__arrow-container {
1647
- display: none;
1614
+ display: none !important;
1648
1615
  }
1649
1616
 
1650
1617
  :deep() .v-popper:focus {
@@ -3,6 +3,7 @@ import Favorite from '@shell/components/nav/Favorite';
3
3
  import { TYPE_MODES } from '@shell/store/type-map';
4
4
 
5
5
  import TabTitle from '@shell/components/TabTitle';
6
+ import { menuRouteMap } from '@shell/config/menuRouteMap';
6
7
 
7
8
  const showFavoritesFor = [TYPE_MODES.FAVORITE, TYPE_MODES.USED];
8
9
 
@@ -61,6 +62,13 @@ export default {
61
62
  const pageFullPath = this.$route.fullPath?.toLowerCase().split('#')[0]; // Ignore the shebang when comparing routes
62
63
  const routeMetaNav = this.$route.meta?.nav;
63
64
 
65
+ const resource = this.$route?.params?.resource || ''
66
+
67
+ // 菜单选中动态映射逻辑
68
+ if (menuRouteMap[this.type.name] && menuRouteMap[this.type.name].includes(resource)) {
69
+ return true;
70
+ }
71
+
64
72
  // If the route explicitly declares the nav path that should be highlighted, then use that
65
73
  if (routeMetaNav) {
66
74
  const cluster = this.$route.params?.cluster;
@@ -141,7 +149,7 @@ export default {
141
149
  <a
142
150
  role="link"
143
151
  :aria-label="type.labelKey ? t(type.labelKey) : (type.labelDisplay || type.label)"
144
- :href="href"
152
+ :href="href.replace(/harvester/g, 'cloud')"
145
153
  class="type-link"
146
154
  :aria-current="isActive ? 'page' : undefined"
147
155
  @click="selectType(); navigate($event);"
@@ -158,7 +166,7 @@ export default {
158
166
  <div v-else style="display: flex; align-items: center;" class="labelKey_menu">
159
167
  <i v-if="!type.labelDisplay || (type.labelDisplay && type.labelDisplay.indexOf('</i>') === -1)" class="icon icon-fw icon-globe" style="color: var(--muted);width: 32px;text-align: left;"></i>
160
168
  <span
161
- v-clean-html="type.labelDisplay.replace('设置', '基础设置') || type.label"
169
+ v-clean-html="type.labelDisplay || type.label"
162
170
  class="label"
163
171
  :class="{'no-icon': !type.icon}"
164
172
  />
@@ -199,7 +207,7 @@ export default {
199
207
  >
200
208
  <a
201
209
  role="link"
202
- :href="type.link"
210
+ :href="type.link.replace(/harvester/g, 'cloud')"
203
211
  :target="type.target"
204
212
  rel="noopener noreferrer nofollow"
205
213
  :aria-label="type.label"
@@ -0,0 +1,10 @@
1
+ // menuRouteMap.js
2
+ export const menuRouteMap = {
3
+ 'projects-namespaces': [
4
+ 'management.cattle.io.project', // 创建项目
5
+ 'namespace',
6
+ ],
7
+ 'cluster-members': [
8
+ 'management.cattle.io.clusterroletemplatebinding'
9
+ ]
10
+ };
@@ -67,16 +67,37 @@ export function init(store) {
67
67
  }
68
68
  });
69
69
 
70
+ const topLevelPermissions = sessionStorage.getItem('TOPLEVELPERMISSIONS')
71
+
70
72
  basicType(['cluster-dashboard', 'cluster-tools']);
71
- basicType([
72
- 'cluster-dashboard',
73
- 'projects-namespaces',
74
- 'namespaces',
75
- NODE,
76
- VIRTUAL_TYPES.CLUSTER_MEMBERS,
77
- EVENT,
78
- 'c-cluster-explorer-tools'
79
- ], 'cluster');
73
+
74
+ if (topLevelPermissions && topLevelPermissions === 'superadmin') {
75
+ basicType([
76
+ 'cluster-dashboard',
77
+ 'projects-namespaces',
78
+ 'namespaces',
79
+ 'namespace',
80
+ NODE,
81
+ VIRTUAL_TYPES.CLUSTER_MEMBERS,
82
+ EVENT,
83
+ 'c-cluster-explorer-tools',
84
+ 'management.cattle.io.project',
85
+ 'management.cattle.io.clusterroletemplatebinding'
86
+ ], 'cluster');
87
+ } else {
88
+ basicType([
89
+ 'cluster-dashboard',
90
+ 'projects-namespaces',
91
+ 'namespaces',
92
+ 'namespace',
93
+ NODE,
94
+ VIRTUAL_TYPES.CLUSTER_MEMBERS,
95
+ EVENT,
96
+ 'management.cattle.io.project',
97
+ 'management.cattle.io.clusterroletemplatebinding'
98
+ ], 'cluster');
99
+ }
100
+
80
101
  basicType([
81
102
  LIMIT_RANGE,
82
103
  NETWORK_POLICY,
@@ -95,6 +116,7 @@ export function init(store) {
95
116
  STORAGE_CLASS,
96
117
  SECRET,
97
118
  VIRTUAL_TYPES.PROJECT_SECRETS,
119
+ VIRTUAL_TYPES.NAMESPACES,
98
120
  CONFIG_MAP
99
121
  ], 'storage');
100
122
  basicType([
@@ -633,7 +655,7 @@ export function init(store) {
633
655
  virtualType({
634
656
  label: store.getters['i18n/t'](`typeLabel.${ VIRTUAL_TYPES.PROJECT_SECRETS }`, { count: 2 }),
635
657
  group: 'storage',
636
- icon: 'globe',
658
+ icon: 'default',
637
659
  namespaced: false,
638
660
  ifRancherCluster: true,
639
661
  name: VIRTUAL_TYPES.PROJECT_SECRETS,
@@ -13,6 +13,7 @@ import { DSL } from '@shell/store/type-map';
13
13
  import { BLANK_CLUSTER } from '@shell/store/store-types.js';
14
14
 
15
15
  export const NAME = 'manager';
16
+ const topLevelPermissions = sessionStorage.getItem('TOPLEVELPERMISSIONS')
16
17
 
17
18
  export function init(store) {
18
19
  const {
@@ -60,11 +61,17 @@ export function init(store) {
60
61
  route: { name: 'c-cluster-manager-cloudCredential' },
61
62
  });
62
63
 
63
- basicType([
64
- CAPI.RANCHER_CLUSTER,
65
- 'cloud-credentials',
66
- 'drivers',
67
- ]);
64
+ if (topLevelPermissions && topLevelPermissions === 'superadmin') {
65
+ basicType([
66
+ CAPI.RANCHER_CLUSTER,
67
+ 'cloud-credentials',
68
+ 'drivers',
69
+ ]);
70
+ } else {
71
+ basicType([
72
+ CAPI.RANCHER_CLUSTER,
73
+ ]);
74
+ }
68
75
 
69
76
  configureType(SNAPSHOT, { depaginate: true });
70
77
 
@@ -111,10 +118,12 @@ export function init(store) {
111
118
  exact: true
112
119
  });
113
120
 
114
- basicType([
115
- 'rke-kontainer-drivers',
116
- 'rke-node-drivers',
117
- ], 'drivers');
121
+ if (topLevelPermissions && topLevelPermissions === 'superadmin') {
122
+ basicType([
123
+ 'rke-kontainer-drivers',
124
+ 'rke-node-drivers',
125
+ ], 'drivers');
126
+ }
118
127
 
119
128
  weightType(CAPI.MACHINE_DEPLOYMENT, 4, true);
120
129
  weightType(CAPI.MACHINE_SET, 3, true);
@@ -123,14 +132,16 @@ export function init(store) {
123
132
  weightType(MANAGEMENT.PSA, 5, true);
124
133
  weightType(VIRTUAL_TYPES.JWT_AUTHENTICATION, 0, true);
125
134
 
126
- basicType([
127
- CAPI.MACHINE_DEPLOYMENT,
128
- CAPI.MACHINE_SET,
129
- CAPI.MACHINE,
130
- CATALOG.CLUSTER_REPO,
131
- MANAGEMENT.PSA,
132
- VIRTUAL_TYPES.JWT_AUTHENTICATION
133
- ], 'advanced');
135
+ if (topLevelPermissions && topLevelPermissions === 'superadmin') {
136
+ basicType([
137
+ CAPI.MACHINE_DEPLOYMENT,
138
+ CAPI.MACHINE_SET,
139
+ CAPI.MACHINE,
140
+ CATALOG.CLUSTER_REPO,
141
+ MANAGEMENT.PSA,
142
+ VIRTUAL_TYPES.JWT_AUTHENTICATION
143
+ ], 'advanced');
144
+ }
134
145
 
135
146
  weightGroup('advanced', -1, true);
136
147
 
@@ -5,14 +5,17 @@ export const NAME = 'uiplugins';
5
5
  export function init(store) {
6
6
  const { product } = DSL(store, NAME);
7
7
 
8
- // Add a product for UI Plugins - will appear in the top-level menu
9
- product({
10
- ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
11
- inStore: 'management',
12
- icon: 'extension',
13
- removable: false,
14
- showClusterSwitcher: false,
15
- category: 'configuration',
16
- weight: 50,
17
- });
8
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
9
+ // Add a product for UI Plugins - will appear in the top-level menu
10
+ product({
11
+ ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
12
+ inStore: 'management',
13
+ icon: 'extension',
14
+ removable: false,
15
+ showClusterSwitcher: false,
16
+ category: 'configuration',
17
+ weight: 50,
18
+ });
19
+ }
20
+
18
21
  }
@@ -11,13 +11,71 @@ import { install as installPageTitle } from '@shell/config/router/navigation-gua
11
11
  import { install as installServerUpgradeGrowl } from '@shell/config/router/navigation-guards/server-upgrade-growl';
12
12
 
13
13
  /**
14
- * Install our router navigation guards. i.e. router.beforeEach(), router.afterEach()
14
+ * Install router navigation guards
15
+ * 1. 保留原有导航守卫顺序
16
+ * 2. 不在 beforeEach 改 params,只在 push/replace & afterEach 改 URL
15
17
  */
16
18
  export function installNavigationGuards(router, context) {
17
- // NOTE: the order of the installation matters.
18
- // Be intentional when adding, removing or modifying the guards that are installed.
19
+ // 最早执行:保证进入逻辑时 params 始终是 harvester
20
+ router.beforeEach((to, from, next) => {
21
+ let changed = false;
22
+ const params = { ...to.params };
23
+
24
+ if (params?.product?.includes('cloud')) {
25
+ params.product = params.product.replace(/cloud/g, 'harvester');
26
+ changed = true;
27
+ }
28
+
29
+ if (params?.cluster?.includes('cloud')) {
30
+ params.cluster = params.cluster.replace(/cloud/g, 'harvester');
31
+ changed = true;
32
+ }
33
+
34
+ if (params?.resource?.includes('cloud')) {
35
+ params.resource = params.resource.replace(/cloud/g, 'harvester');
36
+ changed = true;
37
+ }
38
+
39
+ if (changed) {
40
+ // 触发路由重定向
41
+ return next({ ...to, params });
42
+ }
43
+
44
+ next();
45
+ });
46
+
19
47
 
20
48
  const navigationGuardInstallers = [installLoadInitialSettings, installAttemptFirstLogin, installAuthentication, installProducts, installClusters, installRuntimeExtensionRoute, installI18N, installHandleInstallRedirect, installPageTitle, installRecordLastRoute, installServerUpgradeGrowl];
21
49
 
22
50
  navigationGuardInstallers.forEach((installer) => installer(router, context));
51
+
52
+ // 🔹 最后执行:只改地址栏,不改内部
53
+ router.afterEach((to) => {
54
+ const base = router.options.history?.base || '';
55
+ const pathParts = to.path.split('/');
56
+
57
+ const newPathParts = pathParts.map((part) => {
58
+ // 只替换 cluster/product/resource 对应的 segment
59
+ for (const key of ['cluster', 'product', 'resource']) {
60
+ if (to.params[key] && to.params[key] === part) {
61
+ return part.replace(/harvester/g, 'cloud');
62
+ }
63
+ }
64
+ return part;
65
+ });
66
+
67
+ let cloudPath = newPathParts.join('/');
68
+ if (!cloudPath.startsWith(base)) {
69
+ cloudPath = base + cloudPath;
70
+ }
71
+
72
+ const currentLocation = window.location.pathname + window.location.search + window.location.hash;
73
+
74
+ if (cloudPath !== currentLocation) {
75
+ console.info('[URL Replace] Updating address bar:', currentLocation, '→', cloudPath);
76
+ window.history.replaceState({}, '', cloudPath);
77
+ }
78
+ });
79
+
23
80
  }
81
+