dashboard-shell-shell 3.0.5-test.61 → 3.0.5-test.80

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.
@@ -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>
@@ -524,7 +524,7 @@ export default {
524
524
  <BrandImage
525
525
  data-testid="side-menu__brand-img"
526
526
  :alt="t('nav.alt.mainMenuRancherLogo')"
527
- file-name="logo.png"
527
+ file-name="logo.svg"
528
528
  />
529
529
  </div>
530
530
  </div>
@@ -58,7 +58,7 @@ export function matches(pl) {
58
58
  }
59
59
 
60
60
  export function getVendor() {
61
- return '云翼云管平台';
61
+ return '威努特超融合';
62
62
  }
63
63
  // export function getVendor() {
64
64
  // if ( vendor === SETTING.PL_RANCHER_VALUE ) {
@@ -83,7 +83,7 @@ export function setTitle() {
83
83
  if (v === 'Harvester') {
84
84
  const ico = require(`~shell/assets/images/pl/harvester.png`);
85
85
 
86
- document.title = '云翼云管平台';
86
+ document.title = '威努特超融合';
87
87
  const link = document.createElement('link');
88
88
 
89
89
  link.hid = 'icon';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashboard-shell-shell",
3
- "version": "3.0.5-test.61",
3
+ "version": "3.0.5-test.80",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -311,7 +311,7 @@ export default {
311
311
  this.$store.dispatch('auth/setInitialPass', this.password);
312
312
  this.$router.push({ name: 'auth-setup' });
313
313
  } else {
314
- this.$router.push({ name: 'index' });
314
+ this.$router.push({ name: 'home' });
315
315
  }
316
316
  } catch (err) {
317
317
  // 登录失败处理
@@ -351,7 +351,7 @@ export default {
351
351
  <img
352
352
  src="../../assets/images/login-logo.svg"
353
353
  alt=""
354
- >
354
+ />
355
355
  </div>
356
356
  <div
357
357
  class="login-messages"
@@ -535,7 +535,7 @@ export default {
535
535
  /> -->
536
536
  </div>
537
537
  <div class="copyright">
538
- Copyright 2019-2025 云翼
538
+ Copyright 2019-2025 威努特超融合
539
539
  </div>
540
540
  </div>
541
541
  </div>
package/public/index.html CHANGED
@@ -6,7 +6,7 @@
6
6
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
7
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
8
  <link rel="shortcut icon" type="image/x-icon" href="/favicon.png">
9
- <title>云翼云管平台</title>
9
+ <title>威努特超融合</title>
10
10
  </head>
11
11
 
12
12
  <body>