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

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 (164) hide show
  1. package/assets/brand/csp/favicon.png +0 -0
  2. package/assets/icons/iconfont.css +4 -1
  3. package/assets/images/pl/dark/logo.png +0 -0
  4. package/assets/styles/all.scss +23 -3
  5. package/assets/styles/base/_variables.scss +2 -2
  6. package/assets/styles/fonts/_icons.scss +3 -2
  7. package/assets/styles/global/_button.scss +1 -1
  8. package/assets/styles/global/_form.scss +1 -0
  9. package/assets/styles/global/_select.scss +1 -1
  10. package/assets/styles/global/_tooltip.scss +5 -1
  11. package/assets/styles/themes/_light.scss +3 -3
  12. package/assets/styles/vendor/vue-select.scss +2 -1
  13. package/assets/translations/en-us.yaml +60 -0
  14. package/assets/translations/zh-hans.yaml +164 -21
  15. package/components/ButtonDropdown.vue +3 -1
  16. package/components/ClusterIconMenu.vue +1 -1
  17. package/components/CodeMirror.vue +6 -4
  18. package/components/ConsumptionGauge.vue +1 -1
  19. package/components/ContainerResourceLimit.vue +2 -2
  20. package/components/CruResource.vue +3 -2
  21. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +22 -19
  22. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -3
  23. package/components/ExplorerMembers.vue +10 -1
  24. package/components/GlobalRoleBindings.vue +52 -112
  25. package/components/PodSecurityAdmission.vue +1 -1
  26. package/components/PromptRemove.vue +23 -1
  27. package/components/RelatedResources.vue +3 -0
  28. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  29. package/components/Resource/Detail/TitleBar/index.vue +37 -24
  30. package/components/ResourceDetail/Masthead/index.vue +1 -1
  31. package/components/ResourceDetail/Masthead/latest.vue +1 -1
  32. package/components/ResourceDetail/Masthead/legacy.vue +8 -7
  33. package/components/ResourceDetail/legacy.vue +15 -15
  34. package/components/ResourceList/Masthead.vue +11 -15
  35. package/components/ResourceTable.vue +16 -0
  36. package/components/SideNav.vue +21 -21
  37. package/components/SingleClusterInfo.vue +2 -1
  38. package/components/SortableTable/THead.vue +46 -1
  39. package/components/SortableTable/index.vue +54 -18
  40. package/components/Tabbed/index.vue +6 -1
  41. package/components/auth/Principal.vue +16 -8
  42. package/components/auth/RoleDetailEdit.vue +11 -7
  43. package/components/breadcrumb/index.vue +13 -210
  44. package/components/form/ArrayList.vue +164 -147
  45. package/components/form/ArrayListGrouped.vue +5 -3
  46. package/components/form/ChangePassword.vue +1 -1
  47. package/components/form/ClusterAppearance.vue +4 -3
  48. package/components/form/Command.vue +4 -5
  49. package/components/form/Conditions.vue +15 -1
  50. package/components/form/Footer.vue +1 -0
  51. package/components/form/HealthCheck.vue +0 -2
  52. package/components/form/HookOption.vue +87 -58
  53. package/components/form/InputWithSelect.vue +8 -7
  54. package/components/form/KeyValue.vue +20 -2
  55. package/components/form/LabeledSelect.vue +3 -1
  56. package/components/form/Labels.vue +2 -2
  57. package/components/form/MatchExpressions.vue +4 -4
  58. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  59. package/components/form/Members/ClusterPermissionsEditor.vue +31 -28
  60. package/components/form/Members/MembershipEditor.vue +3 -3
  61. package/components/form/Members/ProjectMembershipEditor.vue +1 -1
  62. package/components/form/NameNsDescription.vue +4 -2
  63. package/components/form/Networking.vue +6 -9
  64. package/components/form/NodeAffinity.vue +29 -28
  65. package/components/form/PodAffinity.vue +23 -23
  66. package/components/form/Probe.vue +15 -11
  67. package/components/form/ProjectMemberEditor.vue +28 -25
  68. package/components/form/ResourceQuota/Namespace.vue +4 -4
  69. package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
  70. package/components/form/ResourceQuota/Project.vue +4 -4
  71. package/components/form/ResourceQuota/ProjectRow.vue +36 -30
  72. package/components/form/ResourceSelector.vue +1 -1
  73. package/components/form/Security.vue +1 -3
  74. package/components/form/Select.vue +7 -1
  75. package/components/form/ServiceNameSelect.vue +2 -5
  76. package/components/form/ServicePorts.vue +149 -75
  77. package/components/form/Tolerations.vue +13 -9
  78. package/components/form/ValueFromResource.vue +110 -96
  79. package/components/formatter/WorkloadHealthScale.vue +4 -3
  80. package/components/nav/Group.vue +6 -0
  81. package/components/nav/Header.vue +17 -137
  82. package/components/nav/NamespaceFilter.vue +14 -19
  83. package/components/nav/TopLevelMenu.vue +99 -125
  84. package/components/nav/Type.vue +11 -3
  85. package/config/menuRouteMap.js +10 -0
  86. package/config/product/explorer.js +32 -10
  87. package/config/product/manager.js +28 -17
  88. package/config/router/navigation-guards/index.js +61 -3
  89. package/detail/node.vue +28 -23
  90. package/dialog/AddCustomBadgeDialog.vue +17 -9
  91. package/dialog/RollbackWorkloadDialog.vue +1 -1
  92. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  93. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  94. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  95. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  96. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  97. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  98. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  99. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  100. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  101. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  102. package/edit/configmap.vue +4 -0
  103. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +32 -8
  104. package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +32 -0
  105. package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +52 -0
  106. package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +45 -0
  107. package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +31 -0
  108. package/edit/networking.k8s.io.ingress/Certificate.vue +14 -5
  109. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  110. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  111. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  112. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  113. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  114. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  115. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  116. package/edit/persistentvolume/index.vue +3 -1
  117. package/edit/persistentvolumeclaim.vue +2 -0
  118. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -1
  119. package/edit/secret/index.vue +2 -2
  120. package/edit/service.vue +4 -1
  121. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  122. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  123. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  124. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  125. package/edit/workload/Job.vue +31 -34
  126. package/edit/workload/Upgrading.vue +5 -5
  127. package/edit/workload/index.vue +19 -15
  128. package/edit/workload/storage/Mount.vue +1 -0
  129. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  130. package/edit/workload/storage/azureDisk.vue +14 -10
  131. package/edit/workload/storage/azureFile.vue +9 -7
  132. package/edit/workload/storage/csi/index.vue +6 -9
  133. package/edit/workload/storage/emptyDir.vue +7 -5
  134. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  135. package/edit/workload/storage/hostPath.vue +7 -5
  136. package/edit/workload/storage/nfs.vue +8 -6
  137. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  138. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  139. package/edit/workload/storage/secret.vue +9 -6
  140. package/edit/workload/storage/vsphereVolume.vue +11 -7
  141. package/initialize/app-extended.js +7 -1
  142. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +8 -6
  143. package/mixins/create-edit-view/impl.js +10 -0
  144. package/models/provisioning.cattle.io.cluster.js +19 -18
  145. package/models/workload.js +2 -2
  146. package/package.json +1 -1
  147. package/pages/account/index.vue +93 -58
  148. package/pages/auth/login.vue +1 -1
  149. package/pages/auth/setup.vue +36 -17
  150. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  151. package/pages/c/_cluster/explorer/index.vue +2 -1
  152. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  153. package/pages/home.vue +55 -13
  154. package/plugins/dashboard-store/actions.js +1 -1
  155. package/rancher-components/Banner/Banner.vue +14 -2
  156. package/rancher-components/Form/Radio/RadioGroup.vue +9 -1
  157. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
  158. package/scripts/build-pkg.sh +18 -23
  159. package/scripts/publish-shell.sh +1 -1
  160. package/store/i18n.js +1 -0
  161. package/store/type-map.js +0 -2
  162. package/utils/error.js +23 -3
  163. package/utils/errorTranslate.json +377 -8
  164. package/utils/errorTranslateNew.json +39 -0
@@ -425,128 +425,7 @@ export default {
425
425
  <TopLevelMenu v-if="isRancherInHarvester || isMultiCluster || !isSingleProduct" />
426
426
  </div>
427
427
 
428
- <!-- <div
429
- class="menu-spacer"
430
- :class="{'isSingleProduct': isSingleProduct }"
431
- >
432
- <router-link
433
- v-if="isSingleProduct && !isRancherInHarvester"
434
- :to="singleProductLogoRoute"
435
- role="link"
436
- :alt="t('branding.logos.home')"
437
- >
438
- <BrandImage
439
- v-if="isSingleProduct.supportCustomLogo && isHarvester"
440
- class="side-menu-logo"
441
- file-name="harvester.svg"
442
- :support-custom-logo="true"
443
- :alt="t('branding.logos.label')"
444
- />
445
- <img
446
- v-else
447
- class="side-menu-logo"
448
- :src="isSingleProduct.logo"
449
- :alt="t('branding.logos.label')"
450
- >
451
- </router-link>
452
- </div>
453
-
454
- <div
455
- v-if="!simple"
456
- ref="product"
457
- class="product"
458
- >
459
- <div
460
- v-if="currentProduct && currentProduct.showClusterSwitcher"
461
- v-clean-tooltip="nameTooltip"
462
- class="cluster cluster-clipped"
463
- >
464
- <div
465
- v-if="isSingleProduct && !isRancherInHarvester"
466
- class="product-name"
467
- >
468
- <template v-if="isSingleProduct.supportCustomLogo">
469
- {{ vendor }}
470
- </template>
471
- <template v-else>
472
- {{ t(isSingleProduct.productNameKey) }}
473
- </template>
474
- </div>
475
- <template v-else>
476
- <ClusterProviderIcon
477
- v-if="currentCluster"
478
- :cluster="currentCluster"
479
- class="mr-10"
480
- :alt="t('branding.logos.label')"
481
- />
482
- <div
483
- v-if="currentCluster"
484
- ref="clusterName"
485
- class="cluster-name"
486
- >
487
- {{ currentCluster.spec.displayName }}
488
- </div>
489
- <ClusterBadge
490
- v-if="currentCluster"
491
- :cluster="currentCluster"
492
- class="ml-10"
493
- :alt="t('branding.logos.label')"
494
- />
495
- <div
496
- v-if="!currentCluster"
497
- class="simple-title"
498
- >
499
- <BrandImage
500
- class="side-menu-logo-img"
501
- file-name="rancher-logo.svg"
502
- :alt="t('branding.logos.label')"
503
- />
504
- </div>
505
- </template>
506
- </div>
507
- <div
508
- v-if="currentProduct && !currentProduct.showClusterSwitcher"
509
- class="cluster"
510
- >
511
- <img
512
- v-if="currentProduct.iconHeader"
513
- v-bind="$attrs"
514
- :src="currentProduct.iconHeader"
515
- class="cluster-os-logo mr-10"
516
- style="width: 44px; height: 36px;"
517
- :alt="t('branding.logos.label')"
518
- >
519
- <div class="product-name">
520
- {{ prod }}
521
- </div>
522
- </div>
523
- </div>
524
-
525
- <div
526
- v-else
527
- class="simple-title"
528
- >
529
- <div
530
- v-if="isSingleProduct"
531
- class="product-name"
532
- >
533
- {{ t(isSingleProduct.productNameKey) }}
534
- </div>
535
-
536
- <div
537
- v-else
538
- class="side-menu-logo"
539
- >
540
- <BrandImage
541
- class="side-menu-logo-img"
542
- data-testid="header__brand-img"
543
- file-name="rancher-logo.svg"
544
- :alt="t('branding.logos.label')"
545
- />
546
- </div>
547
- </div> -->
548
-
549
- <!-- ===== 左侧 logo 区域 ===== -->
428
+ <!-- ===== 左侧 logo 区域 ===== -->
550
429
  <div class="menu-spacer">
551
430
  <!-- 如果是单产品模式且不是 RancherInHarvester,就显示 logo 路由跳转 -->
552
431
  <router-link
@@ -593,7 +472,7 @@ export default {
593
472
  <template v-if="currentProduct && currentProduct.showClusterSwitcher">
594
473
 
595
474
  <!-- 导入 YAML 按钮 -->
596
- <button
475
+ <!-- <button
597
476
  v-if="showImportYaml"
598
477
  v-clean-tooltip="t('nav.import')"
599
478
  :disabled="!importEnabled"
@@ -606,9 +485,9 @@ export default {
606
485
  @click="openImport()"
607
486
  >
608
487
  <i class="icon icon-upload icon-lg" />
609
- </button>
488
+ </button> -->
610
489
 
611
- <button
490
+ <!-- <button
612
491
  v-if="showKubeShell"
613
492
  id="btn-kubectl"
614
493
  v-clean-tooltip="t('nav.shellShortcut', {key: shellShortcut})"
@@ -623,10 +502,10 @@ export default {
623
502
  @click="currentCluster.openShell()"
624
503
  >
625
504
  <i class="icon icon-terminal icon-lg" />
626
- </button>
505
+ </button> -->
627
506
 
628
507
  <!-- 下载 kubeconfig 按钮 -->
629
- <button
508
+ <!-- <button
630
509
  v-if="showKubeConfig"
631
510
  v-clean-tooltip="t('nav.kubeconfig.download')"
632
511
  :disabled="!kubeConfigEnabled"
@@ -639,10 +518,10 @@ export default {
639
518
  @click="currentCluster.downloadKubeConfig()"
640
519
  >
641
520
  <i class="icon icon-file icon-lg" />
642
- </button>
521
+ </button> -->
643
522
 
644
523
  <!-- 复制 kubeconfig 按钮 -->
645
- <button
524
+ <!-- <button
646
525
  v-if="showCopyConfig"
647
526
  v-clean-tooltip="t('nav.kubeconfig.copy')"
648
527
  :disabled="!kubeConfigEnabled"
@@ -655,22 +534,21 @@ export default {
655
534
  @click="copyKubeConfig($event)"
656
535
  >
657
536
 
658
- <!-- 点击复制后显示对勾 -->
659
537
  <i
660
538
  v-if="kubeConfigCopying"
661
539
  class="icon icon-checkmark icon-lg"
662
540
  />
663
541
 
664
- <!-- 未复制状态显示复制图标 -->
665
542
  <i
666
543
  v-else
667
544
  class="icon icon-copy icon-lg"
668
545
  />
669
- </button>
546
+ </button> -->
670
547
  </template>
671
548
 
672
549
  <!-- 资源搜索按钮 -->
673
- <button
550
+ <!-- 2025/9/30 隐藏 -->
551
+ <!-- <button
674
552
  v-if="showSearch"
675
553
  id="header-btn-search"
676
554
  v-clean-tooltip="t('nav.resourceSearch.toolTip', {key: searchShortcut})"
@@ -685,7 +563,7 @@ export default {
685
563
  @click="openSearch()"
686
564
  >
687
565
  <i class="icon icon-search icon-lg" />
688
- </button>
566
+ </button> -->
689
567
 
690
568
  <!-- 搜索弹窗 -->
691
569
  <app-modal
@@ -706,9 +584,10 @@ export default {
706
584
  v-if="extensionHeaderActions.length"
707
585
  class="header-buttons"
708
586
  >
587
+ <template v-for="action, i in extensionHeaderActions" :key="`${action.label}${i}`">
588
+ <!-- kubectl-explain.action | 2025/9/30隐藏 -->
709
589
  <button
710
- v-for="action, i in extensionHeaderActions"
711
- :key="`${action.label}${i}`"
590
+ v-if="action.labelKey !== 'kubectl-explain.action'"
712
591
  v-clean-tooltip="handleExtensionTooltip(action)"
713
592
  v-shortkey="action.shortcutKey"
714
593
  :disabled="action.enabled ? !action.enabled(ctx) : false"
@@ -728,6 +607,7 @@ export default {
728
607
  color="header"
729
608
  />
730
609
  </button>
610
+ </template>
731
611
  </div>
732
612
 
733
613
  <!-- ===== 用户菜单(右上角头像 + 下拉) ===== -->
@@ -1021,7 +901,7 @@ export default {
1021
901
  border: none;
1022
902
  background: var(--header-btn-bg);
1023
903
  color: var(--header-btn-text);
1024
- padding: 0 15px 0 10px;
904
+ padding: 0 10px 0 10px;
1025
905
  line-height: 32px;
1026
906
  min-height: 32px;
1027
907
  width: 30px;
@@ -748,7 +748,7 @@ export default {
748
748
  data-testid="namespaces-values-label"
749
749
  class="ns-values"
750
750
  >
751
- {{ value[0].label }}
751
+ {{ value[0].label.replace('harvester', 'cloud') }}
752
752
  </div>
753
753
 
754
754
  <!-- All the selected namespaces -->
@@ -774,20 +774,18 @@ export default {
774
774
  :data-testid="`namespaces-value-${j}`"
775
775
  class="ns-value"
776
776
  >
777
- <div>{{ ns.label }}</div>
777
+ <div>{{ ns.label.replace('harvester', 'cloud') }}</div>
778
778
  <!-- block user from removing the last selection if ns forced filtering is on -->
779
- <RcButton
779
+ <i
780
780
  v-if="!namespaceFilterMode || value.length > 1"
781
781
  small
782
782
  ghost
783
- class="ns-chip-button"
783
+ class="ns-chip-button icon icon-close"
784
784
  :data-testid="`namespaces-values-close-${j}`"
785
785
  @click="removeOption(ns, $event)"
786
786
  @keydown.enter.space.stop="removeOption(ns, $event)"
787
787
  @mousedown="handleValueMouseDown(ns, $event)"
788
- >
789
- <i class="icon icon-close" />
790
- </RcButton>
788
+ />
791
789
  </div>
792
790
  </div>
793
791
 
@@ -836,19 +834,15 @@ export default {
836
834
  @click="focusFilter"
837
835
  @keydown="inputKeyHandler($event)"
838
836
  >
839
- <RcButton
837
+ <i
840
838
  v-if="hasFilter"
841
839
  small
842
840
  ghost
843
- class="ns-filter-clear"
841
+ class="ns-filter-clear icon icon-close"
844
842
  :aria-label="t('namespaceFilter.button.clearFilter')"
845
843
  @click="clearFilter"
846
844
  @keydown.enter.stop="clearFilter"
847
- >
848
- <i
849
- class="icon icon-close"
850
- />
851
- </RcButton>
845
+ />
852
846
  </div>
853
847
  <div
854
848
  v-if="namespaceFilterMode"
@@ -859,7 +853,7 @@ export default {
859
853
  class="icon icon-info"
860
854
  />
861
855
  </div>
862
- <RcButton
856
+ <div
863
857
  v-else
864
858
  small
865
859
  ghost
@@ -871,8 +865,9 @@ export default {
871
865
  >
872
866
  <i
873
867
  class="icon icon-close"
868
+ @click="clear()"
874
869
  />
875
- </RcButton>
870
+ </div>
876
871
  </div>
877
872
  <div class="ns-divider mt-0" />
878
873
  <div
@@ -889,12 +884,12 @@ export default {
889
884
  v-for="(opt, i) in cachedFiltered"
890
885
  :key="opt.id"
891
886
  >
892
- <hr
887
+ <div
893
888
  v-if="opt.kind === NAMESPACE_FILTER_KINDS.DIVIDER"
894
889
  role="separator"
895
890
  aria-orientation="horizontal"
896
891
  class="ns-divider"
897
- >
892
+ />
898
893
  <div
899
894
  v-else
900
895
  :id="opt.elementId"
@@ -919,7 +914,7 @@ export default {
919
914
  v-if="opt.kind === NAMESPACE_FILTER_KINDS.NAMESPACE"
920
915
  class="icon icon-folder"
921
916
  />
922
- <div>{{ opt.label }}</div>
917
+ <div>{{ opt.label.replace('harvester', 'cloud') }}</div>
923
918
  <i
924
919
  v-if="opt.selected"
925
920
  class="icon icon-checkmark"
@@ -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,
@@ -523,7 +520,7 @@ export default {
523
520
  </div>
524
521
 
525
522
  <!-- 品牌Logo -->
526
- <div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'" class="side-menu-logo">
523
+ <div class="side-menu-logo">
527
524
  <BrandImage
528
525
  data-testid="side-menu__brand-img"
529
526
  :alt="t('nav.alt.mainMenuRancherLogo')"
@@ -534,7 +531,7 @@ export default {
534
531
 
535
532
  <!-- ====================== 菜单内容区 ====================== -->
536
533
  <div class="body">
537
- <div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
534
+ <div>
538
535
 
539
536
  <!-- 首页按钮 -->
540
537
  <div @click="hide()">
@@ -650,7 +647,7 @@ export default {
650
647
  </template>
651
648
 
652
649
  <!-- ====================== 集群列表 ====================== -->
653
- <template v-if="topLevelPermissions && topLevelPermissions === 'superadmin' && !!allClustersCount">
650
+ <template v-if="!!allClustersCount">
654
651
  <div
655
652
  ref="clusterList"
656
653
  class="clusters"
@@ -833,7 +830,7 @@ export default {
833
830
  </div>
834
831
  </div>
835
832
 
836
- <!-- 查看所有集群按钮 -->
833
+ <!-- See all clusters -->
837
834
  <router-link
838
835
  v-if="allClustersCount > maxClustersToShow"
839
836
  class="clusters-all"
@@ -853,129 +850,106 @@ export default {
853
850
  </template>
854
851
 
855
852
  <!-- ====================== 多集群应用区 ====================== -->
856
- <div :style="!(topLevelPermissions && topLevelPermissions === 'superadmin') ? { placeContent: 'flex-start', display: 'flex', flexDirection: 'column' } : {}" class="category">
853
+ <div class="category">
857
854
  <!-- 多集群应用 -->
858
855
  <template v-if="multiClusterApps.length">
859
- <template v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
860
- <div
861
- class="category-title"
856
+ <div
857
+ class="category-title"
858
+ >
859
+ <hr role="none">
860
+ <span>
861
+ {{ t('nav.categories.multiCluster') }}
862
+ </span>
863
+ </div>
864
+ <div
865
+ v-for="(a, i) in appBar.multiClusterApps"
866
+ :key="i"
867
+ @click="hide()"
868
+ >
869
+ <router-link
870
+ v-if="a.value !== 'fleet'"
871
+ class="option"
872
+ :class="{'active-menu-link': a.isMenuActive }"
873
+ :to="a.to"
874
+ role="link"
875
+ :aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
862
876
  >
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>
877
+ <IconOrSvg
878
+ v-clean-tooltip="getTooltipConfig(a.label)"
879
+ class="app-icon"
880
+ :icon="a.icon"
881
+ :src="a.svg"
882
+ />
883
+ <span class="option-link">{{ a.label }}</span>
884
+ </router-link>
885
+ </div>
915
886
  </template>
916
887
 
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>
888
+ <!-- Configuration apps menu -->
889
+ <template v-if="configurationApps.length">
890
+ <div
891
+ class="category-title"
892
+ >
893
+ <hr role="none">
894
+ <span>
895
+ {{ t('nav.categories.configuration') }}
896
+ </span>
897
+ </div>
898
+ <div
899
+ v-for="(a, i) in appBar.configurationApps"
900
+ :key="i"
901
+ @click="hide()"
902
+ >
903
+ <router-link
904
+ class="option"
905
+ :class="{'active-menu-link': a.isMenuActive }"
906
+ :to="a.to"
907
+ role="link"
908
+ :aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
909
+ >
910
+ <IconOrSvg
911
+ v-clean-tooltip="getTooltipConfig(a.label)"
912
+ class="app-icon"
913
+ :icon="a.icon"
914
+ :src="a.svg"
915
+ />
916
+ <div>{{ a.label }}</div>
917
+ </router-link>
918
+ </div>
919
+ </template>
920
+ </div>
921
+ </div>
922
+
923
+ <!-- Footer -->
924
+ <div
925
+ class="footer"
926
+ >
927
+ <!-- <div
928
+ v-if="canEditSettings"
929
+ class="support"
930
+ @click="hide()"
931
+ >
932
+ <router-link
933
+ :to="{name: 'support'}"
934
+ role="link"
935
+ :aria-label="t('nav.ariaLabel.support')"
936
+ >
937
+ {{ t('nav.support', {hasSupport}) }}
938
+ </router-link>
978
939
  </div>
940
+ <div
941
+ class="version"
942
+ :class="{'version-small': largeAboutText}"
943
+ @click="hide()"
944
+ >
945
+ <router-link
946
+ :to="{ name: 'about' }"
947
+ role="link"
948
+ :aria-label="t('nav.ariaLabel.about')"
949
+ >
950
+ {{ aboutText }}
951
+ </router-link>
952
+ </div> -->
979
953
  </div>
980
954
  </div>
981
955
  </transition>
@@ -1644,7 +1618,7 @@ export default {
1644
1618
  }
1645
1619
 
1646
1620
  :deep() .v-popper__arrow-container {
1647
- display: none;
1621
+ display: none !important;
1648
1622
  }
1649
1623
 
1650
1624
  :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
+ };