dashboard-shell-shell 3.0.5-test.4 → 3.0.5-test.40

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 (163) 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 +5 -5
  6. package/assets/styles/fonts/_icons.scss +3 -2
  7. package/assets/styles/global/_button.scss +8 -8
  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 +9 -5
  11. package/assets/styles/themes/_light.scss +6 -4
  12. package/assets/styles/vendor/vue-select.scss +2 -1
  13. package/assets/translations/en-us.yaml +59 -0
  14. package/assets/translations/zh-hans.yaml +168 -15
  15. package/components/ActionDropdown.vue +1 -1
  16. package/components/ButtonDropdown.vue +3 -1
  17. package/components/CodeMirror.vue +6 -4
  18. package/components/ContainerResourceLimit.vue +2 -2
  19. package/components/CopyToClipboard.vue +15 -0
  20. package/components/Drawer/Chrome.vue +2 -2
  21. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +30 -27
  22. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +1 -1
  23. package/components/Drawer/ResourceDetailDrawer/index.vue +5 -4
  24. package/components/ExplorerMembers.vue +28 -4
  25. package/components/GlobalRoleBindings.vue +51 -112
  26. package/components/PodSecurityAdmission.vue +2 -2
  27. package/components/RelatedResources.vue +3 -0
  28. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +1 -3
  29. package/components/Resource/Detail/Metadata/KeyValue.vue +8 -4
  30. package/components/Resource/Detail/Metadata/index.vue +3 -1
  31. package/components/Resource/Detail/TitleBar/Title.vue +4 -3
  32. package/components/Resource/Detail/TitleBar/Top.vue +2 -0
  33. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  34. package/components/Resource/Detail/TitleBar/index.vue +123 -25
  35. package/components/ResourceDetail/Masthead/index.vue +1 -1
  36. package/components/ResourceDetail/Masthead/latest.vue +1 -1
  37. package/components/ResourceDetail/Masthead/legacy.vue +8 -7
  38. package/components/ResourceDetail/legacy.vue +18 -16
  39. package/components/ResourceList/Masthead.vue +13 -17
  40. package/components/ResourceTable.vue +10 -0
  41. package/components/SideNav.vue +21 -21
  42. package/components/SortableTable/THead.vue +46 -1
  43. package/components/SortableTable/index.vue +40 -20
  44. package/components/Tabbed/index.vue +6 -1
  45. package/components/auth/Principal.vue +10 -5
  46. package/components/auth/RoleDetailEdit.vue +11 -7
  47. package/components/breadcrumb/index.vue +119 -0
  48. package/components/form/ArrayList.vue +164 -147
  49. package/components/form/ArrayListGrouped.vue +5 -3
  50. package/components/form/ChangePassword.vue +1 -1
  51. package/components/form/Command.vue +4 -5
  52. package/components/form/Conditions.vue +15 -1
  53. package/components/form/Footer.vue +1 -0
  54. package/components/form/HealthCheck.vue +0 -2
  55. package/components/form/HookOption.vue +87 -58
  56. package/components/form/InputWithSelect.vue +8 -7
  57. package/components/form/KeyValue.vue +20 -2
  58. package/components/form/LabeledSelect.vue +6 -3
  59. package/components/form/Labels.vue +2 -2
  60. package/components/form/MatchExpressions.vue +4 -4
  61. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  62. package/components/form/Members/ClusterPermissionsEditor.vue +31 -28
  63. package/components/form/Members/MembershipEditor.vue +2 -2
  64. package/components/form/NameNsDescription.vue +1 -1
  65. package/components/form/Networking.vue +6 -9
  66. package/components/form/NodeAffinity.vue +29 -28
  67. package/components/form/PodAffinity.vue +23 -23
  68. package/components/form/Probe.vue +15 -11
  69. package/components/form/ProjectMemberEditor.vue +28 -25
  70. package/components/form/ResourceQuota/Namespace.vue +4 -4
  71. package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
  72. package/components/form/ResourceQuota/Project.vue +4 -4
  73. package/components/form/ResourceQuota/ProjectRow.vue +36 -30
  74. package/components/form/ResourceSelector.vue +1 -1
  75. package/components/form/Security.vue +1 -3
  76. package/components/form/Select.vue +7 -1
  77. package/components/form/ServiceNameSelect.vue +2 -5
  78. package/components/form/ServicePorts.vue +149 -75
  79. package/components/form/Taints.vue +2 -1
  80. package/components/form/Tolerations.vue +13 -9
  81. package/components/form/ValueFromResource.vue +110 -96
  82. package/components/form/WorkloadPorts.vue +143 -123
  83. package/components/formatter/WorkloadHealthScale.vue +4 -3
  84. package/components/nav/Group.vue +6 -0
  85. package/components/nav/Header.vue +7 -4
  86. package/components/nav/NamespaceFilter.vue +15 -21
  87. package/components/nav/TopLevelMenu.vue +99 -125
  88. package/components/nav/Type.vue +11 -3
  89. package/config/menuRouteMap.js +10 -0
  90. package/config/product/explorer.js +31 -9
  91. package/config/router/navigation-guards/index.js +61 -3
  92. package/detail/node.vue +28 -23
  93. package/dialog/AddCustomBadgeDialog.vue +17 -9
  94. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  95. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  96. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  97. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  98. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  99. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  100. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  101. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  102. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  103. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  104. package/edit/configmap.vue +4 -0
  105. package/edit/networking.k8s.io.ingress/Certificate.vue +14 -5
  106. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  107. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  108. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  109. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  110. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  111. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  112. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  113. package/edit/persistentvolume/index.vue +3 -1
  114. package/edit/persistentvolumeclaim.vue +2 -0
  115. package/edit/secret/index.vue +2 -2
  116. package/edit/service.vue +4 -1
  117. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  118. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  119. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  120. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  121. package/edit/workload/Job.vue +31 -34
  122. package/edit/workload/Upgrading.vue +5 -5
  123. package/edit/workload/index.vue +22 -18
  124. package/edit/workload/storage/Mount.vue +1 -0
  125. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  126. package/edit/workload/storage/azureDisk.vue +14 -10
  127. package/edit/workload/storage/azureFile.vue +9 -7
  128. package/edit/workload/storage/csi/index.vue +6 -9
  129. package/edit/workload/storage/emptyDir.vue +7 -5
  130. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  131. package/edit/workload/storage/hostPath.vue +7 -5
  132. package/edit/workload/storage/nfs.vue +8 -6
  133. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  134. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  135. package/edit/workload/storage/secret.vue +9 -6
  136. package/edit/workload/storage/vsphereVolume.vue +11 -7
  137. package/initialize/app-extended.js +7 -1
  138. package/models/provisioning.cattle.io.cluster.js +19 -18
  139. package/package.json +1 -1
  140. package/pages/account/index.vue +90 -118
  141. package/pages/account/pri.vue +229 -0
  142. package/pages/auth/login.vue +6 -1
  143. package/pages/auth/setup.vue +36 -17
  144. package/pages/c/_cluster/_product/namespaces.vue +1 -1
  145. package/pages/c/_cluster/auth/roles/index.vue +38 -5
  146. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  147. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  148. package/pages/home.vue +3 -4
  149. package/pkg/tsconfig.json +9 -9
  150. package/pkg/vue.config.js +1 -1
  151. package/plugins/dashboard-store/resource-class.js +28 -27
  152. package/rancher-components/BadgeState/BadgeState.vue +33 -52
  153. package/rancher-components/Banner/Banner.vue +4 -1
  154. package/rancher-components/Form/Radio/RadioGroup.vue +9 -1
  155. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
  156. package/rancher-components/RcDropdown/RcDropdownMenu.vue +8 -7
  157. package/scripts/publish-shell.sh +1 -1
  158. package/store/i18n.js +4 -0
  159. package/store/type-map.js +1 -3
  160. package/types/shell/index.d.ts +4 -30
  161. package/utils/error.js +3 -1
  162. package/utils/errorTranslate.json +366 -2
  163. package/vue.config.js +1 -1
@@ -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
+ };
@@ -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([
@@ -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
+
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"
@@ -49,8 +49,8 @@ export default {
49
49
 
50
50
  <template>
51
51
  <div>
52
- <div class="row mb-20">
53
- <div class="col span-12">
52
+ <div class="row">
53
+ <div class="span-12">
54
54
  <ArrayListGrouped
55
55
  v-model:value="value.spec.behavior[type].policies"
56
56
  :add-label="t('hpa.scalingRule.addPolicy')"
@@ -59,7 +59,7 @@ export default {
59
59
  >
60
60
  <template #default="props">
61
61
  <div class="row">
62
- <div class="col span-4">
62
+ <div class="col">
63
63
  <LabeledSelect
64
64
  v-model:value="props.row.value.type"
65
65
  :mode="mode"
@@ -72,7 +72,9 @@ export default {
72
72
  :label="t('hpa.scalingRule.policy.type')"
73
73
  />
74
74
  </div>
75
- <div class="col span-4">
75
+ </div>
76
+ <div class="row">
77
+ <div class="col">
76
78
  <LabeledInput
77
79
  v-model:value.number="props.row.value.value"
78
80
  :mode="mode"
@@ -83,7 +85,9 @@ export default {
83
85
  :label="t('hpa.scalingRule.policy.value')"
84
86
  />
85
87
  </div>
86
- <div class="col span-4">
88
+ </div>
89
+ <div class="row">
90
+ <div class="col">
87
91
  <LabeledInput
88
92
  v-model:value.number="props.row.value.periodSeconds"
89
93
  :mode="mode"
@@ -125,6 +129,5 @@ export default {
125
129
  />
126
130
  </div>
127
131
  </div>
128
- <div class="row mb-40" />
129
132
  </div>
130
133
  </template>
@@ -215,7 +215,7 @@ export default {
215
215
  :label="t('hpa.tabs.target')"
216
216
  :weight="10"
217
217
  >
218
- <div class="row mb-20">
218
+ <div class="row">
219
219
  <div class="col span-6">
220
220
  <LabeledSelect
221
221
  v-model:value="value.spec.scaleTargetRef"
@@ -242,6 +242,8 @@ export default {
242
242
  type="number"
243
243
  />
244
244
  </div>
245
+ </div>
246
+ <div class="row">
245
247
  <div class="col span-6">
246
248
  <LabeledInput
247
249
  v-model:value.number="value.spec.maxReplicas"