dashboard-shell-shell 3.0.5-test.41 → 3.0.5-test.43

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.
@@ -6464,6 +6464,7 @@ storageClass:
6464
6464
  tooltip: By default the default storage class on the host Harvester cluster is used.
6465
6465
 
6466
6466
  tableHeaders:
6467
+ claimedby: claimedby
6467
6468
  pod: pod
6468
6469
  volumeattributesclass: volumeattributesclass
6469
6470
  assuredConcurrencyShares: Assured Concurrency Shares
@@ -796,6 +796,10 @@ asyncButton:
796
796
  action: 恢复编排
797
797
  success: 已恢复编排
798
798
  waiting: 正在恢复编排
799
+ redeploy:
800
+ action: 重新部署
801
+ success: 重新部署成功
802
+ waiting: 正在重新部署工作负载
799
803
  rollback:
800
804
  action: 回滚
801
805
  success: 已回滚
@@ -4592,6 +4596,10 @@ promptRollback:
4592
4596
  multipleWorkloadError: "一次只能回滚一个工作负载。"
4593
4597
  singleRevisionBanner: 没有可用于回滚的修订版本。
4594
4598
 
4599
+ promptRedeploy:
4600
+ title: 重新部署 {type}?
4601
+ attemptingToRedeploy: "您正在尝试重新部署 {type} {names} 重新部署将重启所选工作负载,可能导致暂时性服务中断。"
4602
+
4595
4603
  promptSaveAsRKETemplate:
4596
4604
  title: 将 {cluster} 转换为新的 RKE 模板
4597
4605
  name: 集群模板名称
@@ -5442,6 +5450,7 @@ storageClass:
5442
5450
  tooltip: 默认使用主机 Cloud 集群上的默认存储类。
5443
5451
 
5444
5452
  tableHeaders:
5453
+ claimedby: 占用者
5445
5454
  pod: pod
5446
5455
  ip: ip
5447
5456
  volumeattributesclass: 卷属性类
@@ -623,13 +623,14 @@ export default {
623
623
  />
624
624
  <span v-else>{{ subtype.label }}</span>
625
625
  </h5>
626
- <a
626
+ <!-- 禅道 3541 隐藏 更多信息 -->
627
+ <!-- <a
627
628
  v-if="subtype.docLink"
628
629
  :href="subtype.docLink"
629
630
  target="_blank"
630
631
  rel="noopener nofollow"
631
632
  class="flex-right"
632
- >{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a>
633
+ >{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a> -->
633
634
  </div>
634
635
  <hr
635
636
  v-if="subtype.description"
@@ -698,6 +698,12 @@ export default {
698
698
  />
699
699
  </template>
700
700
 
701
+ <template #banner>
702
+ <slot
703
+ name="banner"
704
+ />
705
+ </template>
706
+
701
707
 
702
708
  <template
703
709
  v-if="externalPaginationEnabled"
@@ -148,7 +148,8 @@ export default {
148
148
  :to="clusterToolsLink"
149
149
  class="cluster-link"
150
150
  >
151
- {{ t('nav.clusterTools') }}
151
+ <!-- 禅道 3539 隐藏集群工具 -->
152
+ <!-- {{ t('nav.clusterTools') }} -->
152
153
  </router-link>
153
154
  </div>
154
155
  </div>
@@ -97,7 +97,7 @@ export default {
97
97
  <div :style="userLogoSize === 79 ? { width: '287px' } : {}" class="avatar">
98
98
  <img
99
99
  :style="{ width: userLogoSize + 'px', height: userLogoSize + 'px' }"
100
- src="@shell/assets/images/user.png"
100
+ :src="require('@shell/assets/images/user.png')"
101
101
  :class="{'round': principal.roundAvatar}"
102
102
  :alt="t('principal.alt.avatar')"
103
103
  >
@@ -170,7 +170,7 @@ export default {
170
170
  >
171
171
  <template #column-headers>
172
172
  <div class="box mb-0">
173
- <div class="column-headers row" style="width: calc(100% - 100px);">
173
+ <div class="column-headers row" :style="{ width: (isCreate && i === 0) || isView ? '100%' : 'calc(100% - 100px)' }">
174
174
  <div class="col span-6">
175
175
  <label class="text-label">{{ t('membershipEditor.user') }}</label>
176
176
  </div>
@@ -58,6 +58,6 @@ export default {
58
58
  :type="NORMAN.PROJECT_ROLE_TEMPLATE_BINDING"
59
59
  :mode="mode"
60
60
  parent-key="projectId"
61
- :parent-id="parentId"
61
+ :parent-id="parentId"
62
62
  />
63
63
  </template>
@@ -655,7 +655,7 @@ export function init(store) {
655
655
  virtualType({
656
656
  label: store.getters['i18n/t'](`typeLabel.${ VIRTUAL_TYPES.PROJECT_SECRETS }`, { count: 2 }),
657
657
  group: 'storage',
658
- icon: 'globe',
658
+ icon: 'default',
659
659
  namespaced: false,
660
660
  ifRancherCluster: true,
661
661
  name: VIRTUAL_TYPES.PROJECT_SECRETS,
@@ -204,7 +204,7 @@ export default {
204
204
  >
205
205
  <template #title>
206
206
  <h4 class="text-default-text">
207
- {{ t('promptRollback.modalTitle', { workloadName }, true) }}
207
+ {{ t('promptRollback.modalTitle', { workloadName }) }}
208
208
  </h4>
209
209
  </template>
210
210
  <template #body>
@@ -37,15 +37,17 @@ export default {
37
37
 
38
38
  <template>
39
39
  <div>
40
- <Banner
41
- color="info"
42
- :label="t('podSecurityAdmission.banner.modifications')"
43
- />
44
-
45
40
  <ResourceTable
46
41
  :loading="loading"
47
42
  :schema="schema"
48
43
  :rows="rows"
49
- />
44
+ >
45
+ <template #banner>
46
+ <Banner
47
+ color="info"
48
+ :label="t('podSecurityAdmission.banner.modifications')"
49
+ />
50
+ </template>
51
+ </ResourceTable>
50
52
  </div>
51
53
  </template>
@@ -170,6 +170,16 @@ export default {
170
170
  } catch (err) {
171
171
  // This exception handles errors from the `request` action when it receives a failed http request. The `err` object could be from the action's error handler (raw http response object containing `status`) or thrown later on given the response of the action (a massaged object containing `_status`). TBD why one 409 triggers the error handler and another does not.
172
172
  const IS_ERR_409 = err.status === 409 || err._status === 409;
173
+
174
+ const IS_ERR_403 = err.status === 403 || err._status === 403;
175
+
176
+ if (err.message === '' && err.fieldName && err.code) {
177
+ err.message = err.code + ' ' + err.fieldName
178
+ }
179
+
180
+ if (IS_ERR_403) {
181
+ err.message = '权限不足'
182
+ }
173
183
 
174
184
  // Conflict, the resource being edited has changed since starting editing
175
185
  if (IS_ERR_409 && depth === 0 && this.isEdit) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashboard-shell-shell",
3
- "version": "3.0.5-test.41",
3
+ "version": "3.0.5-test.43",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -694,7 +694,8 @@ export default {
694
694
  role="link"
695
695
  :aria-label="t('nav.clusterTools')"
696
696
  >
697
- <span>{{ t('nav.clusterTools') }}</span>
697
+ <!-- 禅道 3539 隐藏集群工具 -->
698
+ <!-- <span>{{ t('nav.clusterTools') }}</span> -->
698
699
  </router-link>
699
700
  </div>
700
701
  <ConfigBadge
@@ -41,6 +41,26 @@ export async function handleSpoofedRequest(rootGetters, schemaStore, opt, produc
41
41
  }
42
42
  }
43
43
 
44
+ export function normalizeSchemaMethods(schema) {
45
+ if (!schema) return schema;
46
+
47
+ const HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
48
+
49
+ if (Array.isArray(schema.resourceMethods)) {
50
+ schema.resourceMethods = schema.resourceMethods.map(m =>
51
+ HTTP_METHODS.includes(m.toLowerCase()) ? m.toUpperCase() : m
52
+ );
53
+ }
54
+
55
+ if (Array.isArray(schema.collectionMethods)) {
56
+ schema.collectionMethods = schema.collectionMethods.map(m =>
57
+ HTTP_METHODS.includes(m.toLowerCase()) ? m.toUpperCase() : m
58
+ );
59
+ }
60
+
61
+ return schema;
62
+ }
63
+
44
64
  export async function loadSchemas(ctx, watch = true) {
45
65
  const {
46
66
  getters, dispatch, commit, rootGetters
@@ -55,6 +75,9 @@ export async function loadSchemas(ctx, watch = true) {
55
75
  }
56
76
 
57
77
  res.data.forEach(addSchemaIndexFields);
78
+
79
+ // ✅ 统一处理 HTTP 方法
80
+ res.data.forEach(normalizeSchemaMethods);
58
81
 
59
82
  commit('loadAll', {
60
83
  ctx,
@@ -83,6 +83,8 @@ export default defineComponent({
83
83
 
84
84
  if (labelStr === 'waiting for api to be available') {
85
85
  labelStr = '等待api可用'
86
+ } else if (labelStr === 'Cluster agent is not connected') {
87
+ labelStr = '集群agent未连接'
86
88
  }
87
89
 
88
90
  return !(typeof labelStr === 'string') ? stringify(labelStr) : undefined;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
3
  # 执行命令示例:
4
- # TAG=shell-pkg-v3.0.5-test.41 ./shell/scripts/publish-shell.sh
4
+ # TAG=shell-pkg-v3.0.5-test.43 ./shell/scripts/publish-shell.sh
5
5
 
6
6
  set -euo pipefail
7
7
 
@@ -2687,6 +2687,7 @@ export default class Ingress {
2687
2687
 
2688
2688
  declare module '@shell/plugins/dashboard-store/actions' {
2689
2689
  export function handleSpoofedRequest(rootGetters: any, schemaStore: any, opt: any, product: any): Promise<any>;
2690
+ export function normalizeSchemaMethods(schema: any): any;
2690
2691
  export function loadSchemas(ctx: any, watch?: boolean): Promise<any>;
2691
2692
  export const _ALL: "all";
2692
2693
  export const _MERGE: "merge";
package/utils/error.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { isArray } from '@shell/utils/array';
2
2
 
3
3
  import translations from './errorTranslate.json';
4
+ import errorTranslateNew from './errorTranslateNew.json';
4
5
 
5
6
  export class ClusterNotFoundError extends Error {
6
7
  static NAME = 'ClusterNotFoundError'
@@ -49,6 +50,9 @@ export class ApiError extends Error {
49
50
  }
50
51
 
51
52
  export function stringify(err) {
53
+
54
+ console.log(err, ' err-------------------------------------------------1')
55
+
52
56
  let str;
53
57
  if ( typeof err === 'string' ) {
54
58
  str = err;
@@ -92,6 +96,8 @@ export function exceptionToErrorsArray(err) {
92
96
  if ( err?.response?.data ) {
93
97
  const body = err.response.data;
94
98
 
99
+ console.log(err, ' err-------------------------------------------------1')
100
+
95
101
  if ( body && body.message ) {
96
102
  return [translateError(body.message)];
97
103
  } else {
@@ -147,7 +153,9 @@ export function translateError(error) {
147
153
  console.log('00044', error);
148
154
 
149
155
 
150
- if (error.includes('spec and status of disks on node') && error.includes('are being syncing and please retry later')) {
156
+ if (error.includes("a lowercase rfc 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character")) {
157
+ error = "无效的名称不符合 RFC 1123 命名规则。名称只能包含小写字母、数字或 '-',并且必须以字母或数字开头和结尾(例如 'my-name' 或 '123-abc')。"
158
+ } else if (error.includes('spec and status of disks on node') && error.includes('are being syncing and please retry later')) {
151
159
  error = error.replace('spec and status of disks on node','').replace('are being syncing and please retry later','')
152
160
  error = '节点' + error + '上的硬盘规格和状态正在同步,请稍后重试'
153
161
  } else if (error.includes('same granularity as schedule') && error.includes('and offset less than')) {
@@ -174,7 +182,7 @@ export function translateError(error) {
174
182
 
175
183
  error = `子网 '${subnetName}' 配置无效:1) 名称禁止以数字开头;2) 排除IP[${idx}] 不能为空且必须是合法 IPv4/IPv6 地址或地址段`;
176
184
  }
177
-
185
+
178
186
  // error = error.replace(/admission webhook(.*?)denied the request:/g, (match, p1) => {
179
187
  // return '';
180
188
  // })
@@ -187,8 +195,9 @@ export function translateError(error) {
187
195
  error = error.substring(errorIndex + 4);
188
196
  }
189
197
 
198
+ const translationsList = [...errorTranslateNew.translations, ...translations.translations]
190
199
 
191
- for (const translation of translations.translations) {
200
+ for (const translation of translationsList) {
192
201
 
193
202
  // if (error.includes(translation.pattern)) {
194
203
  // error = error.replace(translation.pattern, translation.replacement);
@@ -1582,6 +1582,10 @@
1582
1582
  "pattern": "could not",
1583
1583
  "replacement": "无法"
1584
1584
  },
1585
+ {
1586
+ "pattern": "MissingRequired",
1587
+ "replacement": "缺少"
1588
+ },
1585
1589
  {
1586
1590
  "pattern": "cannot",
1587
1591
  "replacement": "不能"
@@ -1742,6 +1746,14 @@
1742
1746
  "pattern": "replicaset",
1743
1747
  "replacement": "副本集"
1744
1748
  },
1749
+ {
1750
+ "pattern": "Cluster",
1751
+ "replacement": "名称"
1752
+ },
1753
+ {
1754
+ "pattern": "name",
1755
+ "replacement": "名称"
1756
+ },
1745
1757
  {
1746
1758
  "pattern": "%",
1747
1759
  "replacement": ""
@@ -0,0 +1,44 @@
1
+ {
2
+ "translations": [
3
+ {
4
+ "pattern": "virtualmachineimages\\.harvesterhci\\.io.*forbidden.*user.*cannot.*(patch|update|create|delete).*resource.*virtualmachineimages.*harvesterhci\\.io.*namespace",
5
+ "replacement": "权限不足",
6
+ "flags": "gi"
7
+ },
8
+ {
9
+ "pattern": "storageclasses\\.storage\\.k8s\\.io.*forbidden.*user.*cannot.*(patch|update|create|delete).*resource.*storageclasses.*storage\\.k8s\\.io.*cluster scope",
10
+ "replacement": "权限不足",
11
+ "flags": "gi"
12
+ },
13
+ {
14
+ "pattern": "Cluster agent is not connected",
15
+ "replacement": "集群agent未连接",
16
+ "flags": "gi"
17
+ },
18
+ {
19
+ "pattern": "waiting for api to be available",
20
+ "replacement": "等待api可用",
21
+ "flags": "gi"
22
+ },
23
+ {
24
+ "pattern": "MissingRequired Cluster name",
25
+ "replacement": "缺少集群名称",
26
+ "flags": "gi"
27
+ },
28
+ {
29
+ "pattern": "users\\.management\\.cattle\\.io.*forbidden.*user.*cannot update resource.*users.*management\\.cattle\\.io.*cluster scope",
30
+ "replacement": "权限不足:当前用户无权修改用户资源。",
31
+ "flags": "gi"
32
+ },
33
+ {
34
+ "pattern": "Cluster agent is not connected",
35
+ "replacement": "集群agent未连接",
36
+ "flags": "gi"
37
+ },
38
+ {
39
+ "pattern": "waiting for api to be available",
40
+ "replacement": "等待api可用",
41
+ "flags": "gi"
42
+ }
43
+ ]
44
+ }