dashboard-shell-shell 3.0.5-test.3 → 3.0.5-test.4
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.
- package/components/ResourceDetail/Masthead/legacy.vue +235 -164
- package/components/ResourceDetail/legacy.vue +30 -16
- package/components/auth/Principal.vue +37 -13
- package/package.json +1 -1
- package/pages/account/index.vue +13 -5
- package/pages/auth/login.vue +1 -6
- package/pages/c/_cluster/_product/namespaces.vue +1 -1
- package/pages/account/pri.vue +0 -229
|
@@ -254,7 +254,7 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
|
|
256
256
|
parent() {
|
|
257
|
-
|
|
257
|
+
const displayName = this.value?.parentNameOverride || this.$store.getters['type-map/labelFor'](this.schema);
|
|
258
258
|
const product = this.$store.getters['currentProduct'].name;
|
|
259
259
|
|
|
260
260
|
const defaultLocation = {
|
|
@@ -491,192 +491,263 @@ export default {
|
|
|
491
491
|
</script>
|
|
492
492
|
|
|
493
493
|
<template>
|
|
494
|
-
|
|
495
|
-
<!-- 顶部区域的容器 -->
|
|
496
494
|
<div class="masthead">
|
|
497
495
|
<div class="title">
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
<!-- <div
|
|
496
|
+
<!-- 创建api密钥不需要面包屑 -->
|
|
497
|
+
<div
|
|
501
498
|
v-if="!(parentRouteOverride === 'account' && resource=== 'token')"
|
|
502
499
|
class="excram-list"
|
|
503
500
|
>
|
|
504
|
-
|
|
505
|
-
遍历 demoDisplay 生成面包屑路径
|
|
506
501
|
<span
|
|
507
502
|
v-for="(item,index) in demoDisplay"
|
|
508
503
|
:key="index"
|
|
509
504
|
>
|
|
510
|
-
<span
|
|
511
|
-
<span
|
|
505
|
+
<span>{{ item }}</span>
|
|
506
|
+
<span>/</span>
|
|
512
507
|
</span>
|
|
513
|
-
|
|
514
|
-
最后一个面包屑显示当前操作(查看/编辑/创建)+ 父资源名称
|
|
515
508
|
<span class="excram-last-name">
|
|
516
509
|
{{ (realMode === 'view'? '查看': realMode === 'edit' ? '编辑':'创建') + parent.displayName }}
|
|
517
510
|
</span>
|
|
518
|
-
</div>
|
|
519
|
-
|
|
520
|
-
<
|
|
521
|
-
<div class="
|
|
522
|
-
<
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
v-else
|
|
535
|
-
:class="'icon-'+ menuIcon + ' detailIcon'"
|
|
536
|
-
/>
|
|
537
|
-
</span>
|
|
538
|
-
|
|
539
|
-
<!-- 资源标题(创建时只显示“创建+名称”,否则显示“名称:”) -->
|
|
540
|
-
<span class="detailIcon-span-title">{{ realMode=== 'create'? '创建': '' }}{{ parent.displayName }}{{ realMode=== 'create'? '': '名称:' }}</span>
|
|
541
|
-
|
|
542
|
-
<!-- 如果不是创建模式,显示操作描述 -->
|
|
543
|
-
<span v-if="realMode !== 'create'">
|
|
544
|
-
|
|
545
|
-
<!-- 如果有覆盖方法,优先显示覆盖内容 -->
|
|
546
|
-
<span v-if="value.detailPageHeaderActionOverride && value.detailPageHeaderActionOverride(realMode)">{{ value.detailPageHeaderActionOverride(realMode) }}</span>
|
|
547
|
-
|
|
548
|
-
<!-- 否则用 t 组件国际化显示 -->
|
|
549
|
-
<t
|
|
550
|
-
v-else
|
|
551
|
-
:k="'resourceDetail.header.' + realMode"
|
|
552
|
-
:subtype="resourceSubtype"
|
|
553
|
-
:name="displayName"
|
|
554
|
-
:escapehtml="false"
|
|
555
|
-
/>
|
|
556
|
-
</span>
|
|
557
|
-
|
|
558
|
-
<!-- 状态点(DotState 组件) -->
|
|
559
|
-
<DotState
|
|
560
|
-
v-if="!isCreate && parent.showState"
|
|
561
|
-
class="masthead-state"
|
|
562
|
-
:value="value"
|
|
563
|
-
/>
|
|
564
|
-
|
|
565
|
-
<!-- Istio 注入状态 -->
|
|
566
|
-
<span
|
|
567
|
-
v-if="!isCreate && value.injectionEnabled"
|
|
568
|
-
class="masthead-istio"
|
|
511
|
+
</div>
|
|
512
|
+
<header>
|
|
513
|
+
<div class="title">
|
|
514
|
+
<div class="primaryheader">
|
|
515
|
+
<span class="primary-title">
|
|
516
|
+
<!-- <nuxt-link
|
|
517
|
+
v-if="location"
|
|
518
|
+
:to="location"
|
|
519
|
+
>
|
|
520
|
+
{{ parent.displayName }}:
|
|
521
|
+
</nuxt-link> -->
|
|
522
|
+
<span class="detailIcon-span">
|
|
523
|
+
<img
|
|
524
|
+
v-if="parentRouteOverride === 'account' && resource=== 'token'"
|
|
525
|
+
:src="Svg"
|
|
526
|
+
style="margin-top: 4px; margin-left: 5px;"
|
|
569
527
|
>
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
</span>
|
|
528
|
+
<i
|
|
529
|
+
v-else
|
|
530
|
+
:class="'icon-'+ menuIcon + ' detailIcon'"
|
|
531
|
+
/>
|
|
575
532
|
</span>
|
|
576
|
-
|
|
577
|
-
|
|
533
|
+
<span class="detailIcon-span-title">{{ realMode=== 'create'? '创建': '' }}{{ parent.displayName }}{{ realMode=== 'create'? '': '名称:' }}</span>
|
|
534
|
+
<span v-if="realMode !== 'create'">
|
|
535
|
+
<span v-if="value.detailPageHeaderActionOverride && value.detailPageHeaderActionOverride(realMode)">{{ value.detailPageHeaderActionOverride(realMode) }}</span>
|
|
536
|
+
<t
|
|
537
|
+
v-else
|
|
538
|
+
:k="'resourceDetail.header.' + realMode"
|
|
539
|
+
:subtype="resourceSubtype"
|
|
540
|
+
:name="displayName"
|
|
541
|
+
:escapehtml="false"
|
|
542
|
+
/>
|
|
543
|
+
</span>
|
|
544
|
+
<DotState
|
|
545
|
+
v-if="!isCreate && parent.showState"
|
|
546
|
+
class="masthead-state"
|
|
547
|
+
:value="value"
|
|
548
|
+
/>
|
|
578
549
|
<span
|
|
579
|
-
v-if="
|
|
580
|
-
class="
|
|
581
|
-
>|</span>
|
|
582
|
-
<router-link
|
|
583
|
-
v-if="location"
|
|
584
|
-
:to="location"
|
|
550
|
+
v-if="!isCreate && value.injectionEnabled"
|
|
551
|
+
class="masthead-istio"
|
|
585
552
|
>
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
553
|
+
<i
|
|
554
|
+
v-clean-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
|
|
555
|
+
class="icon icon-sm icon-istio"
|
|
556
|
+
/>
|
|
557
|
+
</span>
|
|
558
|
+
</span>
|
|
559
|
+
<span
|
|
560
|
+
v-if="location"
|
|
561
|
+
class="valid"
|
|
562
|
+
>|</span>
|
|
563
|
+
<router-link
|
|
564
|
+
v-if="location"
|
|
565
|
+
:to="location"
|
|
566
|
+
>
|
|
567
|
+
返回
|
|
568
|
+
</router-link>
|
|
569
|
+
<!-- <h1>
|
|
570
|
+
<TabTitle
|
|
571
|
+
v-if="isCreate"
|
|
572
|
+
:showChild="false"
|
|
573
|
+
>
|
|
574
|
+
{{ parent.displayName }}
|
|
575
|
+
</TabTitle>
|
|
576
|
+
<TabTitle
|
|
577
|
+
v-else
|
|
578
|
+
:showChild="false"
|
|
579
|
+
>
|
|
580
|
+
{{ displayName }}
|
|
581
|
+
</TabTitle>
|
|
582
|
+
<router-link
|
|
583
|
+
v-if="location"
|
|
584
|
+
:to="location"
|
|
585
|
+
role="link"
|
|
586
|
+
class="masthead-resource-list-link"
|
|
587
|
+
:aria-label="parent.displayName"
|
|
588
|
+
>
|
|
589
|
+
{{ parent.displayName }}:
|
|
590
|
+
</router-link>
|
|
591
|
+
<span v-else>{{ parent.displayName }}:</span>
|
|
592
|
+
<span v-if="value?.detailPageHeaderActionOverride && value?.detailPageHeaderActionOverride(realMode)">{{ value?.detailPageHeaderActionOverride(realMode) }}</span>
|
|
593
|
+
<t
|
|
594
|
+
v-else
|
|
595
|
+
class="masthead-resource-title"
|
|
596
|
+
:k="'resourceDetail.header.' + realMode"
|
|
597
|
+
:subtype="resourceSubtype"
|
|
598
|
+
:name="displayName"
|
|
599
|
+
:escapehtml="false"
|
|
600
|
+
/>
|
|
601
|
+
<BadgeState
|
|
602
|
+
v-if="!isCreate && parent.showState"
|
|
603
|
+
class="masthead-state"
|
|
604
|
+
:value="value"
|
|
605
|
+
/>
|
|
606
|
+
<span
|
|
607
|
+
v-if="!isCreate && value.injectionEnabled"
|
|
608
|
+
class="masthead-istio"
|
|
609
|
+
>
|
|
610
|
+
<i
|
|
611
|
+
v-clean-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
|
|
612
|
+
class="icon icon-sm icon-istio"
|
|
613
|
+
/>
|
|
614
|
+
</span>
|
|
615
|
+
<a
|
|
616
|
+
v-if="dev && !!resourceExternalLink"
|
|
617
|
+
v-clean-tooltip="t(resourceExternalLink.tipsKey || 'generic.resourceExternalLinkTips')"
|
|
618
|
+
class="resource-external"
|
|
619
|
+
rel="nofollow noopener noreferrer"
|
|
620
|
+
target="_blank"
|
|
621
|
+
:href="resourceExternalLink.url"
|
|
622
|
+
>
|
|
623
|
+
<i class="icon icon-external-link" />
|
|
624
|
+
</a>
|
|
625
|
+
</h1> -->
|
|
589
626
|
</div>
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
627
|
+
<!-- <div
|
|
628
|
+
v-if="!isCreate"
|
|
629
|
+
class="subheader"
|
|
630
|
+
>
|
|
631
|
+
<span v-if="isNamespace && project">{{ t("resourceDetail.masthead.project") }}: <router-link :to="project.detailLocation">{{ project.nameDisplay }}</router-link></span>
|
|
632
|
+
<span v-else-if="isWorkspace">{{ t("resourceDetail.masthead.workspace") }}: <router-link :to="workspaceLocation">{{ namespace }}</router-link></span>
|
|
633
|
+
<span v-else-if="namespace && !hasMultipleNamespaces">
|
|
634
|
+
{{ t("resourceDetail.masthead.namespace") }}:
|
|
635
|
+
<router-link
|
|
636
|
+
v-if="!hideNamespaceLocation"
|
|
637
|
+
:to="namespaceLocation"
|
|
638
|
+
data-testid="masthead-subheader-namespace"
|
|
639
|
+
>
|
|
640
|
+
{{ namespace }}
|
|
641
|
+
</router-link>
|
|
642
|
+
<span v-else>
|
|
643
|
+
{{ namespace }}
|
|
644
|
+
</span>
|
|
645
|
+
</span>
|
|
646
|
+
<span v-if="parent.showAge">
|
|
647
|
+
{{ t("resourceDetail.masthead.age") }}:
|
|
648
|
+
<LiveDate
|
|
649
|
+
class="live-date"
|
|
650
|
+
:value="value.creationTimestamp"
|
|
651
|
+
/>
|
|
652
|
+
</span>
|
|
653
|
+
<span
|
|
654
|
+
v-if="value.showCreatedBy"
|
|
655
|
+
data-testid="masthead-subheader-createdBy"
|
|
656
|
+
>
|
|
657
|
+
{{ t("resourceDetail.masthead.createdBy") }}:
|
|
658
|
+
<router-link
|
|
659
|
+
v-if="value.createdBy.location"
|
|
660
|
+
:to="value.createdBy.location"
|
|
661
|
+
data-testid="masthead-subheader-createdBy-link"
|
|
662
|
+
>
|
|
663
|
+
{{ value.createdBy.displayName }}
|
|
664
|
+
</router-link>
|
|
665
|
+
<span
|
|
666
|
+
v-else
|
|
667
|
+
data-testid="masthead-subheader-createdBy_plain-text"
|
|
668
|
+
>
|
|
669
|
+
{{ value.createdBy.displayName }}
|
|
670
|
+
</span>
|
|
671
|
+
</span>
|
|
672
|
+
<span v-if="value.showPodRestarts">{{ t("resourceDetail.masthead.restartCount") }}:<span class="live-data"> {{ value.restartCount }}</span></span>
|
|
673
|
+
</div> -->
|
|
674
|
+
</div>
|
|
675
|
+
<slot name="right">
|
|
676
|
+
<div class="actions-container align-start">
|
|
677
|
+
<div class="actions">
|
|
678
|
+
<button
|
|
679
|
+
v-if="detailsAction && currentView === DETAIL_VIEW && isView"
|
|
680
|
+
type="button"
|
|
681
|
+
class="btn role-primary actions mr-10"
|
|
682
|
+
:disabled="!detailsAction.enabled"
|
|
683
|
+
@click="invokeDetailsAction"
|
|
684
|
+
>
|
|
685
|
+
{{ detailsAction.label }}
|
|
686
|
+
</button>
|
|
687
|
+
<ButtonGroup
|
|
688
|
+
v-if="showSensitiveToggle"
|
|
689
|
+
:value="!!hideSensitiveData"
|
|
690
|
+
icon-size="lg"
|
|
691
|
+
:options="sensitiveOptions"
|
|
692
|
+
class="mr-10"
|
|
693
|
+
@update:value="toggleSensitiveData"
|
|
694
|
+
/>
|
|
695
|
+
|
|
696
|
+
<ButtonGroup
|
|
697
|
+
v-if="viewOptions && isView"
|
|
698
|
+
v-model:value="currentView"
|
|
699
|
+
:options="viewOptions"
|
|
700
|
+
class="mr-10"
|
|
701
|
+
/>
|
|
702
|
+
|
|
703
|
+
<template v-if="featureDropdownMenu">
|
|
704
|
+
<ActionMenu
|
|
705
|
+
v-if="isView"
|
|
706
|
+
button-role="multiAction"
|
|
707
|
+
button-size="compact"
|
|
708
|
+
:resource="value"
|
|
709
|
+
data-testid="masthead-action-menu"
|
|
710
|
+
/>
|
|
711
|
+
</template>
|
|
712
|
+
<template v-else>
|
|
597
713
|
<button
|
|
598
|
-
v-if="
|
|
714
|
+
v-if="isView"
|
|
715
|
+
ref="actions"
|
|
716
|
+
data-testid="masthead-action-menu"
|
|
717
|
+
aria-haspopup="true"
|
|
599
718
|
type="button"
|
|
600
|
-
class="btn role-
|
|
601
|
-
|
|
602
|
-
@click="invokeDetailsAction"
|
|
719
|
+
class="btn role-multi-action actions"
|
|
720
|
+
@click="showActions"
|
|
603
721
|
>
|
|
604
|
-
|
|
722
|
+
<i class="icon icon-actions" />
|
|
605
723
|
</button>
|
|
606
|
-
|
|
607
|
-
<!-- 敏感信息显示/隐藏切换 -->
|
|
608
|
-
<ButtonGroup
|
|
609
|
-
v-if="showSensitiveToggle"
|
|
610
|
-
:value="!!hideSensitiveData"
|
|
611
|
-
icon-size="lg"
|
|
612
|
-
:options="sensitiveOptions"
|
|
613
|
-
class="mr-10"
|
|
614
|
-
@update:value="toggleSensitiveData"
|
|
615
|
-
/>
|
|
616
|
-
|
|
617
|
-
<!-- 视图切换按钮 -->
|
|
618
|
-
<ButtonGroup
|
|
619
|
-
v-if="viewOptions && isView"
|
|
620
|
-
v-model:value="currentView"
|
|
621
|
-
:options="viewOptions"
|
|
622
|
-
class="mr-10"
|
|
623
|
-
/>
|
|
624
|
-
|
|
625
|
-
<!-- 功能菜单:优先使用 ActionMenu 组件 -->
|
|
626
|
-
<template v-if="featureDropdownMenu">
|
|
627
|
-
<ActionMenu
|
|
628
|
-
v-if="isView"
|
|
629
|
-
button-role="multiAction"
|
|
630
|
-
button-size="compact"
|
|
631
|
-
:resource="value"
|
|
632
|
-
data-testid="masthead-action-menu"
|
|
633
|
-
/>
|
|
634
|
-
</template>
|
|
635
|
-
|
|
636
|
-
<!-- 如果没有 featureDropdownMenu,则使用普通的多操作按钮 -->
|
|
637
|
-
<template v-else>
|
|
638
|
-
<button
|
|
639
|
-
v-if="isView"
|
|
640
|
-
ref="actions"
|
|
641
|
-
data-testid="masthead-action-menu"
|
|
642
|
-
aria-haspopup="true"
|
|
643
|
-
type="button"
|
|
644
|
-
class="btn role-multi-action actions"
|
|
645
|
-
@click="showActions"
|
|
646
|
-
>
|
|
647
|
-
<i class="icon icon-actions" />
|
|
648
|
-
</button>
|
|
649
|
-
</template>
|
|
650
|
-
</div>
|
|
724
|
+
</template>
|
|
651
725
|
</div>
|
|
652
|
-
</
|
|
653
|
-
</
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
<!-- 内容插槽 -->
|
|
679
|
-
<slot />
|
|
726
|
+
</div>
|
|
727
|
+
</slot>
|
|
728
|
+
</header>
|
|
729
|
+
|
|
730
|
+
<!-- Extension area -->
|
|
731
|
+
<ExtensionPanel
|
|
732
|
+
:resource="value"
|
|
733
|
+
:type="extensionType"
|
|
734
|
+
:location="extensionLocation"
|
|
735
|
+
/>
|
|
736
|
+
|
|
737
|
+
<Banner
|
|
738
|
+
v-if="banner && isView && !parent.hideBanner"
|
|
739
|
+
class="state-banner mb-10"
|
|
740
|
+
:color="banner.color"
|
|
741
|
+
:label="banner.message"
|
|
742
|
+
/>
|
|
743
|
+
<Banner
|
|
744
|
+
v-if="managedWarning.show"
|
|
745
|
+
color="warning"
|
|
746
|
+
class="mb-20"
|
|
747
|
+
:label="t('resourceDetail.masthead.managedWarning', managedWarning)"
|
|
748
|
+
/>
|
|
749
|
+
|
|
750
|
+
<slot />
|
|
680
751
|
</div>
|
|
681
752
|
</div>
|
|
682
753
|
</template>
|
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
_VIEW, _EDIT, _CLONE, _IMPORT, _STAGE, _CREATE,
|
|
7
7
|
AS, _YAML, _DETAIL, _CONFIG, _GRAPH, PREVIEW, MODE,
|
|
8
8
|
} from '@shell/config/query-params';
|
|
9
|
-
import { SCHEMA } from '@shell/config/types';
|
|
9
|
+
import { FLEET, SCHEMA } from '@shell/config/types';
|
|
10
10
|
import { createYaml } from '@shell/utils/create-yaml';
|
|
11
11
|
import Masthead from '@shell/components/ResourceDetail/Masthead';
|
|
12
12
|
import DetailTop from '@shell/components/DetailTop';
|
|
13
13
|
import { clone, diff } from '@shell/utils/object';
|
|
14
14
|
import IconMessage from '@shell/components/IconMessage';
|
|
15
15
|
import ForceDirectedTreeChart from '@shell/components/ForceDirectedTreeChart';
|
|
16
|
+
import { checkSchemasForFindAllHash } from '@shell/utils/auth';
|
|
16
17
|
import { stringify } from '@shell/utils/error';
|
|
17
18
|
import { Banner } from '@components/Banner';
|
|
18
19
|
|
|
@@ -171,6 +172,28 @@ export default {
|
|
|
171
172
|
yaml = createYaml(schemas, resourceType, data);
|
|
172
173
|
}
|
|
173
174
|
} else {
|
|
175
|
+
if ( as === _GRAPH ) {
|
|
176
|
+
const graphSchema = await checkSchemasForFindAllHash({
|
|
177
|
+
cluster: {
|
|
178
|
+
inStoreType: 'management',
|
|
179
|
+
type: FLEET.CLUSTER
|
|
180
|
+
},
|
|
181
|
+
bundle: {
|
|
182
|
+
inStoreType: 'management',
|
|
183
|
+
type: FLEET.BUNDLE,
|
|
184
|
+
opt: { excludeFields: ['metadata.managedFields', 'spec.resources'] },
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
bundleDeployment: {
|
|
188
|
+
inStoreType: 'management',
|
|
189
|
+
type: FLEET.BUNDLE_DEPLOYMENT
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
}, this.$store);
|
|
193
|
+
|
|
194
|
+
this.canViewChart = graphSchema.cluster && graphSchema.bundle && graphSchema.bundleDeployment;
|
|
195
|
+
}
|
|
196
|
+
|
|
174
197
|
let fqid = id;
|
|
175
198
|
|
|
176
199
|
if ( schema.attributes?.namespaced && namespace ) {
|
|
@@ -273,6 +296,7 @@ export default {
|
|
|
273
296
|
value: null,
|
|
274
297
|
model: null,
|
|
275
298
|
notFound: null,
|
|
299
|
+
canViewChart: true,
|
|
276
300
|
canViewYaml: null,
|
|
277
301
|
errors: []
|
|
278
302
|
};
|
|
@@ -440,7 +464,7 @@ export default {
|
|
|
440
464
|
|
|
441
465
|
<template>
|
|
442
466
|
<Loading v-if="$fetchState.pending || notFound" />
|
|
443
|
-
<div
|
|
467
|
+
<div v-else>
|
|
444
468
|
<Masthead
|
|
445
469
|
v-if="showMasthead"
|
|
446
470
|
:resource="resourceType"
|
|
@@ -451,17 +475,14 @@ export default {
|
|
|
451
475
|
:has-graph="hasGraph"
|
|
452
476
|
:has-detail="hasCustomDetail"
|
|
453
477
|
:has-edit="hasCustomEdit"
|
|
454
|
-
:can-view-yaml="canViewYaml"
|
|
455
478
|
:resource-subtype="resourceSubtype"
|
|
456
479
|
:parent-route-override="parentRouteOverride"
|
|
457
480
|
:store-override="storeOverride"
|
|
458
|
-
|
|
459
|
-
:isManuallyHide="false"
|
|
460
481
|
>
|
|
461
|
-
<DetailTop
|
|
482
|
+
<!-- <DetailTop
|
|
462
483
|
v-if="isView && isDetail"
|
|
463
484
|
:value="liveModel"
|
|
464
|
-
/>
|
|
485
|
+
/> -->
|
|
465
486
|
</Masthead>
|
|
466
487
|
<div
|
|
467
488
|
v-if="hasErrors"
|
|
@@ -481,7 +502,7 @@ export default {
|
|
|
481
502
|
</div>
|
|
482
503
|
|
|
483
504
|
<ForceDirectedTreeChart
|
|
484
|
-
v-if="isGraph"
|
|
505
|
+
v-if="isGraph && canViewChart"
|
|
485
506
|
:data="chartData"
|
|
486
507
|
:fdc-config="getGraphConfig"
|
|
487
508
|
/>
|
|
@@ -495,9 +516,8 @@ export default {
|
|
|
495
516
|
:offer-preview="offerPreview"
|
|
496
517
|
:done-route="doneRoute"
|
|
497
518
|
:done-override="value ? value.doneOverride : null"
|
|
498
|
-
:show-errors="false"
|
|
499
519
|
@update:value="$emit('input', $event)"
|
|
500
|
-
@error="
|
|
520
|
+
@error="e=>errors.push(e)"
|
|
501
521
|
/>
|
|
502
522
|
|
|
503
523
|
<component
|
|
@@ -555,10 +575,4 @@ export default {
|
|
|
555
575
|
flex-direction: column;
|
|
556
576
|
flex-grow: 1;
|
|
557
577
|
}
|
|
558
|
-
.cru__errors {
|
|
559
|
-
position: sticky;
|
|
560
|
-
top: 0;
|
|
561
|
-
z-index: 1;
|
|
562
|
-
background-color: var(--header-bg);
|
|
563
|
-
}
|
|
564
578
|
</style>
|
|
@@ -16,6 +16,10 @@ export default {
|
|
|
16
16
|
showLabels: {
|
|
17
17
|
type: Boolean,
|
|
18
18
|
default: false,
|
|
19
|
+
},
|
|
20
|
+
isShowPass: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false,
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
|
|
@@ -88,7 +92,7 @@ export default {
|
|
|
88
92
|
<template v-else-if="principal">
|
|
89
93
|
<div class="avatar">
|
|
90
94
|
<img
|
|
91
|
-
|
|
95
|
+
src="@shell/assets/images/user.png"
|
|
92
96
|
:class="{'round': principal.roundAvatar}"
|
|
93
97
|
:alt="t('principal.alt.avatar')"
|
|
94
98
|
>
|
|
@@ -98,11 +102,19 @@ export default {
|
|
|
98
102
|
class="name"
|
|
99
103
|
>
|
|
100
104
|
<table>
|
|
101
|
-
<
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
<tr class="mb-10">
|
|
106
|
+
<td>{{ t('principal.name') }}: </td><td>{{ principal.name || principal.loginName }}</td>
|
|
107
|
+
</tr>
|
|
108
|
+
<tr class="mb-10">
|
|
109
|
+
<td>{{ t('principal.loginName') }}: </td><td>{{ principal.loginName }}</td>
|
|
110
|
+
</tr>
|
|
111
|
+
<tr
|
|
112
|
+
v-if="isShowPass"
|
|
113
|
+
class="mb-10"
|
|
114
|
+
>
|
|
115
|
+
<td>修改密码: </td><td>****** <slot name="edit" /></td>
|
|
116
|
+
</tr>
|
|
117
|
+
<tr><td>{{ t('principal.type') }}: </td><td>{{ principal.displayType }}</td></tr>
|
|
106
118
|
</table>
|
|
107
119
|
</div>
|
|
108
120
|
<template v-else>
|
|
@@ -154,7 +166,7 @@ export default {
|
|
|
154
166
|
</template>
|
|
155
167
|
|
|
156
168
|
<style lang="scss" scoped>
|
|
157
|
-
$size:
|
|
169
|
+
$size: 79px;
|
|
158
170
|
|
|
159
171
|
.principal {
|
|
160
172
|
display: grid;
|
|
@@ -162,7 +174,7 @@ export default {
|
|
|
162
174
|
"avatar name"
|
|
163
175
|
"avatar description";
|
|
164
176
|
grid-template-columns: $size auto;
|
|
165
|
-
|
|
177
|
+
grid-template-rows: auto math.div($size, 2);
|
|
166
178
|
column-gap: 10px;
|
|
167
179
|
|
|
168
180
|
th {
|
|
@@ -172,23 +184,35 @@ export default {
|
|
|
172
184
|
}
|
|
173
185
|
|
|
174
186
|
&.showLabels {
|
|
175
|
-
grid-template-areas:
|
|
187
|
+
/* grid-template-areas:
|
|
176
188
|
"avatar name";
|
|
177
189
|
grid-template-columns: 60px auto;
|
|
178
190
|
grid-template-rows: 60px;
|
|
179
|
-
column-gap: 0;
|
|
191
|
+
column-gap: 0; */
|
|
192
|
+
display: flex;
|
|
193
|
+
column-gap:0;
|
|
180
194
|
.name {
|
|
195
|
+
display: flex;
|
|
181
196
|
line-height: unset;
|
|
182
197
|
}
|
|
183
|
-
|
|
198
|
+
table tr {
|
|
199
|
+
display: block;
|
|
200
|
+
}
|
|
184
201
|
table tr td:not(:first-of-type) {
|
|
185
202
|
padding-left: 10px;
|
|
186
203
|
}
|
|
204
|
+
table tr td:not(:last-of-type) {
|
|
205
|
+
width: 100px;
|
|
206
|
+
}
|
|
187
207
|
}
|
|
188
208
|
|
|
189
209
|
.avatar {
|
|
190
|
-
grid-area: avatar;
|
|
191
|
-
text-align: center;
|
|
210
|
+
/* grid-area: avatar;
|
|
211
|
+
text-align: center; */
|
|
212
|
+
width: 287px;
|
|
213
|
+
display: flex;
|
|
214
|
+
justify-content: center;
|
|
215
|
+
align-items: center;
|
|
192
216
|
|
|
193
217
|
DIV.empty {
|
|
194
218
|
border: 1px solid var(--border);
|
package/package.json
CHANGED
package/pages/account/index.vue
CHANGED
|
@@ -3,8 +3,7 @@ import BackLink from '@shell/components/BackLink';
|
|
|
3
3
|
import { MANAGEMENT, NORMAN } from '@shell/config/types';
|
|
4
4
|
import { SETTING } from '@shell/config/settings';
|
|
5
5
|
import Loading from '@shell/components/Loading';
|
|
6
|
-
|
|
7
|
-
import Principal from './pri.vue';
|
|
6
|
+
import Principal from '@shell/components/auth/Principal';
|
|
8
7
|
import BackRoute from '@shell/mixins/back-link';
|
|
9
8
|
import { mapGetters } from 'vuex';
|
|
10
9
|
|
|
@@ -17,7 +16,7 @@ const API_ENDPOINT = '/v3';
|
|
|
17
16
|
|
|
18
17
|
export default {
|
|
19
18
|
components: {
|
|
20
|
-
CopyToClipboardText, BackLink, Banner,
|
|
19
|
+
CopyToClipboardText, BackLink, Banner, Loading, ResourceTable, Principal, TabTitle
|
|
21
20
|
},
|
|
22
21
|
mixins: [BackRoute],
|
|
23
22
|
async fetch() {
|
|
@@ -190,13 +189,12 @@ export default {
|
|
|
190
189
|
type="button"
|
|
191
190
|
class="btn role-primary"
|
|
192
191
|
data-testid="account_change_password"
|
|
193
|
-
@click="
|
|
192
|
+
@click="showChangePasswordDialog"
|
|
194
193
|
>
|
|
195
194
|
{{ t("accountAndKeys.account.change") }}
|
|
196
195
|
</button>
|
|
197
196
|
</div> -->
|
|
198
197
|
</div>
|
|
199
|
-
<PromptChangePassword ref="promptChangePassword" />
|
|
200
198
|
|
|
201
199
|
<!-- <hr role="none"> -->
|
|
202
200
|
<div
|
|
@@ -217,6 +215,16 @@ export default {
|
|
|
217
215
|
/>
|
|
218
216
|
</div>
|
|
219
217
|
</div>
|
|
218
|
+
<button
|
|
219
|
+
v-if="apiKeySchema"
|
|
220
|
+
role="button"
|
|
221
|
+
:aria-label="t('accountAndKeys.apiKeys.add.label')"
|
|
222
|
+
class="btn role-primary add mb-20"
|
|
223
|
+
data-testid="account_create_api_keys"
|
|
224
|
+
@click="addKey"
|
|
225
|
+
>
|
|
226
|
+
{{ t('accountAndKeys.apiKeys.add.label') }}
|
|
227
|
+
</button>
|
|
220
228
|
</div>
|
|
221
229
|
<div
|
|
222
230
|
v-if="apiKeySchema"
|
package/pages/auth/login.vue
CHANGED
|
@@ -32,7 +32,6 @@ import loadPlugins from '@shell/plugins/plugin';
|
|
|
32
32
|
import Loading from '@shell/components/Loading';
|
|
33
33
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
34
34
|
import TabTitle from '@shell/components/TabTitle.vue';
|
|
35
|
-
import { AFTER_LOGIN_ROUTE } from '@shell/store/prefs';
|
|
36
35
|
|
|
37
36
|
export default {
|
|
38
37
|
name: 'Login',
|
|
@@ -64,10 +63,6 @@ export default {
|
|
|
64
63
|
};
|
|
65
64
|
},
|
|
66
65
|
|
|
67
|
-
created () {
|
|
68
|
-
// this.$store.dispatch('i18n/switchTo', 'zh-hans');
|
|
69
|
-
},
|
|
70
|
-
|
|
71
66
|
computed: {
|
|
72
67
|
...mapGetters(['isSingleProduct']),
|
|
73
68
|
...mapGetters({ t: 'i18n/t', hasMultipleLocales: 'i18n/hasMultipleLocales' }),
|
|
@@ -173,7 +168,7 @@ export default {
|
|
|
173
168
|
this.focusSomething();
|
|
174
169
|
});
|
|
175
170
|
},
|
|
176
|
-
|
|
171
|
+
|
|
177
172
|
methods: {
|
|
178
173
|
async loadInitialSettings() {
|
|
179
174
|
let firstLoginSetting, plSetting, brand;
|
package/pages/account/pri.vue
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { NORMAN } from '@shell/config/types';
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
props: {
|
|
6
|
-
value: {
|
|
7
|
-
type: String,
|
|
8
|
-
required: true,
|
|
9
|
-
},
|
|
10
|
-
|
|
11
|
-
useMuted: {
|
|
12
|
-
type: Boolean,
|
|
13
|
-
default: true,
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
showLabels: {
|
|
17
|
-
type: Boolean,
|
|
18
|
-
default: false,
|
|
19
|
-
},
|
|
20
|
-
isShowPass: {
|
|
21
|
-
type: Boolean,
|
|
22
|
-
default: false,
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
async fetch() {
|
|
27
|
-
this.principal = this.$store.getters['rancher/byId'](NORMAN.PRINCIPAL, this.value);
|
|
28
|
-
|
|
29
|
-
if ( this.principal ) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const principalId = escape(this.value).replace(/\//g, '%2F');
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
this.principal = await this.$store.dispatch('rancher/find', {
|
|
37
|
-
type: NORMAN.PRINCIPAL,
|
|
38
|
-
id: this.value,
|
|
39
|
-
opt: { url: `/v3/principals/${ principalId }` }
|
|
40
|
-
});
|
|
41
|
-
} catch (e) {
|
|
42
|
-
console.error('Failed to fetch principal', this.value, principalId); // eslint-disable-line no-console
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
data() {
|
|
47
|
-
// Load from cache immediately if possible
|
|
48
|
-
return { principal: null };
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
computed: {
|
|
52
|
-
showBoth() {
|
|
53
|
-
const p = this.principal;
|
|
54
|
-
|
|
55
|
-
return p.name && p.loginName && p.name.trim().toLowerCase() !== p.loginName.trim().toLowerCase();
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<template>
|
|
62
|
-
<div
|
|
63
|
-
class="principal"
|
|
64
|
-
:class="{'showLabels': showLabels}"
|
|
65
|
-
>
|
|
66
|
-
<template v-if="!principal && $fetchState.pending">
|
|
67
|
-
<div class="avatar">
|
|
68
|
-
<div class="empty">
|
|
69
|
-
<i class="icon icon-spinner icon-lg" />
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
<div
|
|
73
|
-
v-clean-html="t('principal.loading', null, true)"
|
|
74
|
-
class="name"
|
|
75
|
-
:class="{'text-muted': useMuted}"
|
|
76
|
-
/>
|
|
77
|
-
<div class="description" />
|
|
78
|
-
</template>
|
|
79
|
-
|
|
80
|
-
<template v-else-if="principal">
|
|
81
|
-
<div class="avatar">
|
|
82
|
-
<img
|
|
83
|
-
src="@shell/assets/images/user.png"
|
|
84
|
-
>
|
|
85
|
-
</div>
|
|
86
|
-
<div
|
|
87
|
-
v-if="showLabels"
|
|
88
|
-
class="name"
|
|
89
|
-
>
|
|
90
|
-
<table>
|
|
91
|
-
<tr class="mb-10">
|
|
92
|
-
<td>{{ t('principal.name') }}: </td><td>{{ principal.name || principal.loginName }}</td>
|
|
93
|
-
</tr>
|
|
94
|
-
<tr class="mb-10">
|
|
95
|
-
<td>{{ t('principal.loginName') }}: </td><td>{{ principal.loginName }}</td>
|
|
96
|
-
</tr>
|
|
97
|
-
<tr
|
|
98
|
-
v-if="isShowPass"
|
|
99
|
-
class="mb-10"
|
|
100
|
-
>
|
|
101
|
-
<td>修改密码: </td><td>****** <slot name="edit" /></td>
|
|
102
|
-
</tr>
|
|
103
|
-
<tr><td>{{ t('principal.type') }}: </td><td>{{ principal.displayType }}</td></tr>
|
|
104
|
-
</table>
|
|
105
|
-
</div>
|
|
106
|
-
<template v-else>
|
|
107
|
-
<div class="name">
|
|
108
|
-
<template v-if="showBoth">
|
|
109
|
-
{{ principal.name }}
|
|
110
|
-
<span
|
|
111
|
-
v-if="principal.loginName"
|
|
112
|
-
:class="{'text-muted': useMuted}"
|
|
113
|
-
>({{ principal.loginName }})</span>
|
|
114
|
-
</template>
|
|
115
|
-
<template v-else-if="principal.name">
|
|
116
|
-
{{ principal.name }}
|
|
117
|
-
</template>
|
|
118
|
-
<template v-else>
|
|
119
|
-
{{ principal.loginName }}
|
|
120
|
-
</template>
|
|
121
|
-
</div>
|
|
122
|
-
<div
|
|
123
|
-
class="description"
|
|
124
|
-
:class="{'text-muted': useMuted}"
|
|
125
|
-
>
|
|
126
|
-
{{ principal.displayType }}
|
|
127
|
-
</div>
|
|
128
|
-
</template>
|
|
129
|
-
</template>
|
|
130
|
-
|
|
131
|
-
<template v-else>
|
|
132
|
-
<div class="avatar">
|
|
133
|
-
<div
|
|
134
|
-
class="empty"
|
|
135
|
-
:class="{'text-muted': useMuted}"
|
|
136
|
-
>
|
|
137
|
-
<i class="icon icon-warning icon-lg" />
|
|
138
|
-
</div>
|
|
139
|
-
</div>
|
|
140
|
-
<div
|
|
141
|
-
v-t="'principal.error'"
|
|
142
|
-
class="name text-error"
|
|
143
|
-
/>
|
|
144
|
-
<div
|
|
145
|
-
class="description"
|
|
146
|
-
:class="{'text-muted': useMuted}"
|
|
147
|
-
>
|
|
148
|
-
{{ value }}
|
|
149
|
-
</div>
|
|
150
|
-
</template>
|
|
151
|
-
</div>
|
|
152
|
-
</template>
|
|
153
|
-
|
|
154
|
-
<style lang="scss" scoped>
|
|
155
|
-
$size: 79px;
|
|
156
|
-
|
|
157
|
-
.principal {
|
|
158
|
-
display: grid;
|
|
159
|
-
grid-template-areas:
|
|
160
|
-
"avatar name"
|
|
161
|
-
"avatar description";
|
|
162
|
-
grid-template-columns: $size auto;
|
|
163
|
-
grid-template-rows: auto math.div($size, 2);
|
|
164
|
-
column-gap: 10px;
|
|
165
|
-
|
|
166
|
-
th {
|
|
167
|
-
text-align: left;
|
|
168
|
-
font-weight: normal;
|
|
169
|
-
padding-right: 10px;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
&.showLabels {
|
|
173
|
-
/* grid-template-areas:
|
|
174
|
-
"avatar name";
|
|
175
|
-
grid-template-columns: 60px auto;
|
|
176
|
-
grid-template-rows: 60px;
|
|
177
|
-
column-gap: 0; */
|
|
178
|
-
display: flex;
|
|
179
|
-
column-gap:0;
|
|
180
|
-
.name {
|
|
181
|
-
display: flex;
|
|
182
|
-
line-height: unset;
|
|
183
|
-
}
|
|
184
|
-
table tr {
|
|
185
|
-
display: block;
|
|
186
|
-
}
|
|
187
|
-
table tr td:not(:first-of-type) {
|
|
188
|
-
padding-left: 10px;
|
|
189
|
-
}
|
|
190
|
-
table tr td:not(:last-of-type) {
|
|
191
|
-
width: 100px;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.avatar {
|
|
196
|
-
/* grid-area: avatar;
|
|
197
|
-
text-align: center; */
|
|
198
|
-
width: 287px;
|
|
199
|
-
display: flex;
|
|
200
|
-
justify-content: center;
|
|
201
|
-
align-items: center;
|
|
202
|
-
|
|
203
|
-
DIV.empty {
|
|
204
|
-
border: 1px solid var(--border);
|
|
205
|
-
line-height: $size;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
IMG {
|
|
209
|
-
width: $size;
|
|
210
|
-
height: $size;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
DIV.round, IMG.round {
|
|
214
|
-
border-radius: 50%;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.name {
|
|
219
|
-
grid-area: name;
|
|
220
|
-
line-height: math.div($size, 2);
|
|
221
|
-
overflow-wrap: anywhere;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.description {
|
|
225
|
-
grid-area: description;
|
|
226
|
-
line-height: math.div($size, 2);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
</style>
|