dashboard-shell-shell 3.0.5-test.3 → 3.0.5-test.31

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 (153) 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 +21 -1
  4. package/assets/styles/base/_variables.scss +5 -5
  5. package/assets/styles/fonts/_icons.scss +3 -2
  6. package/assets/styles/global/_button.scss +8 -8
  7. package/assets/styles/global/_select.scss +1 -1
  8. package/assets/styles/global/_tooltip.scss +9 -5
  9. package/assets/styles/themes/_light.scss +3 -1
  10. package/assets/styles/vendor/vue-select.scss +2 -1
  11. package/assets/translations/zh-hans.yaml +156 -13
  12. package/components/ActionDropdown.vue +1 -1
  13. package/components/ButtonDropdown.vue +3 -1
  14. package/components/CodeMirror.vue +6 -4
  15. package/components/ContainerResourceLimit.vue +2 -2
  16. package/components/CopyToClipboard.vue +15 -0
  17. package/components/Drawer/Chrome.vue +2 -2
  18. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +30 -27
  19. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +1 -1
  20. package/components/Drawer/ResourceDetailDrawer/index.vue +5 -4
  21. package/components/ExplorerMembers.vue +28 -4
  22. package/components/GlobalRoleBindings.vue +48 -112
  23. package/components/PodSecurityAdmission.vue +2 -2
  24. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +1 -3
  25. package/components/Resource/Detail/Metadata/KeyValue.vue +8 -4
  26. package/components/Resource/Detail/Metadata/index.vue +3 -1
  27. package/components/Resource/Detail/TitleBar/Title.vue +4 -3
  28. package/components/Resource/Detail/TitleBar/Top.vue +2 -0
  29. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  30. package/components/Resource/Detail/TitleBar/index.vue +123 -25
  31. package/components/ResourceDetail/Masthead/index.vue +1 -1
  32. package/components/ResourceDetail/Masthead/latest.vue +1 -1
  33. package/components/ResourceDetail/Masthead/legacy.vue +239 -167
  34. package/components/ResourceDetail/legacy.vue +44 -28
  35. package/components/ResourceList/Masthead.vue +14 -15
  36. package/components/SideNav.vue +21 -21
  37. package/components/SortableTable/THead.vue +21 -1
  38. package/components/SortableTable/index.vue +23 -6
  39. package/components/Tabbed/index.vue +6 -1
  40. package/components/auth/Principal.vue +42 -13
  41. package/components/auth/RoleDetailEdit.vue +11 -7
  42. package/components/breadcrumb/index.vue +119 -0
  43. package/components/form/ArrayList.vue +164 -147
  44. package/components/form/ArrayListGrouped.vue +3 -1
  45. package/components/form/ChangePassword.vue +1 -1
  46. package/components/form/Command.vue +4 -5
  47. package/components/form/Conditions.vue +15 -1
  48. package/components/form/Footer.vue +1 -0
  49. package/components/form/HealthCheck.vue +0 -2
  50. package/components/form/HookOption.vue +87 -58
  51. package/components/form/InputWithSelect.vue +8 -7
  52. package/components/form/KeyValue.vue +20 -2
  53. package/components/form/LabeledSelect.vue +6 -3
  54. package/components/form/Labels.vue +2 -2
  55. package/components/form/MatchExpressions.vue +3 -4
  56. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  57. package/components/form/Members/ClusterPermissionsEditor.vue +5 -5
  58. package/components/form/Members/MembershipEditor.vue +2 -2
  59. package/components/form/NameNsDescription.vue +1 -1
  60. package/components/form/Networking.vue +6 -9
  61. package/components/form/NodeAffinity.vue +29 -28
  62. package/components/form/PodAffinity.vue +23 -23
  63. package/components/form/Probe.vue +15 -11
  64. package/components/form/ResourceQuota/Namespace.vue +4 -4
  65. package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
  66. package/components/form/ResourceQuota/Project.vue +4 -4
  67. package/components/form/ResourceQuota/ProjectRow.vue +36 -30
  68. package/components/form/ResourceSelector.vue +1 -1
  69. package/components/form/Security.vue +1 -3
  70. package/components/form/Select.vue +6 -1
  71. package/components/form/ServiceNameSelect.vue +2 -5
  72. package/components/form/ServicePorts.vue +149 -75
  73. package/components/form/Taints.vue +2 -1
  74. package/components/form/Tolerations.vue +12 -9
  75. package/components/form/ValueFromResource.vue +110 -96
  76. package/components/form/WorkloadPorts.vue +143 -123
  77. package/components/formatter/WorkloadHealthScale.vue +4 -3
  78. package/components/nav/Group.vue +6 -0
  79. package/components/nav/Header.vue +7 -4
  80. package/components/nav/NamespaceFilter.vue +15 -21
  81. package/components/nav/TopLevelMenu.vue +99 -125
  82. package/components/nav/Type.vue +15 -3
  83. package/config/menuRouteMap.js +10 -0
  84. package/config/product/explorer.js +5 -1
  85. package/config/router/navigation-guards/index.js +61 -3
  86. package/detail/node.vue +28 -23
  87. package/dialog/AddCustomBadgeDialog.vue +17 -9
  88. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  89. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  90. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  91. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  92. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  93. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  94. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  95. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  96. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  97. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  98. package/edit/configmap.vue +4 -0
  99. package/edit/networking.k8s.io.ingress/Certificate.vue +7 -5
  100. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  101. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  102. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  103. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  104. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  105. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  106. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  107. package/edit/persistentvolume/index.vue +3 -1
  108. package/edit/persistentvolumeclaim.vue +2 -0
  109. package/edit/secret/index.vue +2 -2
  110. package/edit/service.vue +4 -1
  111. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  112. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  113. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  114. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  115. package/edit/workload/Job.vue +31 -34
  116. package/edit/workload/Upgrading.vue +5 -5
  117. package/edit/workload/index.vue +22 -18
  118. package/edit/workload/storage/Mount.vue +1 -0
  119. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  120. package/edit/workload/storage/azureDisk.vue +14 -10
  121. package/edit/workload/storage/azureFile.vue +9 -7
  122. package/edit/workload/storage/csi/index.vue +6 -9
  123. package/edit/workload/storage/emptyDir.vue +7 -5
  124. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  125. package/edit/workload/storage/hostPath.vue +7 -5
  126. package/edit/workload/storage/nfs.vue +8 -6
  127. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  128. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  129. package/edit/workload/storage/secret.vue +9 -6
  130. package/edit/workload/storage/vsphereVolume.vue +11 -7
  131. package/initialize/app-extended.js +7 -1
  132. package/models/provisioning.cattle.io.cluster.js +19 -18
  133. package/package.json +1 -1
  134. package/pages/account/index.vue +95 -115
  135. package/pages/auth/setup.vue +35 -16
  136. package/pages/c/_cluster/auth/roles/index.vue +38 -5
  137. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  138. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  139. package/pages/home.vue +3 -4
  140. package/pkg/tsconfig.json +9 -9
  141. package/pkg/vue.config.js +1 -1
  142. package/plugins/dashboard-store/resource-class.js +28 -27
  143. package/rancher-components/BadgeState/BadgeState.vue +33 -52
  144. package/rancher-components/Banner/Banner.vue +4 -1
  145. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
  146. package/rancher-components/RcDropdown/RcDropdownMenu.vue +8 -7
  147. package/scripts/publish-shell.sh +1 -1
  148. package/store/i18n.js +4 -0
  149. package/store/type-map.js +1 -1
  150. package/types/shell/index.d.ts +4 -30
  151. package/utils/error.js +3 -1
  152. package/utils/errorTranslate.json +356 -2
  153. package/vue.config.js +1 -1
@@ -244,31 +244,31 @@ export default {
244
244
 
245
245
  replaceWith(this.groups, ...sortBy(out, ['weight:desc', 'label']));
246
246
 
247
- // if (this.principal.loginName !== 'admin') {
248
- // // 递归过滤函数(根据 label)
249
- // this.groups = this.filterMenus(this.groups);
250
- // }
247
+
248
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') !== 'superadmin') {
249
+ // 递归过滤函数(根据 label)
250
+ this.groups = this.filterMenus(this.groups);
251
+ }
251
252
 
252
253
 
253
254
  this.gettingGroups = false;
254
255
  },
255
256
 
256
- // filterMenus(menus) {
257
- // return menus
258
- // .filter(item => item.label !== 'RBAC') // 过滤掉顶层 RBAC
259
- // .map(item => {
260
- // let newItem = { ...item };
261
- // if (newItem.children) {
262
- // // 过滤掉 children 里的 "资源大盘"
263
- // newItem.children = newItem.children.filter(
264
- // child => child.label !== '资源大盘'
265
- // );
266
- // // 递归处理剩下的 children
267
- // newItem.children = filterMenus(newItem.children);
268
- // }
269
- // return newItem;
270
- // });
271
- // },
257
+ filterMenus(menus) {
258
+ return menus.filter(item => item.name !== 'inUse' && item.name !== 'apps') // 过滤掉顶层 inUse 和 apps
259
+ // .map(item => {
260
+ // let newItem = { ...item };
261
+ // if (newItem.children) {
262
+ // // 过滤掉 children 里的 "资源大盘"
263
+ // newItem.children = newItem.children.filter(
264
+ // child => child.label !== '资源大盘'
265
+ // );
266
+ // // 递归处理剩下的 children
267
+ // newItem.children = filterMenus(newItem.children);
268
+ // }
269
+ // return newItem;
270
+ // });
271
+ },
272
272
 
273
273
  getProductsGroups(out, loadProducts, namespaceMode, productMap) {
274
274
  const clusterId = this.$store.getters['clusterId'];
@@ -436,7 +436,7 @@ export default {
436
436
  :aria-label="t('nav.ariaLabel.sideNav')"
437
437
  >
438
438
  <div class="side-all-title">
439
- {{ prod == 'Cloud' && currentCluster ? '控制台' : prod }}
439
+ {{ (prod == 'Cloud' || prod == 'Harvester') && currentCluster ? '控制台' : prod }}
440
440
  </div>
441
441
 
442
442
  <!-- Actual nav -->
@@ -208,9 +208,29 @@ export default {
208
208
  return null;
209
209
  }
210
210
 
211
+ // 创建英文到中文的映射
212
+ const tooltipMap = {
213
+ 'The minimum number of pods that must be available': '必须可用的 Pod 最小数量',
214
+ 'The maximum number of pods that may be unavailable': '允许不可用的 Pod 最大数量',
215
+ 'Calculated number of pods that may be disrupted at this time': '当前允许中断的 Pod 数量',
216
+ 'Request represents a minimum amount of cpu/memory that a container may consume': 'Request 表示容器必须保证的最小 CPU/内存资源量',
217
+ 'Limits control the maximum amount of cpu/memory that a container may use independent of contention on the node': 'Limits 控制容器可使用的 CPU/内存最大资源量,该限制与节点上的资源竞争情况无关',
218
+
219
+ };
220
+
211
221
  const exists = this.$store.getters['i18n/exists'];
212
222
 
213
- return exists(col.tooltip) ? this.t(col.tooltip) : col.tooltip;
223
+ // 如果 tooltip 是语言包键名
224
+ if (exists(col.tooltip)) {
225
+ return this.t(col.tooltip);
226
+ }
227
+
228
+ // 如果 tooltip 是英文文本,使用映射
229
+ if (tooltipMap[col.tooltip]) {
230
+ return tooltipMap[col.tooltip];
231
+ }
232
+
233
+ return col.tooltip; // 回退到原始文本
214
234
  },
215
235
  }
216
236
 
@@ -1074,12 +1074,22 @@ export default {
1074
1074
  if ( col.labelKey ) {
1075
1075
  return this.t(col.labelKey, undefined, true);
1076
1076
  } else if ( col.label ) {
1077
- return col.label;
1077
+ // 判断 label 是否为中文
1078
+ if (this.isChinese(col.label)) {
1079
+ return col.label;
1080
+ } else {
1081
+ return this.t(`tableHeaders.${col.label.replace(/\s+/g, '').toLowerCase()}`, undefined, true);
1082
+ }
1078
1083
  }
1079
1084
 
1080
1085
  return ucFirst(col.name);
1081
1086
  },
1082
1087
 
1088
+ // 判断字符串是否包含中文
1089
+ isChinese(str) {
1090
+ return /[\u4e00-\u9fa5]/.test(str);
1091
+ },
1092
+
1083
1093
  valueFor(row, col, isLabel) {
1084
1094
  if (typeof col.value === 'function') {
1085
1095
  return col.value(row);
@@ -1841,7 +1851,7 @@ export default {
1841
1851
  class="paging"
1842
1852
  >
1843
1853
  <div style="height: 100%; align-content: center;">
1844
- 共 {{ filteredRows.length }} 条
1854
+ 共 {{ filteredRows ? filteredRows.length : 0 }} 条
1845
1855
  </div>
1846
1856
 
1847
1857
  <button
@@ -2186,7 +2196,7 @@ export default {
2186
2196
  border-collapse: collapse;
2187
2197
  min-width: 400px;
2188
2198
  border-radius: 5px 5px 0 0;
2189
- border-bottom: 1px solid var(--border);
2199
+ border-bottom: 1px solid var(--border) !important;
2190
2200
  /* outline: 1px solid var(--border); */
2191
2201
  background: var(--sortable-table-bg);
2192
2202
  border-radius: 4px;
@@ -2199,8 +2209,13 @@ export default {
2199
2209
  }
2200
2210
 
2201
2211
  td {
2212
+ height: 60px;
2213
+ min-height: 60px;
2202
2214
  padding: 8px 5px;
2203
2215
  border: 0;
2216
+ white-space: normal;
2217
+ word-break: break-all;
2218
+ overflow-wrap: break-word;
2204
2219
 
2205
2220
  &:first-child {
2206
2221
  padding-left: 10px;
@@ -2217,7 +2232,7 @@ export default {
2217
2232
 
2218
2233
  tbody {
2219
2234
  tr {
2220
- border-bottom: 1px solid var(--sortable-table-top-divider);
2235
+ border-bottom: 1px solid var(--sortable-table-top-divider) !important;
2221
2236
  background-color: var(--sortable-table-row-bg);
2222
2237
 
2223
2238
  &.main-row.has-sub-row {
@@ -2658,13 +2673,15 @@ export default {
2658
2673
 
2659
2674
  .pageSelect{
2660
2675
  &:deep() .vs__actions:after{
2661
- padding-top: 10px;
2676
+ // padding-top: 10px;
2677
+ display: flex;
2678
+ align-items: center;
2662
2679
  }
2663
2680
  }
2664
2681
  .sort-table-div{
2665
2682
  width:100%;
2666
2683
  white-space:nowrap;
2667
- overflow-x: auto;
2684
+ // overflow-x: auto;
2668
2685
  }
2669
2686
 
2670
2687
  /* 滚动阴影左边 */
@@ -384,12 +384,13 @@ export default {
384
384
 
385
385
  &.horizontal {
386
386
  border: solid thin var(--border);
387
- border-bottom: 0;
387
+ // border-bottom: 0;
388
388
  display: flex;
389
389
  flex-direction: row;
390
390
 
391
391
  + .tab-container {
392
392
  border: solid thin var(--border);
393
+ border-top: 0px;
393
394
  }
394
395
 
395
396
  .tab.active {
@@ -504,6 +505,8 @@ margin: 0px -20px;
504
505
  display: flex;
505
506
  border-bottom:1px solid #d7d7d7;
506
507
  padding: 0 0 0 20px;
508
+ // overflow: auto;
509
+ // overflow-y: hidden;
507
510
  /* flex: 1 0; */
508
511
  /* flex-direction: column; */
509
512
 
@@ -571,6 +574,8 @@ margin: 0px -20px;
571
574
  li {
572
575
  display: flex;
573
576
  flex: 1;
577
+ border-left: 1px solid var(--border);
578
+ border-right: 1px solid var(--border);
574
579
 
575
580
  .btn {
576
581
  flex: 1 1;
@@ -16,7 +16,15 @@ export default {
16
16
  showLabels: {
17
17
  type: Boolean,
18
18
  default: false,
19
- }
19
+ },
20
+ isShowPass: {
21
+ type: Boolean,
22
+ default: false,
23
+ },
24
+ userLogoSize: {
25
+ type: Number,
26
+ default: 20,
27
+ },
20
28
  },
21
29
 
22
30
  async fetch() {
@@ -86,9 +94,10 @@ export default {
86
94
  </template>
87
95
 
88
96
  <template v-else-if="principal">
89
- <div class="avatar">
97
+ <div :style="userLogoSize === 79 ? { width: '287px' } : {}" class="avatar">
90
98
  <img
91
- :src="principal.avatarSrc"
99
+ :style="{ width: userLogoSize + 'px', height: userLogoSize + 'px' }"
100
+ src="@shell/assets/images/user.png"
92
101
  :class="{'round': principal.roundAvatar}"
93
102
  :alt="t('principal.alt.avatar')"
94
103
  >
@@ -98,11 +107,19 @@ export default {
98
107
  class="name"
99
108
  >
100
109
  <table>
101
- <tbody>
102
- <tr><th>{{ t('principal.name') }}: </th><td>{{ principal.name || principal.loginName }}</td></tr>
103
- <tr><th>{{ t('principal.loginName') }}: </th><td>{{ principal.loginName }}</td></tr>
104
- <tr><th>{{ t('principal.type') }}: </th><td>{{ principal.displayType }}</td></tr>
105
- </tbody>
110
+ <tr class="mb-10">
111
+ <td>{{ t('principal.name') }}: </td><td>{{ principal.name || principal.loginName }}</td>
112
+ </tr>
113
+ <tr class="mb-10">
114
+ <td>{{ t('principal.loginName') }}: </td><td>{{ principal.loginName }}</td>
115
+ </tr>
116
+ <tr
117
+ v-if="isShowPass"
118
+ class="mb-10"
119
+ >
120
+ <td>修改密码: </td><td>****** <slot name="edit" /></td>
121
+ </tr>
122
+ <tr><td>{{ t('principal.type') }}: </td><td>{{ principal.displayType }}</td></tr>
106
123
  </table>
107
124
  </div>
108
125
  <template v-else>
@@ -172,23 +189,35 @@ export default {
172
189
  }
173
190
 
174
191
  &.showLabels {
175
- grid-template-areas:
192
+ /* grid-template-areas:
176
193
  "avatar name";
177
194
  grid-template-columns: 60px auto;
178
195
  grid-template-rows: 60px;
179
- column-gap: 0;
196
+ column-gap: 0; */
197
+ display: flex;
198
+ column-gap:0;
180
199
  .name {
200
+ display: flex;
181
201
  line-height: unset;
182
202
  }
183
-
203
+ table tr {
204
+ display: block;
205
+ }
184
206
  table tr td:not(:first-of-type) {
185
207
  padding-left: 10px;
186
208
  }
209
+ table tr td:not(:last-of-type) {
210
+ width: 100px;
211
+ }
187
212
  }
188
213
 
189
214
  .avatar {
190
- grid-area: avatar;
191
- text-align: center;
215
+ /* grid-area: avatar;
216
+ text-align: center; */
217
+ // width: 287px;
218
+ display: flex;
219
+ justify-content: center;
220
+ align-items: center;
192
221
 
193
222
  DIV.empty {
194
223
  border: 1px solid var(--border);
@@ -152,7 +152,7 @@ export default {
152
152
  });
153
153
  }
154
154
 
155
- if (this.value?.metadata?.name && !this.value.displayName) {
155
+ if (this.value?.metadata?.name && !this.value?.displayName) {
156
156
  this.value['displayName'] = this.value.metadata.name;
157
157
  }
158
158
 
@@ -705,12 +705,12 @@ export default {
705
705
  <!-- 列表头部 -->
706
706
  <template #column-headers>
707
707
  <div class="column-headers row">
708
- <div :class="ruleClass">
708
+ <div class="arrayListCls" :class="ruleClass">
709
709
  <span class="text-label">{{ t('rbac.roletemplate.tabs.grantResources.tableHeaders.verbs') }}
710
710
  <span class="required">*</span>
711
711
  </span>
712
712
  </div>
713
- <div :class="ruleClass">
713
+ <div class="arrayListCls" :class="ruleClass">
714
714
  <span class="text-label">
715
715
  {{ t('rbac.roletemplate.tabs.grantResources.tableHeaders.resources') }}
716
716
  <i
@@ -723,7 +723,7 @@ export default {
723
723
  >*</span>
724
724
  </span>
725
725
  </div>
726
- <div :class="ruleClass">
726
+ <div class="arrayListCls" :class="ruleClass">
727
727
  <span class="text-label">{{ t('rbac.roletemplate.tabs.grantResources.tableHeaders.apiGroups') }}</span>
728
728
  </div>
729
729
  <div
@@ -740,7 +740,7 @@ export default {
740
740
  <div class="columns row mr-20">
741
741
 
742
742
  <!-- 动作(verbs)选择 -->
743
- <div :class="ruleClass">
743
+ <div class="arrayListCls" :class="ruleClass">
744
744
  <!-- Select verbs -->
745
745
  <Select
746
746
  :value="props.row.value.verbs"
@@ -758,7 +758,7 @@ export default {
758
758
  </div>
759
759
 
760
760
  <!-- 资源(resources)选择 -->
761
- <div :class="ruleClass">
761
+ <div class="arrayListCls" :class="ruleClass">
762
762
  <Select
763
763
  style="width: auto;"
764
764
  :value="getRule('resources', props.row.value)"
@@ -776,7 +776,7 @@ export default {
776
776
  </div>
777
777
 
778
778
  <!-- API Groups 输入 -->
779
- <div :class="ruleClass">
779
+ <div class="arrayListCls" :class="ruleClass">
780
780
  <LabeledInput
781
781
  :value="getRule('apiGroups', props.row.value)"
782
782
  :disabled="isBuiltin"
@@ -788,6 +788,7 @@ export default {
788
788
 
789
789
  <!-- 非命名空间 URL 输入(仅非命名空间模式显示) -->
790
790
  <div
791
+ class="arrayListCls"
791
792
  v-if="!isNamespaced"
792
793
  :class="ruleClass"
793
794
  >
@@ -859,6 +860,9 @@ export default {
859
860
  </template>
860
861
 
861
862
  <style lang="scss" scoped>
863
+ .arrayListCls {
864
+ min-width: 360px;
865
+ }
862
866
  .ruleCls {
863
867
  margin-right: 10px;
864
868
  }
@@ -0,0 +1,119 @@
1
+ <script>
2
+ import { get } from '@shell/utils/object';;
3
+ import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
4
+ import { useStore } from 'vuex';
5
+
6
+ export default {
7
+
8
+ name: 'MastheadBreadcrumb',
9
+
10
+ components: {
11
+ },
12
+ props: {
13
+ resourceTypeLabel: {
14
+ type: String,
15
+ default: ''
16
+ },
17
+
18
+ resource: {
19
+ type: String,
20
+ default: null,
21
+ },
22
+
23
+ realMode: {
24
+ type: String,
25
+ default: 'view',
26
+ }
27
+
28
+ },
29
+
30
+ setup() {
31
+ const store = useStore();
32
+ const { featureDropdownMenu } = useRuntimeFlag(store);
33
+
34
+ return { featureDropdownMenu };
35
+ },
36
+
37
+ data() {
38
+ return {
39
+ };
40
+ },
41
+
42
+ computed: {
43
+
44
+ demoDisplay() {
45
+
46
+ const resources = this.$route.params?.resource || ''
47
+
48
+ let productId = this.$store.getters['type-map/groupForBasicType'](this.$store.getters['productId'], resources);
49
+ const parts = productId.split('::');
50
+ const newString = 'root';
51
+
52
+ if (!parts?.includes(newString)) {
53
+ parts.unshift(newString); // 将字符串添加到数组第一位
54
+ }
55
+
56
+ const partsEn = parts.map((item) => {
57
+ return this.$store.getters['i18n/t'](`typeLabel."${ item.toLowerCase() }"`);
58
+ });
59
+
60
+ return partsEn;
61
+ },
62
+
63
+ },
64
+
65
+ methods: {
66
+ get,
67
+ }
68
+ };
69
+ </script>
70
+
71
+ <template>
72
+ <div class="masthead">
73
+ <div class="title">
74
+ <!-- 标题区域 -->
75
+ <div
76
+ class="excram-list"
77
+ >
78
+ <span
79
+ v-for="(item,index) in demoDisplay"
80
+ :key="index"
81
+ >
82
+ <span>{{ item }}</span>
83
+ <span>/</span>
84
+ </span>
85
+ <span class="excram-last-name">
86
+ {{ (realMode === 'view'? '查看': realMode === 'edit' ? '编辑':'创建') + resourceTypeLabel }}
87
+ </span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </template>
92
+
93
+ <style lang='scss' scoped>
94
+
95
+ .excram-list{
96
+ font-size: 14px;
97
+ margin-bottom: 20px;
98
+ }
99
+ .excram-last-name{
100
+ color: var(--link);
101
+ }
102
+
103
+ .detailIcon-span{
104
+ width: 24px;
105
+ height: 24px;
106
+ display: inline-block;
107
+ position: relative;
108
+ background: var(--primary);
109
+ margin-right: 10px;
110
+ }
111
+ .detailIcon{
112
+ position: absolute;
113
+ color: #fff;
114
+ font-size: 38px;
115
+ left: 4px;
116
+ top: -2px;
117
+ }
118
+
119
+ </style>