dashboard-shell-shell 3.0.5-tsh.1 → 3.0.5-tsh.11

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 (67) hide show
  1. package/assets/iconsNew/demo.css +539 -0
  2. package/assets/iconsNew/demo.css:Zone.Identifier +0 -0
  3. package/assets/iconsNew/demo_index.html +303 -0
  4. package/assets/iconsNew/demo_index.html:Zone.Identifier +0 -0
  5. package/assets/iconsNew/iconfont.css +43 -0
  6. package/assets/iconsNew/iconfont.css:Zone.Identifier +0 -0
  7. package/assets/iconsNew/iconfont.js +1 -0
  8. package/assets/iconsNew/iconfont.js:Zone.Identifier +0 -0
  9. package/assets/iconsNew/iconfont.json +44 -0
  10. package/assets/iconsNew/iconfont.json:Zone.Identifier +0 -0
  11. package/assets/iconsNew/iconfont.ttf +0 -0
  12. package/assets/iconsNew/iconfont.ttf:Zone.Identifier +0 -0
  13. package/assets/iconsNew/iconfont.woff +0 -0
  14. package/assets/iconsNew/iconfont.woff2 +0 -0
  15. package/assets/iconsNew/iconfont.woff2:Zone.Identifier +0 -0
  16. package/assets/iconsNew/iconfont.woff:Zone.Identifier +0 -0
  17. package/assets/images/login-logo.svg +37 -12
  18. package/assets/images/logo.svg +47 -0
  19. package/assets/styles/app.scss +1 -0
  20. package/assets/styles/base/_helpers.scss +1 -1
  21. package/assets/translations/en-us.yaml +4 -0
  22. package/assets/translations/zh-hans.yaml +57 -1
  23. package/components/GlobalRoleBindings.vue +21 -6
  24. package/components/form/Members/ClusterPermissionsEditor.vue +34 -18
  25. package/components/form/Members/MembershipEditor.vue +1 -1
  26. package/components/form/NameNsDescription.vue +17 -3
  27. package/components/form/ProjectMemberEditor.vue +38 -23
  28. package/components/form/SecretSelector.vue +24 -23
  29. package/components/nav/Group.vue +2 -1
  30. package/components/nav/Header.vue +40 -43
  31. package/config/private-label.js +2 -3
  32. package/config/product/uiplugins.js +13 -10
  33. package/edit/logging-flow/index.vue +1 -2
  34. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +3 -3
  35. package/edit/logging.banzaicloud.io.output/providers/azurestorage.vue +19 -19
  36. package/edit/logging.banzaicloud.io.output/providers/cloudwatch.vue +23 -23
  37. package/edit/logging.banzaicloud.io.output/providers/datadog.vue +19 -19
  38. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +14 -14
  39. package/edit/logging.banzaicloud.io.output/providers/forward.vue +12 -12
  40. package/edit/logging.banzaicloud.io.output/providers/gcs.vue +23 -23
  41. package/edit/logging.banzaicloud.io.output/providers/gelf.vue +6 -6
  42. package/edit/logging.banzaicloud.io.output/providers/kafka.vue +10 -10
  43. package/edit/logging.banzaicloud.io.output/providers/kinesisStream.vue +8 -8
  44. package/edit/logging.banzaicloud.io.output/providers/logdna.vue +17 -17
  45. package/edit/logging.banzaicloud.io.output/providers/logz.vue +7 -7
  46. package/edit/logging.banzaicloud.io.output/providers/loki.vue +12 -12
  47. package/edit/logging.banzaicloud.io.output/providers/newrelic.vue +3 -3
  48. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +14 -14
  49. package/edit/logging.banzaicloud.io.output/providers/redis.vue +6 -6
  50. package/edit/logging.banzaicloud.io.output/providers/s3.vue +23 -23
  51. package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +13 -13
  52. package/edit/logging.banzaicloud.io.output/providers/sumologic.vue +2 -2
  53. package/edit/logging.banzaicloud.io.output/providers/syslog.vue +54 -54
  54. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +8 -8
  55. package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +13 -5
  56. package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +19 -6
  57. package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +18 -5
  58. package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +18 -3
  59. package/package.json +1 -1
  60. package/pages/auth/login.vue +25 -28
  61. package/pages/c/_cluster/auth/roles/index.vue +27 -3
  62. package/public/index.html +1 -1
  63. package/scripts/publish-shell.sh +1 -1
  64. package/types/shell/index.d.ts +8 -0
  65. package/utils/errorTranslate.json +25 -0
  66. package/utils/roleFiltering.js +33 -0
  67. package/utils/title.ts +1 -1
@@ -3129,6 +3129,8 @@ logging:
3129
3129
  path: 路径
3130
3130
  overwriteExistingPath: 覆盖现有路径
3131
3131
  output:
3132
+ output:
3133
+ label: 输出
3132
3134
  buffer:
3133
3135
  label: 输出缓冲
3134
3136
  selectOutputs: 选择输出
@@ -3152,7 +3154,7 @@ logging:
3152
3154
  azurestorage: Azure Storage
3153
3155
  cloudwatch: Cloudwatch
3154
3156
  datadog: Datadog
3155
- file: 文件
3157
+ file: File
3156
3158
  gcs: GCS
3157
3159
  kinesisStream: Kinesis Stream
3158
3160
  logdna: LogDNA
@@ -3264,6 +3266,18 @@ members:
3264
3266
  viewClusterCatalogs: 查看集群应用商店
3265
3267
  viewClusterMembers: 查看集群成员
3266
3268
  viewNodes: 查看节点
3269
+ safe-admin:
3270
+ label: 安全管理员
3271
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
3272
+ project-tenant:
3273
+ label: 租户
3274
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3275
+ cluster-tenant:
3276
+ label: 租户
3277
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3278
+ tenant:
3279
+ label: 租户
3280
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3267
3281
  owner:
3268
3282
  label: 所有者
3269
3283
  description: 所有者对集群和集群内的所有资源拥有完全的控制权。
@@ -3495,6 +3509,18 @@ monitoringReceiver:
3495
3509
  opsgenie:
3496
3510
  label: Opsgenie
3497
3511
  title: Opsgenie 配置
3512
+ dingding:
3513
+ label: 钉钉
3514
+ title: 钉钉 配置
3515
+ weixin:
3516
+ label: 企业微信
3517
+ title: 企业微信 配置
3518
+ snmp:
3519
+ label: SNMP
3520
+ title: SNMP 配置
3521
+ message:
3522
+ label: 短信
3523
+ title: 短信 配置
3498
3524
  pagerduty:
3499
3525
  label: PagerDuty
3500
3526
  title: PagerDuty 配置
@@ -4490,6 +4516,12 @@ projectMembers:
4490
4516
  description: 控制用户对项目的访问权限
4491
4517
  noDescription: 已创建用户 - 没有描述
4492
4518
  searchForMember: 搜索需要向其提供项目访问权限的成员
4519
+ safe-admin:
4520
+ label: 安全管理员
4521
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
4522
+ tenant:
4523
+ label: 租户
4524
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4493
4525
  owner:
4494
4526
  label: 所有者
4495
4527
  description: 所有者对项目和项目内的所有资源拥有完全的控制权限。
@@ -4753,6 +4785,9 @@ rbac:
4753
4785
  description: 无描述
4754
4786
  assignOnlyRole: 已分配该角色
4755
4787
  role:
4788
+ cluster-tenant:
4789
+ label: 租户
4790
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4756
4791
  admin:
4757
4792
  label: 管理员
4758
4793
  description: 管理员可以完全控制整个安装以及所有集群中的所有资源。
@@ -4762,6 +4797,12 @@ rbac:
4762
4797
  user-base:
4763
4798
  label: User-Base 用户
4764
4799
  description: User-Base 用户只拥有登录权限。
4800
+ tenant:
4801
+ label: 租户
4802
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4803
+ safe-admin:
4804
+ label: 安全管理员
4805
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
4765
4806
  clusters-create:
4766
4807
  label: 创建集群
4767
4808
  description: 允许用户创建集群,并成为该集群的所有者(owner)。普通用户默认拥有此权限。
@@ -6532,6 +6573,7 @@ model:
6532
6573
  label: Service Account 用户名
6533
6574
  projectMember:
6534
6575
  role:
6576
+ tenant: 租户
6535
6577
  member: 成员
6536
6578
  owner: 所有者
6537
6579
  readonly: 只读用户
@@ -6627,6 +6669,10 @@ typeDescription:
6627
6669
  batch.cronjob: CronJob 创建 Job,然后按照重复调度来运行 Pod。该调度以标准的 Unix cron 格式表示,并使用 Kubernetes Control Plane 的时区(通常是 UTC)。
6628
6670
  batch.job: Job 创建一个或多个 Pod。 Job 通过运行 Pod 直到其成功退出,以可靠执行一次性任务。失败的 Pod 会自动被替换,直到达到指定的完成运行次数。Job 还可以并行运行多个 Pod,或作为批处理工作队列。
6629
6671
  pod: Pod 是你可以在 Kubernetes 中创建和管理的最小可部署计算单元。Pod 是一个或多个容器,具有共享的存储和网络资源以及运行容器的规范。
6672
+ harvesterhci.io.logging.clusterflow: 用于配置集群范围内的日志采集与流转规则,可匹配多个资源组的日志,并将日志转发至指定的集群日志外发目标,实现全局级的日志统一管理与路由。
6673
+ harvesterhci.io.logging.clusteroutput: 定义集群范围的日志输出目标,例如 Elasticsearch、Loki、S3、Kafka 等。可被多个集群日志配置引用,用于集中存储与分析集群级日志数据。
6674
+ harvesterhci.io.logging.flow: 用于配置资源组(命名空间)内的日志采集与流转规则,仅作用于当前资源组内的日志,并将日志转发至对应的资源组日志外发目标,便于分组级的日志管理。
6675
+ harvesterhci.io.logging.output: 定义资源组级别的日志输出目标,仅能被同一资源组下的日志配置引用,用于将该资源组内的日志发送至指定的存储或分析系统。
6630
6676
  typeLabel:
6631
6677
  management.cattle.io.project: |-
6632
6678
  {count, plural,
@@ -8075,3 +8121,13 @@ component:
8075
8121
  keyValue:
8076
8122
  noRows: 此资源上没有配置{propertyName}.
8077
8123
  showConfiguration: 显示配置
8124
+
8125
+
8126
+
8127
+ customConversion:
8128
+ Tenant: 租户
8129
+ Cluster Owner: 所有者
8130
+ Project Owner: 项目负责人
8131
+
8132
+
8133
+
@@ -103,21 +103,36 @@ export default {
103
103
  this.sortedRoles.global.push(...remainingGlobalRoles);
104
104
  // End sort of global roles
105
105
 
106
- delete this.sortedRoles.builtin
107
- delete this.sortedRoles.custom
106
+ if (!(sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin')) {
107
+ delete this.sortedRoles.builtin
108
+ delete this.sortedRoles.custom
109
+ }
108
110
 
109
111
  this.update();
110
112
  }
111
113
  } catch (e) { }
112
114
  },
113
115
  data() {
114
- return {
115
- // This not only identifies global roles but the order here is the order we want to display them in the UI
116
- globalPermissions: [
116
+
117
+ let globalPermissions = [
118
+ 'admin',
119
+ 'safe-admin',
120
+ 'tenant',
121
+ ]
122
+
123
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
124
+ globalPermissions = [
117
125
  'admin',
126
+ 'safe-admin',
118
127
  'user',
119
128
  'user-base',
120
- ],
129
+ 'tenant',
130
+ ]
131
+ }
132
+
133
+ return {
134
+ // This not only identifies global roles but the order here is the order we want to display them in the UI
135
+ globalPermissions,
121
136
  globalRoleBindings: null,
122
137
  sortedRoles: null,
123
138
  selectedRoles: [],
@@ -143,30 +143,46 @@ export default {
143
143
  return [this.permissionGroup];
144
144
  },
145
145
  options() {
146
+
146
147
  const customRoles = this.customRoles.map((role) => ({
147
148
  label: role.nameDisplay,
148
149
  description: role.description || role.metadata?.annotations?.[DESCRIPTION] || this.t('members.clusterPermissions.noDescription'),
149
150
  value: role.id
150
151
  }));
151
152
 
152
- return [
153
- {
154
- label: this.t('members.clusterPermissions.owner.label'),
155
- description: this.t('members.clusterPermissions.owner.description'),
156
- value: 'owner'
157
- },
158
- {
159
- label: this.t('members.clusterPermissions.member.label'),
160
- description: this.t('members.clusterPermissions.member.description'),
161
- value: 'member'
162
- },
163
- ...customRoles,
164
- // {
165
- // label: this.t('members.clusterPermissions.custom.label'),
166
- // description: this.t('members.clusterPermissions.custom.description'),
167
- // value: 'custom'
168
- // }
169
- ];
153
+ let optionList = [{
154
+ label: this.t('members.clusterPermissions.cluster-tenant.label'),
155
+ description: this.t('members.clusterPermissions.cluster-tenant.description'),
156
+ value: 'cluster-tenant'
157
+ }];
158
+
159
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
160
+ optionList = [
161
+ {
162
+ label: this.t('members.clusterPermissions.cluster-tenant.label'),
163
+ description: this.t('members.clusterPermissions.cluster-tenant.description'),
164
+ value: 'cluster-tenant'
165
+ },
166
+ {
167
+ label: this.t('members.clusterPermissions.owner.label'),
168
+ description: this.t('members.clusterPermissions.owner.description'),
169
+ value: 'owner'
170
+ },
171
+ {
172
+ label: this.t('members.clusterPermissions.member.label'),
173
+ description: this.t('members.clusterPermissions.member.description'),
174
+ value: 'member'
175
+ },
176
+ ...customRoles,
177
+ {
178
+ label: this.t('members.clusterPermissions.custom.label'),
179
+ description: this.t('members.clusterPermissions.custom.description'),
180
+ value: 'custom'
181
+ }
182
+ ];
183
+ }
184
+
185
+ return optionList
170
186
  },
171
187
  principal() {
172
188
  const principalId = this.principalId.replace(/\//g, '%2F');
@@ -191,7 +191,7 @@ export default {
191
191
  :data-testid="`role-item-${i}`"
192
192
  class="col span-6 role"
193
193
  >
194
- {{ row.value.roleDisplay }}
194
+ {{ $store.getters['i18n/withFallback'](`customConversion.${row.value.roleDisplay}`, row.value.roleDisplay) }}
195
195
  </div>
196
196
  </div>
197
197
  </template>
@@ -176,6 +176,11 @@ export default {
176
176
  componentTestid: {
177
177
  type: String,
178
178
  default: 'name-ns-description'
179
+ },
180
+
181
+ extraNamespaceOptions: {
182
+ type: Array,
183
+ default: () => []
179
184
  }
180
185
  },
181
186
 
@@ -269,6 +274,16 @@ export default {
269
274
  });
270
275
  }
271
276
 
277
+ if (props.extraNamespaceOptions && props.extraNamespaceOptions.length > 0) {
278
+ props.extraNamespaceOptions.map(item => {
279
+ const objs = {
280
+ label: item,
281
+ value: item,
282
+ }
283
+ sortedByLabel.push(objs);
284
+ })
285
+ }
286
+
272
287
  const createButton = {
273
288
  label: t('namespace.createNamespace'),
274
289
  value: '',
@@ -514,9 +529,8 @@ export default {
514
529
  </div>
515
530
 
516
531
  <!-- 自定义插槽,可插入额外内容 -->
517
- <div :class=" isDialog? 'namespace-item-row mb-20': 'col span-6'">
518
- <slot name="customize" />
519
- </div>
532
+ <slot name="customize" />
533
+
520
534
  <!-- <div
521
535
  v-show="!descriptionHidden"
522
536
  :data-testid="componentTestid + '-description'"
@@ -166,29 +166,44 @@ export default {
166
166
  value: this.purifyOption(role.id),
167
167
  }));
168
168
 
169
- return [
170
- {
171
- label: this.t('projectMembers.projectPermissions.owner.label'),
172
- description: this.t('projectMembers.projectPermissions.owner.description'),
173
- value: 'owner'
174
- },
175
- {
176
- label: this.t('projectMembers.projectPermissions.member.label'),
177
- description: this.t('projectMembers.projectPermissions.member.description'),
178
- value: 'member'
179
- },
180
- {
181
- label: this.t('projectMembers.projectPermissions.readOnly.label'),
182
- description: this.t('projectMembers.projectPermissions.readOnly.description'),
183
- value: 'read-only'
184
- },
185
- ...customRoles,
186
- {
187
- label: this.t('projectMembers.projectPermissions.custom.label'),
188
- description: this.t('projectMembers.projectPermissions.custom.description'),
189
- value: 'custom'
190
- }
191
- ];
169
+ let optionList = [{
170
+ label: this.t('members.clusterPermissions.project-tenant.label'),
171
+ description: this.t('members.clusterPermissions.project-tenant.description'),
172
+ value: 'project-tenant'
173
+ }];
174
+
175
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
176
+ optionList = [
177
+ {
178
+ label: this.t('members.clusterPermissions.project-tenant.label'),
179
+ description: this.t('members.clusterPermissions.project-tenant.description'),
180
+ value: 'project-tenant'
181
+ },
182
+ {
183
+ label: this.t('projectMembers.projectPermissions.owner.label'),
184
+ description: this.t('projectMembers.projectPermissions.owner.description'),
185
+ value: 'owner'
186
+ },
187
+ {
188
+ label: this.t('projectMembers.projectPermissions.member.label'),
189
+ description: this.t('projectMembers.projectPermissions.member.description'),
190
+ value: 'member'
191
+ },
192
+ {
193
+ label: this.t('projectMembers.projectPermissions.readOnly.label'),
194
+ description: this.t('projectMembers.projectPermissions.readOnly.description'),
195
+ value: 'read-only'
196
+ },
197
+ ...customRoles,
198
+ {
199
+ label: this.t('projectMembers.projectPermissions.custom.label'),
200
+ description: this.t('projectMembers.projectPermissions.custom.description'),
201
+ value: 'custom'
202
+ }
203
+ ];
204
+ }
205
+
206
+ return optionList
192
207
  },
193
208
  customPermissionsUpdate() {
194
209
  return this.customPermissions.reduce((acc, customPermissionsItem) => {
@@ -210,31 +210,32 @@ export default {
210
210
  <template>
211
211
  <div
212
212
  class="secret-selector"
213
- :class="{'show-key-selector': showKeySelector}"
214
213
  >
215
- <div class="input-container">
214
+ <div :class="{'row': showKeySelector}" class="input-container">
216
215
  <!-- key by namespace to ensure label select current page is recreated on ns change -->
217
- <ResourceLabeledSelect
218
- :key="namespace"
219
- v-model:value="name"
220
- :disabled="!isView && disabled"
221
- :label="secretNameLabel"
222
- :mode="mode"
223
- :resource-type="SECRET"
224
- :in-store="inStore"
225
- :paginated-resource-settings="paginateSecretsSetting"
226
- :all-resources-settings="allSecretsSettings"
227
- />
228
- <LabeledSelect
229
- v-if="showKeySelector"
230
- :key="namespace"
231
- v-model:value="key"
232
- class="col span-6"
233
- :disabled="isKeyDisabled"
234
- :options="keys"
235
- :label="keyNameLabel"
236
- :mode="mode"
237
- />
216
+ <div :class="{'col span-6': showKeySelector}">
217
+ <ResourceLabeledSelect
218
+ :key="namespace"
219
+ v-model:value="name"
220
+ :disabled="!isView && disabled"
221
+ :label="secretNameLabel"
222
+ :mode="mode"
223
+ :resource-type="SECRET"
224
+ :in-store="inStore"
225
+ :paginated-resource-settings="paginateSecretsSetting"
226
+ :all-resources-settings="allSecretsSettings"
227
+ />
228
+ </div>
229
+ <div v-if="showKeySelector" class="col span-6">
230
+ <LabeledSelect
231
+ :key="namespace"
232
+ v-model:value="key"
233
+ :disabled="isKeyDisabled"
234
+ :options="keys"
235
+ :label="keyNameLabel"
236
+ :mode="mode"
237
+ />
238
+ </div>
238
239
  </div>
239
240
  </div>
240
241
  </template>
@@ -58,7 +58,8 @@ export default {
58
58
  '网络管理': 'icon-networks',
59
59
  '镜像管理': 'icon-imagelist',
60
60
  '资源管理': 'icon-sorcetype',
61
- '运维管理': 'icon-monitoringandlogging'
61
+ '运维管理': 'icon-monitoringandlogging',
62
+ '日志管理': 'icon-new-Logging'
62
63
  }
63
64
 
64
65
 
@@ -80,7 +80,7 @@ export default {
80
80
  ctx: this,
81
81
  showImportModal: false,
82
82
  showSearchModal: false,
83
- userIcon: require('@shell/assets/images/logo.png'),
83
+ userIcon: require('@shell/assets/images/logo.svg'),
84
84
  };
85
85
  },
86
86
 
@@ -277,14 +277,14 @@ export default {
277
277
 
278
278
  methods: {
279
279
 
280
- LogOutfn (type) {
281
- sessionStorage.removeItem('TOPLEVELPERMISSIONS')
280
+ LogOutfn(type) {
281
+ sessionStorage.removeItem('TOPLEVELPERMISSIONS');
282
282
  if (type === '1') {
283
- this.$router.push({ name: 'account'})
283
+ this.$router.push({ name: 'account' });
284
284
  } else if (type === '2') {
285
- this.showSloModal()
285
+ this.showSloModal();
286
286
  } else if (type === '3') {
287
- this.$router.push(this.generateLogoutRoute)
287
+ this.$router.push(this.generateLogoutRoute);
288
288
  }
289
289
  },
290
290
 
@@ -413,14 +413,12 @@ export default {
413
413
  </script>
414
414
 
415
415
  <template>
416
-
417
416
  <!-- 整个页面的顶部 header -->
418
417
  <header
419
418
  ref="header"
420
419
  data-testid="header"
421
420
  >
422
421
  <div>
423
-
424
422
  <!-- 顶部一级菜单(根据不同产品/集群条件决定是否显示) -->
425
423
  <TopLevelMenu v-if="isRancherInHarvester || isMultiCluster || !isSingleProduct" />
426
424
  </div>
@@ -432,20 +430,18 @@ export default {
432
430
  v-if="isSingleProduct && !isRancherInHarvester"
433
431
  :to="singleProductLogoRoute"
434
432
  >
435
-
436
433
  <!-- 显示用户头像或 logo 图片 -->
437
434
  <img
438
435
  :src="userIcon"
439
436
  >
440
437
  </router-link>
441
438
  </div>
442
-
439
+
443
440
  <!-- ===== 中间占位符(把左右内容分开) ===== -->
444
441
  <div class="spacer" />
445
442
 
446
443
  <!-- ===== 右侧功能区域 ===== -->
447
444
  <div class="rd-header-right">
448
-
449
445
  <!-- 动态插入右侧自定义组件(例如插件扩展的 header) -->
450
446
  <component :is="navHeaderRight" />
451
447
 
@@ -454,10 +450,9 @@ export default {
454
450
  v-if="showFilter"
455
451
  class="top"
456
452
  >
457
-
458
453
  <!-- 如果集群就绪 + 当前产品支持命名空间过滤器 或 Explorer 模式 -->
459
454
  <NamespaceFilter v-if="clusterReady && currentProduct && (currentProduct.showNamespaceFilter || isExplorer)" />
460
-
455
+
461
456
  <!-- 否则显示工作空间切换器 -->
462
457
  <WorkspaceSwitcher v-else-if="clusterReady && currentProduct && currentProduct.showWorkspaceSwitcher" />
463
458
  </div>
@@ -467,10 +462,8 @@ export default {
467
462
  v-if="currentCluster && !simple"
468
463
  class="header-buttons"
469
464
  >
470
-
471
465
  <!-- 如果当前产品支持集群切换器 -->
472
466
  <template v-if="currentProduct && currentProduct.showClusterSwitcher">
473
-
474
467
  <!-- 导入 YAML 按钮 -->
475
468
  <!-- <button
476
469
  v-if="showImportYaml"
@@ -533,7 +526,7 @@ export default {
533
526
  :aria-label="t('nav.kubeconfig.copy')"
534
527
  @click="copyKubeConfig($event)"
535
528
  >
536
-
529
+
537
530
  <i
538
531
  v-if="kubeConfigCopying"
539
532
  class="icon icon-checkmark icon-lg"
@@ -575,8 +568,7 @@ export default {
575
568
  :trigger-focus-trap="true"
576
569
  return-focus-selector="#header-btn-search"
577
570
  @close="hideSearch()"
578
- >
579
- </app-modal>
571
+ />
580
572
  </div>
581
573
 
582
574
  <!-- ===== 插件扩展按钮区 ===== -->
@@ -584,30 +576,33 @@ export default {
584
576
  v-if="extensionHeaderActions.length"
585
577
  class="header-buttons"
586
578
  >
587
- <template v-for="action, i in extensionHeaderActions" :key="`${action.label}${i}`">
588
- <!-- kubectl-explain.action | 2025/9/30隐藏 -->
589
- <button
590
- v-if="action.labelKey !== 'kubectl-explain.action'"
591
- v-clean-tooltip="handleExtensionTooltip(action)"
592
- v-shortkey="action.shortcutKey"
593
- :disabled="action.enabled ? !action.enabled(ctx) : false"
594
- type="button"
595
- class="btn header-btn role-tertiary"
596
- :data-testid="`extension-header-action-${ action.labelKey || action.label }`"
597
- role="button"
598
- tabindex="0"
599
- :aria-label="action.label"
600
- @shortkey="handleExtensionAction(action, $event)"
601
- @click="handleExtensionAction(action, $event)"
579
+ <template
580
+ v-for="action, i in extensionHeaderActions"
581
+ :key="`${action.label}${i}`"
602
582
  >
603
- <IconOrSvg
604
- class="icon icon-lg"
605
- :icon="action.icon"
606
- :src="action.svg"
607
- color="header"
608
- />
609
- </button>
610
- </template>
583
+ <!-- kubectl-explain.action | 2025/9/30隐藏 -->
584
+ <button
585
+ v-if="action.labelKey !== 'kubectl-explain.action'"
586
+ v-clean-tooltip="handleExtensionTooltip(action)"
587
+ v-shortkey="action.shortcutKey"
588
+ :disabled="action.enabled ? !action.enabled(ctx) : false"
589
+ type="button"
590
+ class="btn header-btn role-tertiary"
591
+ :data-testid="`extension-header-action-${ action.labelKey || action.label }`"
592
+ role="button"
593
+ tabindex="0"
594
+ :aria-label="action.label"
595
+ @shortkey="handleExtensionAction(action, $event)"
596
+ @click="handleExtensionAction(action, $event)"
597
+ >
598
+ <IconOrSvg
599
+ class="icon icon-lg"
600
+ :icon="action.icon"
601
+ :src="action.svg"
602
+ color="header"
603
+ />
604
+ </button>
605
+ </template>
611
606
  </div>
612
607
 
613
608
  <!-- ===== 用户菜单(右上角头像 + 下拉) ===== -->
@@ -618,7 +613,6 @@ export default {
618
613
  v-if="showUserMenu"
619
614
  :aria-label="t('nav.userMenu.label')"
620
615
  >
621
-
622
616
  <!-- 头像触发按钮 -->
623
617
  <rc-dropdown-trigger
624
618
  ghost
@@ -638,7 +632,10 @@ export default {
638
632
  v-else
639
633
  class="icon icon-user icon-3x avatar"
640
634
  /> -->
641
- <i class="icon icon-usericon" style="padding-bottom: 5px;" />
635
+ <i
636
+ class="icon icon-usericon"
637
+ style="padding-bottom: 5px;"
638
+ />
642
639
  <span class="login-name">{{ principal.loginName }}</span>
643
640
  </rc-dropdown-trigger>
644
641
 
@@ -58,8 +58,7 @@ export function matches(pl) {
58
58
  }
59
59
 
60
60
  export function getVendor() {
61
-
62
- return 'HCI';
61
+ return '云翼云管平台';
63
62
  }
64
63
  // export function getVendor() {
65
64
  // if ( vendor === SETTING.PL_RANCHER_VALUE ) {
@@ -84,7 +83,7 @@ export function setTitle() {
84
83
  if (v === 'Harvester') {
85
84
  const ico = require(`~shell/assets/images/pl/harvester.png`);
86
85
 
87
- document.title = 'HCI';
86
+ document.title = '云翼云管平台';
88
87
  const link = document.createElement('link');
89
88
 
90
89
  link.hid = 'icon';
@@ -5,14 +5,17 @@ export const NAME = 'uiplugins';
5
5
  export function init(store) {
6
6
  const { product } = DSL(store, NAME);
7
7
 
8
- // Add a product for UI Plugins - will appear in the top-level menu
9
- product({
10
- ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
11
- inStore: 'management',
12
- icon: 'extension',
13
- removable: false,
14
- showClusterSwitcher: false,
15
- category: 'configuration',
16
- weight: 50,
17
- });
8
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
9
+ // Add a product for UI Plugins - will appear in the top-level menu
10
+ product({
11
+ ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
12
+ inStore: 'management',
13
+ icon: 'extension',
14
+ removable: false,
15
+ showClusterSwitcher: false,
16
+ category: 'configuration',
17
+ weight: 50,
18
+ });
19
+ }
20
+
18
21
  }
@@ -418,10 +418,9 @@ export default {
418
418
  class="mt-0"
419
419
  :label="t('logging.flow.matches.banner')"
420
420
  />
421
- <div v-if="isHarvester">
421
+ <div class="mb-20" v-if="isHarvester">
422
422
  <LabeledSelect
423
423
  v-model:value="loggingType"
424
- class="mb-20"
425
424
  :options="flowTypeOptions"
426
425
  :mode="mode"
427
426
  :disabled="!isCreate"