dashboard-shell-shell 3.0.5-test.58 → 3.0.5-test.59

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.
@@ -6477,6 +6477,7 @@ tableHeaders:
6477
6477
  apikey: API Key
6478
6478
  available: Available
6479
6479
  attachedVM: Attached VM
6480
+ vpc: vpc
6480
6481
 
6481
6482
  authRoles:
6482
6483
  globalDefault: New User Default
@@ -7652,6 +7653,8 @@ typeDescription:
7652
7653
  harvesterhci.io.logging.clusteroutput: 定义集群范围的日志输出目标,例如 Elasticsearch、Loki、S3、Kafka 等。可被多个集群日志配置引用,用于集中存储与分析集群级日志数据。
7653
7654
  harvesterhci.io.logging.flow: 用于配置资源组(命名空间)内的日志采集与流转规则,仅作用于当前资源组内的日志,并将日志转发至对应的资源组日志外发目标,便于分组级的日志管理。
7654
7655
  harvesterhci.io.logging.output: 定义资源组级别的日志输出目标,仅能被同一资源组下的日志配置引用,用于将该资源组内的日志发送至指定的存储或分析系统。
7656
+ kubeovn.io.ovneip: EIP(Elastic IP,弹性公网 IP) 是一种可独立分配、绑定和管理的公网 IPv4 地址资源,使云上实例能够与公网进行双向通信。EIP 具备可移植、可复用和高可用等特性,为云中应用提供灵活的公网访问能力。
7657
+ kubeovn.io.nat: NAT(Network Address Translation,网络地址转换) 是一种让私有子网内的云资源在不暴露自身公网 IP 的情况下访问互联网的网络服务。通过 NAT,实例可以共享统一的公网出口,实现安全、简化的外网访问能力。
7655
7658
  typeLabel:
7656
7659
  management.cattle.io.oidcclient: |-
7657
7660
  {count, plural,
@@ -2182,7 +2182,7 @@ resource:
2182
2182
  update: "更新 {name} 出错"
2183
2183
 
2184
2184
  codeMirror:
2185
- escapeText: 按 Shift+Escape 键从编辑器中模糊
2185
+ escapeText: 按 Shift+Escape 退出编辑状态
2186
2186
  keymap:
2187
2187
  tooltip: 键映射首选项
2188
2188
  indicatorToolip: "按键映射: {name}"
@@ -3509,6 +3509,18 @@ monitoringReceiver:
3509
3509
  opsgenie:
3510
3510
  label: Opsgenie
3511
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: 短信 配置
3512
3524
  pagerduty:
3513
3525
  label: PagerDuty
3514
3526
  title: PagerDuty 配置
@@ -5543,6 +5555,7 @@ tableHeaders:
5543
5555
  apikey: API 密钥
5544
5556
  available: 可用
5545
5557
  attachedVM: 挂载的虚拟机
5558
+ vpc: vpc
5546
5559
 
5547
5560
  authRoles:
5548
5561
  globalDefault: 新用户的默认角色
@@ -6630,7 +6643,7 @@ typeDescription:
6630
6643
  devices.harvesterhci.io.vgpudevice: vGPU(虚拟 GPU,Virtual GPU)是一种通过虚拟化技术将物理 GPU 资源分割、共享给多个虚拟机(VM)或容器的技术,旨在解决物理 GPU 资源利用率低、部署成本高的问题,同时满足多用户对图形渲染、高性能计算(HPC)、AI 加速等场景的需求。
6631
6644
  kubeovn.io.vpc: VPC(Virtual Private Cloud,虚拟私有云)是一种云计算服务模型,允许用户在公有云环境中创建隔离的虚拟网络空间,以实现更高的安全性和灵活性。VPC 使用户能够定义自己的网络拓扑、IP 地址范围、子网、路由表和网络网关等,从而提供类似于传统数据中心的网络控制和配置能力。
6632
6645
  kubeovn.io.subnet: 子网是虚拟私有云(VPC)中的一个逻辑分区,用于将网络划分为更小的、可管理的部分。每个子网都有自己的 IP 地址范围和网络配置,允许用户在 VPC 内创建隔离的网络环境,以满足不同应用或服务的需求。
6633
- kubeovn.io.providernetwork: 物理网络(Provider Network)是指在虚拟私有云(VPC)中,由云服务提供商管理的网络资源。它通常用于连接 VPC 内的虚拟机、容器和其他资源,并提供对外部网络的访问。提供者网络可以包括物理网络设备、虚拟交换机、路由器等,以实现高效、安全的网络通信。
6646
+ kubeovn.io.providernetwork: 公共网络是指在虚拟私有云(VPC)中,由云服务提供商管理的网络资源。它通常用于连接 VPC 内的虚拟机、容器和其他资源,并提供对外部网络的访问。提供者网络可以包括物理网络设备、虚拟交换机、路由器等,以实现高效、安全的网络通信。
6634
6647
  kubeovn.io.vlan: VLAN(Virtual Local Area Network,虚拟局域网)是一种网络技术,用于在物理网络中创建逻辑隔离的子网络。VLAN 允许用户将不同的设备和服务分组到同一虚拟网络中,从而提高网络的安全性、灵活性和可管理性。每个 VLAN 都有一个唯一的标识符(VLAN ID),用于区分不同的虚拟网络。
6635
6648
  management.cattle.io.setting: 统一配置平台基础选项与全局设置,支持CA证书、密码规则、域名、Token时效等核心配置。
6636
6649
  management.cattle.io.user: 用于管理用户账号,支持创建、维护用户信息,可设置用户权限、管理密码等,保障系统资源仅由授权用户访问,提升系统安全性。
@@ -6661,6 +6674,8 @@ typeDescription:
6661
6674
  harvesterhci.io.logging.clusteroutput: 定义集群范围的日志输出目标,例如 Elasticsearch、Loki、S3、Kafka 等。可被多个集群日志配置引用,用于集中存储与分析集群级日志数据。
6662
6675
  harvesterhci.io.logging.flow: 用于配置资源组(命名空间)内的日志采集与流转规则,仅作用于当前资源组内的日志,并将日志转发至对应的资源组日志外发目标,便于分组级的日志管理。
6663
6676
  harvesterhci.io.logging.output: 定义资源组级别的日志输出目标,仅能被同一资源组下的日志配置引用,用于将该资源组内的日志发送至指定的存储或分析系统。
6677
+ kubeovn.io.ovneip: EIP(Elastic IP,弹性公网 IP) 是一种可独立分配、绑定和管理的公网 IPv4 地址资源,使云上实例能够与公网进行双向通信。EIP 具备可移植、可复用和高可用等特性,为云中应用提供灵活的公网访问能力。
6678
+ kubeovn.io.nat: NAT(Network Address Translation,网络地址转换) 是一种让私有子网内的云资源在不暴露自身公网 IP 的情况下访问互联网的网络服务。通过 NAT,实例可以共享统一的公网出口,实现安全、简化的外网访问能力。
6664
6679
  typeLabel:
6665
6680
  management.cattle.io.project: |-
6666
6681
  {count, plural,
@@ -33,6 +33,10 @@ export default {
33
33
  TabTitle
34
34
  },
35
35
  props: {
36
+ actionsPositioning: {
37
+ type: String,
38
+ required: '-48px',
39
+ },
36
40
  resource: {
37
41
  type: String,
38
42
  required: true,
@@ -322,6 +326,7 @@ export default {
322
326
  <div
323
327
  ref="actionsContainer"
324
328
  v-if="!(tabList.includes(_typeDisplay))"
329
+ :style="{ bottom: actionsPositioning ? actionsPositioning : '-48px' }"
325
330
  class="actions-container actions-positioning"
326
331
  style="min-height: 32px;align-self: flex-end;"
327
332
  >
@@ -0,0 +1,649 @@
1
+ <script>
2
+ import { KUBERNETES, PROJECT } from '@shell/config/labels-annotations';
3
+ import { FLEET, NAMESPACE, MANAGEMENT, HELM } from '@shell/config/types';
4
+ import ButtonGroup from '@shell/components/ButtonGroup';
5
+ // import { BadgeState } from '@components/BadgeState';
6
+ import DotState from '@shell/components/DotState.vue';
7
+ import { Banner } from '@components/Banner';
8
+ import { get } from '@shell/utils/object';
9
+ import { NAME as FLEET_NAME } from '@shell/config/product/fleet';
10
+ import { HIDE_SENSITIVE } from '@shell/store/prefs';
11
+ import {
12
+ AS, _DETAIL, _CONFIG, _YAML, MODE, _CREATE, _EDIT, _VIEW, _UNFLAG, _GRAPH
13
+ } from '@shell/config/query-params';
14
+ import { ExtensionPoint, PanelLocation } from '@shell/core/types';
15
+ import ExtensionPanel from '@shell/components/ExtensionPanel';
16
+ import TabTitle from '@shell/components/TabTitle';
17
+ import ActionMenu from '@shell/components/ActionMenuShell.vue';
18
+ import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
19
+ import { useStore } from 'vuex';
20
+
21
+ // i18n-uses resourceDetail.header.*
22
+
23
+ /**
24
+ * Resource Detail Masthead component.
25
+ *
26
+ * ToDo: this component seem to be picking up a lot of logic from special cases, could be simplified down to parameters and then customized per use-case via wrapper component
27
+ */
28
+ export default {
29
+
30
+ name: 'MastheadResourceDetail',
31
+
32
+ components: {
33
+ // BadgeState,
34
+ DotState,
35
+ Banner,
36
+ ButtonGroup,
37
+ ExtensionPanel,
38
+ TabTitle,
39
+ ActionMenu,
40
+ },
41
+ props: {
42
+ value: {
43
+ type: Object,
44
+ default: () => {
45
+ return {};
46
+ }
47
+ },
48
+
49
+ isManuallyHide: {
50
+ type: Boolean,
51
+ default: true
52
+ },
53
+
54
+ mode: {
55
+ type: String,
56
+ default: 'create'
57
+ },
58
+
59
+ realMode: {
60
+ type: String,
61
+ default: 'create'
62
+ },
63
+
64
+ as: {
65
+ type: String,
66
+ default: _YAML,
67
+ },
68
+
69
+ hasGraph: {
70
+ type: Boolean,
71
+ default: false
72
+ },
73
+
74
+ hasDetail: {
75
+ type: Boolean,
76
+ default: false
77
+ },
78
+
79
+ hasEdit: {
80
+ type: Boolean,
81
+ default: false
82
+ },
83
+
84
+ storeOverride: {
85
+ type: String,
86
+ default: null,
87
+ },
88
+
89
+ resource: {
90
+ type: String,
91
+ default: null,
92
+ },
93
+
94
+ resourceSubtype: {
95
+ type: String,
96
+ default: null,
97
+ },
98
+
99
+ parentRouteOverride: {
100
+ type: String,
101
+ default: null,
102
+ },
103
+
104
+ canViewYaml: {
105
+ type: Boolean,
106
+ default: false,
107
+ }
108
+ },
109
+
110
+ setup() {
111
+ const store = useStore();
112
+ const { featureDropdownMenu } = useRuntimeFlag(store);
113
+
114
+ return { featureDropdownMenu };
115
+ },
116
+
117
+ data() {
118
+ return {
119
+ DETAIL_VIEW: _DETAIL,
120
+ extensionType: ExtensionPoint.PANEL,
121
+ extensionLocation: PanelLocation.DETAILS_MASTHEAD,
122
+ Svg: require('~shell/assets/images/API.svg')
123
+ };
124
+ },
125
+
126
+ computed: {
127
+ dev() {
128
+ return this.$store.getters['prefs/dev'];
129
+ },
130
+
131
+ schema() {
132
+ const inStore = this.storeOverride || this.$store.getters['currentStore'](this.resource);
133
+
134
+ return this.$store.getters[`${ inStore }/schemaFor`]( this.resource );
135
+ },
136
+
137
+ isView() {
138
+ return this.mode === _VIEW;
139
+ },
140
+
141
+ isEdit() {
142
+ return this.mode === _EDIT;
143
+ },
144
+
145
+ isCreate() {
146
+ return this.mode === _CREATE;
147
+ },
148
+
149
+ isNamespace() {
150
+ return this.schema?.id === NAMESPACE;
151
+ },
152
+
153
+ isProject() {
154
+ return this.schema?.id === MANAGEMENT.PROJECT;
155
+ },
156
+
157
+ isProjectHelmChart() {
158
+ return this.schema?.id === HELM.PROJECTHELMCHART;
159
+ },
160
+
161
+ hasMultipleNamespaces() {
162
+ return !!this.value.namespaces;
163
+ },
164
+
165
+ namespace() {
166
+ if (this.value?.metadata?.namespace) {
167
+ return this.value?.metadata?.namespace;
168
+ }
169
+
170
+ return null;
171
+ },
172
+
173
+ detailsAction() {
174
+ return this.value?.detailsAction;
175
+ },
176
+
177
+ shouldHifenize() {
178
+ return (this.mode === 'view' || this.mode === 'edit') && this.resourceSubtype?.length && this.value?.nameDisplay?.length;
179
+ },
180
+
181
+ namespaceLocation() {
182
+ if (!this.isNamespace) {
183
+ return this.value.namespaceLocation || {
184
+ name: 'c-cluster-product-resource-id',
185
+ params: {
186
+ cluster: this.$route.params.cluster,
187
+ product: this.$store.getters['productId'],
188
+ resource: NAMESPACE,
189
+ id: this.$route.params.namespace
190
+ }
191
+ };
192
+ }
193
+
194
+ return null;
195
+ },
196
+
197
+ isWorkspace() {
198
+ return this.$store.getters['productId'] === FLEET_NAME && !!this.value?.metadata?.namespace;
199
+ },
200
+
201
+ workspaceLocation() {
202
+ return {
203
+ name: 'c-cluster-product-resource-id',
204
+ params: {
205
+ cluster: this.$route.params.cluster,
206
+ product: this.$store.getters['productId'],
207
+ resource: FLEET.WORKSPACE,
208
+ id: this.$route.params.namespace
209
+ }
210
+ };
211
+ },
212
+
213
+ project() {
214
+ if (this.isNamespace) {
215
+ const cluster = this.$store.getters['currentCluster'];
216
+
217
+ if (cluster) {
218
+ const id = (this.value?.metadata?.labels || {})[PROJECT];
219
+
220
+ return this.$store.getters['management/byId'](MANAGEMENT.PROJECT, `${ cluster.id }/${ id }`);
221
+ }
222
+ }
223
+
224
+ return null;
225
+ },
226
+
227
+ banner() {
228
+ if (this.value?.stateObj?.error) {
229
+ const defaultErrorMessage = this.t('resourceDetail.masthead.defaultBannerMessage.error', undefined, true);
230
+
231
+ return {
232
+ color: 'error',
233
+ message: this.value.stateObj.message || defaultErrorMessage
234
+ };
235
+ }
236
+
237
+ if (this.value?.spec?.paused) {
238
+ return {
239
+ color: 'info',
240
+ message: this.t('asyncButton.pause.description')
241
+ };
242
+ }
243
+
244
+ if (this.value?.stateObj?.transitioning) {
245
+ const defaultTransitioningMessage = this.t('resourceDetail.masthead.defaultBannerMessage.transitioning', undefined, true);
246
+
247
+ return {
248
+ color: 'info',
249
+ message: this.value.stateObj.message || defaultTransitioningMessage
250
+ };
251
+ }
252
+
253
+ return null;
254
+ },
255
+
256
+ parent() {
257
+ let displayName = this.value?.parentNameOverride || this.$store.getters['type-map/labelFor'](this.schema);
258
+ const product = this.$store.getters['currentProduct'].name;
259
+
260
+ const defaultLocation = {
261
+ name: 'c-cluster-product-resource',
262
+ params: {
263
+ resource: this.resource,
264
+ product,
265
+ }
266
+ };
267
+
268
+ const location = this.value?.parentLocationOverride || defaultLocation;
269
+
270
+ if (this.parentRouteOverride) {
271
+ location.name = this.parentRouteOverride;
272
+ }
273
+
274
+ const typeOptions = this.$store.getters[`type-map/optionsFor`]( this.resource );
275
+
276
+ // 转换为中文
277
+ const displayName_zh_hans = {
278
+ 'GlobalRole': '全局角色',
279
+ 'RoleTemplate': '集群角色',
280
+ }
281
+ if (displayName_zh_hans[displayName]) {
282
+ displayName = displayName_zh_hans[displayName]
283
+ }
284
+
285
+ if (displayName == '集群角色' && (this.$route.query?.roleContext == 'NAMESPACE' || location.hash == '#NAMESPACE')) {
286
+ displayName = '项目或资源组角色'
287
+ }
288
+
289
+ const out = {
290
+ displayName, location, ...typeOptions
291
+ };
292
+
293
+ return out;
294
+ },
295
+
296
+ hideSensitiveData() {
297
+ return this.$store.getters['prefs/get'](HIDE_SENSITIVE);
298
+ },
299
+
300
+ sensitiveOptions() {
301
+ return [
302
+ {
303
+ tooltipKey: 'resourceDetail.masthead.sensitive.hide',
304
+ icon: 'icon-hide',
305
+ value: true,
306
+ },
307
+ {
308
+ tooltipKey: 'resourceDetail.masthead.sensitive.show',
309
+ icon: 'icon-show',
310
+ value: false
311
+ }
312
+ ];
313
+ },
314
+
315
+ viewOptions() {
316
+ const out = [];
317
+
318
+ if ( this.hasDetail ) {
319
+ out.push({
320
+ labelKey: 'resourceDetail.masthead.detail',
321
+ value: _DETAIL,
322
+ });
323
+ }
324
+
325
+ if ( this.hasEdit && this.parent?.showConfigView !== false) {
326
+ out.push({
327
+ labelKey: 'resourceDetail.masthead.config',
328
+ value: _CONFIG,
329
+ });
330
+ }
331
+
332
+ if ( this.hasGraph ) {
333
+ out.push({
334
+ labelKey: 'resourceDetail.masthead.graph',
335
+ value: _GRAPH,
336
+ });
337
+ }
338
+
339
+ // if ( this.canViewYaml ) {
340
+ // out.push({
341
+ // labelKey: 'resourceDetail.masthead.yaml',
342
+ // value: _YAML,
343
+ // });
344
+ // }
345
+
346
+ if ( out.length < 2 ) {
347
+ return null;
348
+ }
349
+
350
+ return out;
351
+ },
352
+
353
+ currentView: {
354
+ get() {
355
+ return this.as;
356
+ },
357
+
358
+ set(val) {
359
+ switch ( val ) {
360
+ case _DETAIL:
361
+ this.$router.applyQuery({
362
+ [MODE]: _UNFLAG,
363
+ [AS]: _UNFLAG,
364
+ });
365
+ break;
366
+ case _CONFIG:
367
+ this.$router.applyQuery({
368
+ [MODE]: _UNFLAG,
369
+ [AS]: _CONFIG,
370
+ });
371
+ break;
372
+ case _GRAPH:
373
+ this.$router.applyQuery({
374
+ [MODE]: _UNFLAG,
375
+ [AS]: _GRAPH,
376
+ });
377
+ break;
378
+ case _YAML:
379
+ this.$router.applyQuery({
380
+ [MODE]: _UNFLAG,
381
+ [AS]: _YAML,
382
+ });
383
+ break;
384
+ }
385
+ },
386
+ },
387
+
388
+ showSensitiveToggle() {
389
+ return !!this.value.hasSensitiveData && this.mode === _VIEW && this.as !== _YAML;
390
+ },
391
+
392
+ managedWarning() {
393
+ const { value } = this;
394
+ const labels = value?.metadata?.labels || {};
395
+
396
+ const managedBy = labels[KUBERNETES.MANAGED_BY] || '';
397
+ const appName = labels[KUBERNETES.MANAGED_NAME] || labels[KUBERNETES.INSTANCE] || '';
398
+
399
+ return {
400
+ show: this.mode === _EDIT && !!managedBy,
401
+ type: value?.kind || '',
402
+ hasName: appName ? 'yes' : 'no',
403
+ appName,
404
+ managedBy,
405
+ };
406
+ },
407
+
408
+ displayName() {
409
+ let displayName = this.value.nameDisplay;
410
+
411
+ if (this.isProjectHelmChart) {
412
+ displayName = this.value.projectDisplayName;
413
+ }
414
+
415
+ return this.shouldHifenize ? ` - ${ displayName }` : displayName;
416
+ },
417
+
418
+ demoDisplay() {
419
+ const product = this.$store.getters['productId'];
420
+
421
+ const resources = this.location?.params?.resource || this.$route.params?.resource || ''
422
+
423
+ const productId = this.$store.getters['type-map/groupForBasicType'](this.$store.getters['productId'], resources);
424
+
425
+ if (productId === undefined) {
426
+ return '';
427
+ }
428
+ const parts = productId?.split('::') || [];
429
+ const newString = 'root';
430
+
431
+ if (!parts?.includes(newString)) {
432
+ parts.unshift(newString); // 将字符串添加到数组第一位
433
+ }
434
+
435
+ const partsEn = parts.map((item) => {
436
+ return this.$store.getters['i18n/t'](`typeLabel."${ item.toLowerCase() }"`);
437
+ });
438
+
439
+ return partsEn;
440
+ },
441
+ menuIcon() {
442
+ const product = this.$store.getters['productId'];
443
+
444
+ const resources = this.location?.params?.resource || this.$route.params?.resource || ''
445
+
446
+
447
+ return this.$store.getters['type-map/groupsForVirTypes'](product, resources) || 'default menuIcon';
448
+ },
449
+
450
+ location() {
451
+ const { parent } = this;
452
+
453
+ return parent?.location;
454
+ },
455
+
456
+ hideNamespaceLocation() {
457
+ return this.$store.getters['currentProduct'].hideNamespaceLocation || this.value.namespaceLocation === null;
458
+ },
459
+
460
+ resourceExternalLink() {
461
+ return this.value.resourceExternalLink;
462
+ },
463
+ },
464
+
465
+ methods: {
466
+ get,
467
+
468
+ showActions() {
469
+ this.$store.commit('action-menu/show', {
470
+ resources: this.value,
471
+ elem: this.$refs.actions,
472
+ });
473
+ },
474
+
475
+ toggleSensitiveData(e) {
476
+ this.$store.dispatch('prefs/set', { key: HIDE_SENSITIVE, value: !!e });
477
+ },
478
+
479
+ invokeDetailsAction() {
480
+ const action = this.detailsAction;
481
+
482
+ if (action) {
483
+ const fn = this.value[action.action];
484
+
485
+ if (fn) {
486
+ fn.apply(this.value, []);
487
+ }
488
+ }
489
+ }
490
+ }
491
+ };
492
+ </script>
493
+
494
+ <template>
495
+ <div class="actions">
496
+ <button
497
+ v-if="detailsAction && currentView === DETAIL_VIEW && isView"
498
+ type="button"
499
+ class="btn role-primary actions mr-10"
500
+ :disabled="!detailsAction.enabled"
501
+ @click="invokeDetailsAction"
502
+ >
503
+ {{ detailsAction.label }}
504
+ </button>
505
+ <ButtonGroup
506
+ v-if="showSensitiveToggle"
507
+ :value="!!hideSensitiveData"
508
+ icon-size="lg"
509
+ :options="sensitiveOptions"
510
+ class="mr-10"
511
+ @update:value="toggleSensitiveData"
512
+ />
513
+ <ButtonGroup
514
+ v-if="viewOptions && isView"
515
+ v-model:value="currentView"
516
+ :options="viewOptions"
517
+ class="mr-10"
518
+ />
519
+ <template v-if="featureDropdownMenu">
520
+ <ActionMenu
521
+ v-if="isView"
522
+ button-role="multiAction"
523
+ button-size="compact"
524
+ :resource="value"
525
+ data-testid="masthead-action-menu"
526
+ />
527
+ </template>
528
+ <template v-else>
529
+ <button
530
+ v-if="isView"
531
+ ref="actions"
532
+ data-testid="masthead-action-menu"
533
+ aria-haspopup="true"
534
+ type="button"
535
+ class="btn role-multi-action actions"
536
+ @click="showActions"
537
+ >
538
+ <i class="icon icon-actions" />
539
+ </button>
540
+ </template>
541
+ </div>
542
+ </template>
543
+
544
+ <style lang='scss' scoped>
545
+ .masthead {
546
+ padding-bottom: 10px;
547
+ /* border-bottom: 1px solid var(--border); */
548
+ margin-bottom: 10px;
549
+ }
550
+
551
+ HEADER {
552
+ margin: 0;
553
+ }
554
+
555
+ .primaryheader {
556
+ display: flex;
557
+ flex-direction: row;
558
+ align-items: center;
559
+ font-size:14px;
560
+ height: 50px;
561
+
562
+ h1 {
563
+ margin: 0;
564
+ }
565
+ }
566
+
567
+ .subheader{
568
+ display: flex;
569
+ flex-direction: row;
570
+ color: var(--input-label);
571
+ & > * {
572
+ margin: 5px 20px 5px 0px;
573
+ }
574
+
575
+ .live-data {
576
+ color: var(--body-text)
577
+ }
578
+ }
579
+
580
+ .state-banner {
581
+ margin: 3px 0 0 0;
582
+ }
583
+
584
+ .masthead-state {
585
+ font-size: initial;
586
+ display: inline-block;
587
+ position: relative;
588
+ /* top: -2px; */
589
+ font-size: 12px;
590
+ margin-left: 5px;
591
+ }
592
+
593
+ .masthead-istio {
594
+ .icon {
595
+ vertical-align: middle;
596
+ color: var(--primary);
597
+ }
598
+ }
599
+
600
+ .left-right-split {
601
+ display: grid;
602
+ align-items: center;
603
+
604
+ .left-half {
605
+ grid-column: 1;
606
+ }
607
+
608
+ .right-half {
609
+ grid-column: 2;
610
+ }
611
+ }
612
+
613
+ .resource-external {
614
+ font-size: 18px;
615
+ }
616
+ .excram-list{
617
+ font-size: 14px;
618
+ margin-bottom: 20px;
619
+ }
620
+ .excram-last-name{
621
+ color: var(--link);
622
+ }
623
+ .valid{
624
+ color: #d7d7d7;
625
+ margin: 0px 10px;
626
+ }
627
+ .detailIcon-span{
628
+ width: 24px;
629
+ height: 24px;
630
+ display: inline-block;
631
+ position: relative;
632
+ background: var(--primary);
633
+ margin-right: 10px;
634
+ }
635
+ .detailIcon{
636
+ position: absolute;
637
+ color: #fff;
638
+ font-size: 38px;
639
+ left: 4px;
640
+ top: -2px;
641
+ }
642
+ .primary-title{
643
+ display: flex;
644
+ align-items: center;
645
+ }
646
+ .detailIcon-span-title{
647
+ font-weight: bold;
648
+ }
649
+ </style>
@@ -176,7 +176,7 @@ export default {
176
176
  componentTestid: {
177
177
  type: String,
178
178
  default: 'name-ns-description'
179
- }
179
+ },
180
180
  },
181
181
 
182
182
  data() {
@@ -17,14 +17,38 @@ import { fetchAlertManagerConfigSpecs } from '@shell/utils/alertmanagerconfig';
17
17
  // i18n-uses monitoringReceiver.slack.*, monitoringReceiver.email.*, monitoringReceiver.pagerduty.*
18
18
  // i18n-uses monitoringReceiver.opsgenie.*, monitoringReceiver.webhook.*, monitoringReceiver.custom.*
19
19
  export const RECEIVERS_TYPES = [
20
- // {
21
- // name: 'slack',
22
- // label: 'monitoringReceiver.slack.label',
23
- // title: 'monitoringReceiver.slack.title',
24
- // info: 'monitoringReceiver.slack.info',
25
- // key: 'slackConfigs',
26
- // logo: require(`@shell/assets/images/vendor/slack.svg`)
27
- // },
20
+ {
21
+ name: 'message',
22
+ label: 'monitoringReceiver.message.label',
23
+ title: 'monitoringReceiver.message.title',
24
+ info: 'monitoringReceiver.slack.info',
25
+ key: 'slackConfigs',
26
+ logo: require(`@shell/assets/images/vendor/slack.svg`)
27
+ },
28
+ {
29
+ name: 'dingding',
30
+ label: 'monitoringReceiver.dingding.label',
31
+ title: 'monitoringReceiver.dingding.title',
32
+ info: 'monitoringReceiver.slack.info',
33
+ key: 'dingding',
34
+ logo: require(`@shell/assets/images/vendor/slack.svg`)
35
+ },
36
+ {
37
+ name: 'work',
38
+ label: 'monitoringReceiver.weixin.label',
39
+ title: 'monitoringReceiver.weixin.title',
40
+ info: 'monitoringReceiver.slack.info',
41
+ key: 'work',
42
+ logo: require(`@shell/assets/images/vendor/slack.svg`)
43
+ },
44
+ {
45
+ name: 'snmp',
46
+ label: 'monitoringReceiver.snmp.label',
47
+ title: 'monitoringReceiver.snmp.title',
48
+ info: 'monitoringReceiver.slack.info',
49
+ key: 'snmp',
50
+ logo: require(`@shell/assets/images/vendor/slack.svg`)
51
+ },
28
52
  {
29
53
  name: 'email',
30
54
  label: 'monitoringReceiver.email.label',
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div>
3
+ <div class="mb-20">
4
+ <LabeledInput
5
+ v-model:value="message"
6
+ :placeholder="'webhook地址'"
7
+ :label="'webhook地址'"
8
+ />
9
+ </div>
10
+ <div class="mb-20">
11
+ <LabeledInput
12
+ v-model:value="id"
13
+ :placeholder="'签名密钥'"
14
+ :label="'签名密钥'"
15
+ />
16
+ </div>
17
+ </div>
18
+ </template>
19
+ <script>
20
+ import { LabeledInput } from '@components/Form/LabeledInput';
21
+ export default {
22
+ components: { LabeledInput },
23
+ data() {
24
+ return {
25
+ message: '',
26
+ id: '',
27
+ scret: '',
28
+ templateId: ''
29
+ };
30
+ }
31
+ };
32
+ </script>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div>
3
+ <div class="mb-20">
4
+ <LabeledInput
5
+ v-model:value="message"
6
+ :placeholder="'请输入手机号'"
7
+ :label="'默认手机人电话'"
8
+ />
9
+ </div>
10
+ <div class="mb-20">
11
+ <LabeledInput
12
+ v-model:value="id"
13
+ :placeholder="'API密钥ID'"
14
+ :label="'默认API密钥ID'"
15
+ />
16
+ </div>
17
+ <div class="mb-20">
18
+ <LabeledInput
19
+ v-model:value="scret"
20
+ :placeholder="'API密钥secret'"
21
+ :label="'默认API密钥secret'"
22
+ />
23
+ </div>
24
+ <div class="mb-20">
25
+ <LabeledInput
26
+ v-model:value="templateId"
27
+ :placeholder="'请输入模板ID'"
28
+ :label="'模板ID'"
29
+ />
30
+ </div>
31
+ </div>
32
+ </template>
33
+ <script>
34
+ import { LabeledInput } from '@components/Form/LabeledInput';
35
+ // import { ref } from 'vue';
36
+ // const id = ref('');
37
+ // const scret = ref('');
38
+ // const message = ref('');
39
+ // const templateId = ref('');
40
+
41
+ export default {
42
+ components: { LabeledInput },
43
+ data() {
44
+ return {
45
+ message: '',
46
+ id: '',
47
+ scret: '',
48
+ templateId: ''
49
+ };
50
+ }
51
+ };
52
+ </script>
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <div>
3
+ <div class="mb-20">
4
+ <LabeledInput
5
+ v-model:value="message"
6
+ :placeholder="'目标主机'"
7
+ :label="'目标主机'"
8
+ />
9
+ </div>
10
+ <div class="mb-20">
11
+ <LabeledInput
12
+ v-model:value="id"
13
+ :placeholder="'端口'"
14
+ :label="'端口'"
15
+ />
16
+ </div>
17
+ <div class="mb-20">
18
+ <LabeledInput
19
+ v-model:value="scret"
20
+ :placeholder="'团体字'"
21
+ :label="'团体字'"
22
+ />
23
+ </div>
24
+ </div>
25
+ </template>
26
+ <script>
27
+ import { LabeledInput } from '@components/Form/LabeledInput';
28
+ // import { ref } from 'vue';
29
+ // const id = ref('');
30
+ // const scret = ref('');
31
+ // const message = ref('');
32
+ // const templateId = ref('');
33
+
34
+ export default {
35
+ components: { LabeledInput },
36
+ data() {
37
+ return {
38
+ message: '',
39
+ id: '',
40
+ scret: '',
41
+ templateId: ''
42
+ };
43
+ }
44
+ };
45
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div>
3
+ <div class="mb-20">
4
+ <LabeledInput
5
+ v-model:value="message"
6
+ :placeholder="'webhook地址'"
7
+ :label="'webhook地址'"
8
+ />
9
+ </div>
10
+ </div>
11
+ </template>
12
+ <script>
13
+ import { LabeledInput } from '@components/Form/LabeledInput';
14
+ // import { ref } from 'vue';
15
+ // const id = ref('');
16
+ // const scret = ref('');
17
+ // const message = ref('');
18
+ // const templateId = ref('');
19
+
20
+ export default {
21
+ components: { LabeledInput },
22
+ data() {
23
+ return {
24
+ message: '',
25
+ id: '',
26
+ scret: '',
27
+ templateId: ''
28
+ };
29
+ }
30
+ };
31
+ </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashboard-shell-shell",
3
- "version": "3.0.5-test.58",
3
+ "version": "3.0.5-test.59",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
3
  # 执行命令示例:
4
- # TAG=shell-pkg-v3.0.5-test.58 ./shell/scripts/publish-shell.sh
4
+ # TAG=shell-pkg-v3.0.5-test.59 ./shell/scripts/publish-shell.sh
5
5
 
6
6
  set -euo pipefail
7
7
 
package/store/index.js CHANGED
@@ -519,10 +519,10 @@ export const getters = {
519
519
  (!isAll && filteredMap && filteredMap[out] );
520
520
  }
521
521
 
522
- out = rootGetters['prefs/get'](LAST_NAMESPACE);
523
- if ( isOk() ) {
524
- return out;
525
- }
522
+ // out = rootGetters['prefs/get'](LAST_NAMESPACE);
523
+ // if ( isOk() ) {
524
+ // return out;
525
+ // }
526
526
 
527
527
  out = 'default';
528
528
  if ( isOk() ) {
@@ -1,5 +1,10 @@
1
1
  {
2
2
  "translations": [
3
+ {
4
+ "pattern": "the status of pod readiness gate &quot;kubevirt\\.io/virtual-machine-unpaused&quot; is not &quot;true&quot;, but false",
5
+ "replacement": "这个只有当虚拟机处于运行状态(非暂停)时,才能进行暂停操作",
6
+ "flags": "gi"
7
+ },
3
8
  {
4
9
  "pattern": "can't delete vlanconfig (\\S+) because the storage network nad (\\S+) is still attached",
5
10
  "replacement": "无法删除 VLAN 配置 '$1':存储网络附加定义 '$2' 仍在使用",