dashboard-shell-shell 3.0.5-test.2 → 3.0.5-test.21

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 (145) hide show
  1. package/assets/icons/iconfont.css +4 -1
  2. package/assets/images/pl/dark/logo.png +0 -0
  3. package/assets/styles/all.scss +3 -1
  4. package/assets/styles/base/_variables.scss +5 -5
  5. package/assets/styles/global/_button.scss +8 -8
  6. package/assets/styles/global/_select.scss +1 -1
  7. package/assets/styles/global/_tooltip.scss +9 -5
  8. package/assets/styles/themes/_light.scss +3 -1
  9. package/assets/styles/vendor/vue-select.scss +2 -1
  10. package/assets/translations/zh-hans.yaml +140 -11
  11. package/components/ActionDropdown.vue +1 -1
  12. package/components/ButtonDropdown.vue +3 -1
  13. package/components/CodeMirror.vue +6 -4
  14. package/components/ContainerResourceLimit.vue +2 -2
  15. package/components/CopyToClipboard.vue +15 -0
  16. package/components/Drawer/Chrome.vue +2 -2
  17. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +30 -27
  18. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +1 -1
  19. package/components/Drawer/ResourceDetailDrawer/index.vue +5 -4
  20. package/components/ExplorerMembers.vue +28 -4
  21. package/components/GlobalRoleBindings.vue +48 -112
  22. package/components/PodSecurityAdmission.vue +1 -1
  23. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +1 -3
  24. package/components/Resource/Detail/Metadata/KeyValue.vue +8 -4
  25. package/components/Resource/Detail/Metadata/index.vue +3 -1
  26. package/components/Resource/Detail/TitleBar/Title.vue +4 -3
  27. package/components/Resource/Detail/TitleBar/Top.vue +2 -0
  28. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  29. package/components/Resource/Detail/TitleBar/index.vue +113 -25
  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 +236 -165
  33. package/components/ResourceDetail/legacy.vue +44 -28
  34. package/components/ResourceList/Masthead.vue +11 -15
  35. package/components/SideNav.vue +1 -1
  36. package/components/SortableTable/index.vue +9 -4
  37. package/components/Tabbed/index.vue +6 -1
  38. package/components/auth/Principal.vue +42 -13
  39. package/components/auth/RoleDetailEdit.vue +11 -7
  40. package/components/breadcrumb/index.vue +124 -0
  41. package/components/form/ArrayList.vue +164 -147
  42. package/components/form/ArrayListGrouped.vue +3 -1
  43. package/components/form/ChangePassword.vue +1 -1
  44. package/components/form/Command.vue +4 -5
  45. package/components/form/Footer.vue +1 -0
  46. package/components/form/HealthCheck.vue +0 -2
  47. package/components/form/HookOption.vue +87 -58
  48. package/components/form/InputWithSelect.vue +8 -7
  49. package/components/form/KeyValue.vue +20 -2
  50. package/components/form/LabeledSelect.vue +6 -3
  51. package/components/form/Labels.vue +2 -2
  52. package/components/form/MatchExpressions.vue +3 -4
  53. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  54. package/components/form/Members/ClusterPermissionsEditor.vue +5 -5
  55. package/components/form/Members/MembershipEditor.vue +2 -2
  56. package/components/form/NameNsDescription.vue +1 -1
  57. package/components/form/Networking.vue +6 -9
  58. package/components/form/NodeAffinity.vue +29 -28
  59. package/components/form/PodAffinity.vue +23 -23
  60. package/components/form/Probe.vue +15 -11
  61. package/components/form/ResourceQuota/Namespace.vue +4 -4
  62. package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
  63. package/components/form/ResourceQuota/Project.vue +4 -4
  64. package/components/form/ResourceQuota/ProjectRow.vue +36 -30
  65. package/components/form/ResourceSelector.vue +1 -1
  66. package/components/form/Security.vue +1 -3
  67. package/components/form/Select.vue +6 -1
  68. package/components/form/ServiceNameSelect.vue +2 -5
  69. package/components/form/ServicePorts.vue +149 -75
  70. package/components/form/Taints.vue +2 -1
  71. package/components/form/Tolerations.vue +12 -9
  72. package/components/form/ValueFromResource.vue +110 -96
  73. package/components/form/WorkloadPorts.vue +143 -123
  74. package/components/nav/Header.vue +3 -4
  75. package/components/nav/NamespaceFilter.vue +15 -21
  76. package/components/nav/TopLevelMenu.vue +99 -125
  77. package/components/nav/Type.vue +3 -3
  78. package/config/product/explorer.js +4 -1
  79. package/config/router/navigation-guards/index.js +52 -3
  80. package/detail/node.vue +28 -23
  81. package/dialog/AddCustomBadgeDialog.vue +17 -9
  82. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  83. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  84. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  85. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  86. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  87. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  88. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  89. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  90. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  91. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  92. package/edit/networking.k8s.io.ingress/Certificate.vue +7 -5
  93. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  94. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  95. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  96. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  97. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  98. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  99. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  100. package/edit/persistentvolume/index.vue +3 -1
  101. package/edit/persistentvolumeclaim.vue +2 -0
  102. package/edit/secret/index.vue +2 -2
  103. package/edit/service.vue +4 -1
  104. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  105. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  106. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  107. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  108. package/edit/workload/Job.vue +31 -34
  109. package/edit/workload/Upgrading.vue +5 -5
  110. package/edit/workload/index.vue +21 -17
  111. package/edit/workload/storage/Mount.vue +1 -0
  112. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  113. package/edit/workload/storage/azureDisk.vue +14 -10
  114. package/edit/workload/storage/azureFile.vue +9 -7
  115. package/edit/workload/storage/csi/index.vue +6 -9
  116. package/edit/workload/storage/emptyDir.vue +7 -5
  117. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  118. package/edit/workload/storage/hostPath.vue +7 -5
  119. package/edit/workload/storage/nfs.vue +8 -6
  120. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  121. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  122. package/edit/workload/storage/secret.vue +9 -6
  123. package/edit/workload/storage/vsphereVolume.vue +11 -7
  124. package/initialize/app-extended.js +7 -1
  125. package/package.json +1 -1
  126. package/pages/account/index.vue +95 -115
  127. package/pages/auth/setup.vue +35 -16
  128. package/pages/c/_cluster/auth/roles/index.vue +38 -5
  129. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  130. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  131. package/pages/home.vue +3 -4
  132. package/pkg/tsconfig.json +9 -9
  133. package/pkg/vue.config.js +1 -1
  134. package/plugins/dashboard-store/resource-class.js +28 -27
  135. package/rancher-components/BadgeState/BadgeState.vue +33 -52
  136. package/rancher-components/Banner/Banner.vue +6 -3
  137. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
  138. package/rancher-components/RcDropdown/RcDropdownMenu.vue +8 -7
  139. package/scripts/publish-shell.sh +1 -1
  140. package/store/i18n.js +4 -0
  141. package/store/type-map.js +1 -1
  142. package/types/shell/index.d.ts +4 -30
  143. package/utils/error.js +3 -1
  144. package/utils/errorTranslate.json +247 -2
  145. package/vue.config.js +1 -1
@@ -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"
@@ -949,7 +944,6 @@ export default {
949
944
  .ns-filter {
950
945
  width: 280px;
951
946
  display: inline-block;
952
- border-radius: var(--border-radius);
953
947
 
954
948
  .ns-glass {
955
949
  top: 0;
@@ -968,9 +962,9 @@ export default {
968
962
  }
969
963
 
970
964
  .ns-clear {
971
- padding: 0 5px;
972
965
  &:hover {
973
966
  color: var(--primary);
967
+ cursor: pointer;
974
968
  }
975
969
  }
976
970
 
@@ -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 {
@@ -141,7 +141,7 @@ export default {
141
141
  <a
142
142
  role="link"
143
143
  :aria-label="type.labelKey ? t(type.labelKey) : (type.labelDisplay || type.label)"
144
- :href="href"
144
+ :href="href.replace(/harvester/g, 'cloud')"
145
145
  class="type-link"
146
146
  :aria-current="isActive ? 'page' : undefined"
147
147
  @click="selectType(); navigate($event);"
@@ -158,7 +158,7 @@ export default {
158
158
  <div v-else style="display: flex; align-items: center;" class="labelKey_menu">
159
159
  <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
160
  <span
161
- v-clean-html="type.labelDisplay.replace('设置', '基础设置') || type.label"
161
+ v-clean-html="type.labelDisplay || type.label"
162
162
  class="label"
163
163
  :class="{'no-icon': !type.icon}"
164
164
  />
@@ -199,7 +199,7 @@ export default {
199
199
  >
200
200
  <a
201
201
  role="link"
202
- :href="type.link"
202
+ :href="type.link.replace(/harvester/g, 'cloud')"
203
203
  :target="type.target"
204
204
  rel="noopener noreferrer nofollow"
205
205
  :aria-label="type.label"
@@ -75,7 +75,9 @@ export function init(store) {
75
75
  NODE,
76
76
  VIRTUAL_TYPES.CLUSTER_MEMBERS,
77
77
  EVENT,
78
- 'c-cluster-explorer-tools'
78
+ 'c-cluster-explorer-tools',
79
+ 'management.cattle.io.project',
80
+ 'management.cattle.io.clusterroletemplatebinding'
79
81
  ], 'cluster');
80
82
  basicType([
81
83
  LIMIT_RANGE,
@@ -95,6 +97,7 @@ export function init(store) {
95
97
  STORAGE_CLASS,
96
98
  SECRET,
97
99
  VIRTUAL_TYPES.PROJECT_SECRETS,
100
+ VIRTUAL_TYPES.NAMESPACES,
98
101
  CONFIG_MAP
99
102
  ], 'storage');
100
103
  basicType([
@@ -11,13 +11,62 @@ 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 || ''; // 获取 router base,防止丢失
55
+ let cloudPath = to.fullPath.replace(/harvester/g, 'cloud');
56
+
57
+ // fullPath 可能已经不带 base,需要拼回去
58
+ if (!cloudPath.startsWith(base)) {
59
+ cloudPath = base + cloudPath;
60
+ }
61
+
62
+ // 获取当前地址栏完整 URL(path + search + hash)
63
+ const currentLocation = window.location.pathname + window.location.search + window.location.hash;
64
+
65
+ // 只有在地址栏实际不同的时候才替换,避免死循环
66
+ if (cloudPath !== currentLocation) {
67
+ console.info('[URL Replace] Updating address bar:', currentLocation, '→', cloudPath);
68
+ window.history.replaceState({}, '', cloudPath);
69
+ }
70
+ });
23
71
  }
72
+
package/detail/node.vue CHANGED
@@ -196,28 +196,7 @@ export default {
196
196
  v-else
197
197
  class="node"
198
198
  >
199
- <div class="spacer" />
200
- <div class="alerts">
201
- <Alert
202
- class="mr-10"
203
- :status="pidPressureStatus"
204
- :message="t('node.detail.glance.pidPressure')"
205
- />
206
- <Alert
207
- class="mr-10"
208
- :status="diskPressureStatus"
209
- :message="t('node.detail.glance.diskPressure')"
210
- />
211
- <Alert
212
- class="mr-10"
213
- :status="memoryPressureStatus"
214
- :message="t('node.detail.glance.memoryPressure')"
215
- />
216
- <Alert
217
- :status="kubeletStatus"
218
- :message="t('node.detail.glance.kubelet')"
219
- />
220
- </div>
199
+ <div style="font-size: 14px;margin-bottom: 32px;">监控数据</div>
221
200
  <div class="mt-20 resources">
222
201
  <ConsumptionGauge
223
202
  :resource-name="t('node.detail.glance.consumptionGauge.cpu')"
@@ -237,7 +216,24 @@ export default {
237
216
  :used="value.podConsumed"
238
217
  />
239
218
  </div>
240
- <div class="spacer" />
219
+ <div class="alerts mt-10">
220
+ <Alert
221
+ :status="pidPressureStatus"
222
+ :message="t('node.detail.glance.pidPressure')"
223
+ />
224
+ <Alert
225
+ :status="diskPressureStatus"
226
+ :message="t('node.detail.glance.diskPressure')"
227
+ />
228
+ <Alert
229
+ :status="memoryPressureStatus"
230
+ :message="t('node.detail.glance.memoryPressure')"
231
+ />
232
+ <Alert
233
+ :status="kubeletStatus"
234
+ :message="t('node.detail.glance.kubelet')"
235
+ />
236
+ </div>
241
237
  <ResourceTabs
242
238
  :value="value"
243
239
  :mode="mode"
@@ -331,4 +327,13 @@ export default {
331
327
  width: 30%;
332
328
  }
333
329
  }
330
+ .alerts{
331
+ display: flex;
332
+ flex-wrap: wrap;
333
+ justify-content: space-between;
334
+ >div{
335
+ width: 30%;
336
+ margin-bottom: 10px;
337
+ }
338
+ }
334
339
  </style>
@@ -236,7 +236,7 @@ export default {
236
236
  <div class="badge-preview-header">
237
237
  <p> {{ t('clusterBadge.modal.previewHeader') }}</p>
238
238
  <div
239
- class="col span-12"
239
+ class="span-12"
240
240
  >
241
241
  <ClusterProviderIcon
242
242
  :cluster="{...previewCluster, badge: displayClusterPrevIcon}"
@@ -340,7 +340,7 @@ export default {
340
340
  display: flex;
341
341
  width: 100%;
342
342
  gap: 40px;
343
- padding: 10px 5px;
343
+ // padding: 10px 5px;
344
344
  margin-bottom: 30px;
345
345
  margin-top: 5px;
346
346
  background: var(--body-bg);
@@ -424,26 +424,34 @@ export default {
424
424
  }
425
425
 
426
426
  .badge-customisation {
427
- display: flex;
428
- gap: 10px;
427
+ // display: flex;
428
+ // gap: 10px;
429
429
 
430
- div {
430
+ >div {
431
431
  display: flex;
432
+ // align-items: flex-end;
433
+ margin-bottom: 30px;
432
434
  flex-direction: column;
433
- flex: 1;
434
- gap: 10px;
435
+ // flex: 1;
436
+ // gap: 10px;
435
437
 
436
438
  .color-input {
437
439
  display: flex;
438
440
  padding: 6px 10px;
439
441
  min-height: 61px;
440
442
  }
443
+
444
+ .checkbox-outer-container{
445
+ min-width: 160px;
446
+ margin-bottom: 10px;
447
+ // align-items: flex-start;
448
+ }
441
449
  }
442
450
 
443
451
  &-color {
444
452
  display: flex;
445
- flex-direction: column;
446
- gap: 10px;
453
+ // flex-direction: column;
454
+ // gap: 10px;
447
455
  }
448
456
  }
449
457
 
@@ -41,7 +41,7 @@ export default {
41
41
 
42
42
  <template>
43
43
  <div>
44
- <div class="row mb-20">
44
+ <div class="row">
45
45
  <MetricTarget
46
46
  v-model:value="value.target"
47
47
  :mode="mode"