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.
@@ -254,7 +254,7 @@ export default {
254
254
  },
255
255
 
256
256
  parent() {
257
- let displayName = this.value?.parentNameOverride || this.$store.getters['type-map/labelFor'](this.schema);
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
- <!-- 面包屑导航(创建 API 密钥时不显示) -->
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 v-if="item">{{ item }}</span>
511
- <span v-if="item">/</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
- <header>
521
- <div class="title">
522
- <div class="primaryheader">
523
- <span class="primary-title">
524
-
525
- <!-- 图标区 -->
526
- <span v-if="menuIcon && !(parentRouteOverride === 'account' && resource=== 'token')" class="detailIcon-span">
527
- <!-- 如果是账户 API token,则显示图片,否则显示 icon -->
528
- <img
529
- v-if="parentRouteOverride === 'account' && resource=== 'token'"
530
- :src="Svg"
531
- style="margin-top: 4px; margin-left: 5px;"
532
- >
533
- <i
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
- <i
571
- v-clean-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
572
- class="icon icon-sm icon-istio"
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="location"
580
- class="valid"
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
- </router-link>
588
- </div>
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
- <!-- 右侧操作按钮区域(支持通过 slot 覆盖) -->
592
- <slot name="right">
593
- <div class="actions-container align-start" style="padding-right: 15px;">
594
- <div class="actions">
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="detailsAction && currentView === DETAIL_VIEW && isView && isManuallyHide"
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-primary actions mr-10"
601
- :disabled="!detailsAction.enabled"
602
- @click="invokeDetailsAction"
719
+ class="btn role-multi-action actions"
720
+ @click="showActions"
603
721
  >
604
- {{ detailsAction.label }}
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
- </slot>
653
- </header>
654
-
655
- <!-- 扩展区域 -->
656
- <ExtensionPanel
657
- :resource="value"
658
- :type="extensionType"
659
- :location="extensionLocation"
660
- />
661
-
662
- <!-- 顶部状态 Banner -->
663
- <Banner
664
- v-if="banner && isView && !parent.hideBanner"
665
- class="state-banner mb-10"
666
- :color="banner.color"
667
- :label="banner.message == 'Waiting for API to be available' ? '等待 API 可用' : banner.message"
668
- />
669
-
670
- <!-- 管理警告 Banner -->
671
- <Banner
672
- v-if="managedWarning.show"
673
- color="warning"
674
- class="mb-20"
675
- :label="t('resourceDetail.masthead.managedWarning', managedWarning)"
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 style="padding: 20px;height: 100%;" v-else>
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="onYamlError"
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
- :src="principal.avatarSrc"
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
- <tbody>
102
- <tr><th>{{ t('principal.name') }}: </th><td>{{ principal.name || principal.loginName }}</td></tr>
103
- <tr><th>{{ t('principal.loginName') }}: </th><td>{{ principal.loginName }}</td></tr>
104
- <tr><th>{{ t('principal.type') }}: </th><td>{{ principal.displayType }}</td></tr>
105
- </tbody>
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: 20px;
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
- // grid-template-rows: auto math.div($size, 2);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashboard-shell-shell",
3
- "version": "3.0.5-test.3",
3
+ "version": "3.0.5-test.4",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -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
- // import Principal from '@shell/components/auth/Principal';
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, PromptChangePassword, Loading, ResourceTable, Principal, TabTitle
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="$refs.promptChangePassword.show(true)"
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"
@@ -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;
@@ -29,8 +29,8 @@ export default {
29
29
  computed: {
30
30
  headers() {
31
31
  return [
32
- NAME,
33
32
  STATE,
33
+ NAME,
34
34
  AGE
35
35
  ];
36
36
  },
@@ -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>