dashboard-shell-shell 1.0.1000000116 → 1.0.1000000117
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/assets/images/action.svg +6 -0
- package/assets/images/pl/logo.png +0 -0
- package/assets/styles/base/_functions.scss +0 -0
- package/assets/styles/base/_mixins.scss +1 -1
- package/assets/styles/global/_button.scss +17 -10
- package/assets/styles/global/_form.scss +2 -2
- package/assets/styles/global/_labeled-input.scss +6 -2
- package/assets/styles/global/_select.scss +6 -7
- package/assets/styles/global/_table.scss +3 -2
- package/assets/styles/global/_tooltip.scss +8 -1
- package/assets/styles/themes/_dark.scss +2 -0
- package/assets/styles/themes/_light.scss +5 -2
- package/assets/styles/vendor/vue-select.scss +2 -1
- package/assets/translations/en-us.yaml +1 -3
- package/assets/translations/zh-hans.yaml +51 -28
- package/components/ActionDropdown.vue +1 -0
- package/components/ActionMenuShell.vue +6 -3
- package/components/BrandImage.vue +22 -0
- package/components/ClusterIconMenu.vue +1 -1
- package/components/CodeMirror.vue +1 -0
- package/components/CruResource.vue +1 -1
- package/components/CruResourceFooter.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +4 -24
- package/components/GlobalRoleBindings.vue +112 -48
- package/components/IndentedPanel.vue +4 -10
- package/components/PromptRemove.vue +3 -3
- package/components/ResourceDetail/Masthead.vue +190 -242
- package/components/ResourceDetail/index.vue +20 -5
- package/components/ResourceList/Masthead.vue +146 -84
- package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
- package/components/ResourceTable.vue +76 -1
- package/components/SideNav.vue +66 -29
- package/components/SortableTable/THead.vue +6 -0
- package/components/SortableTable/index.vue +481 -388
- package/components/Tabbed/index.vue +4 -5
- package/components/auth/Principal.vue +3 -2
- package/components/auth/RoleDetailEdit.vue +58 -5
- package/components/auth/SelectPrincipal.vue +1 -0
- package/components/form/BannerSettings.vue +18 -16
- package/components/form/ChangePassword.vue +4 -4
- package/components/form/ColorInput.vue +32 -8
- package/components/form/Footer.vue +1 -1
- package/components/form/InputWithSelect.vue +2 -0
- package/components/form/KeyValue.vue +31 -7
- package/components/form/LabeledSelect.vue +178 -178
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -2
- package/components/form/Members/MembershipEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +24 -11
- package/components/form/Password.vue +6 -2
- package/components/form/ResourceQuota/Namespace.vue +1 -1
- package/components/form/ResourceQuota/NamespaceRow.vue +13 -10
- package/components/form/ResourceQuota/ProjectRow.vue +0 -1
- package/components/form/Select.vue +2 -2
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +69 -23
- package/components/nav/Header.vue +82 -17
- package/components/nav/HeaderPageActionMenu.vue +1 -0
- package/components/nav/NamespaceFilter.vue +0 -3
- package/components/nav/TopLevelMenu.vue +182 -119
- package/components/nav/Type.vue +48 -11
- package/composables/useClickOutside.ts +1 -1
- package/config/product/auth.js +16 -7
- package/config/product/explorer.js +1 -1
- package/config/product/settings.js +17 -8
- package/config/settings.ts +28 -0
- package/edit/management.cattle.io.user.vue +17 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
- package/edit/token.vue +1 -1
- package/list/harvesterhci.io.management.cluster.vue +17 -0
- package/list/management.cattle.io.setting.vue +22 -13
- package/list/management.cattle.io.user.vue +25 -14
- package/list/provisioning.cattle.io.cluster.vue +6 -7
- package/mixins/brand.js +17 -0
- package/package.json +1 -1
- package/pages/auth/login.vue +84 -29
- package/pages/c/_cluster/auth/roles/index.vue +61 -14
- package/pages/c/_cluster/settings/banners.vue +174 -101
- package/pages/c/_cluster/settings/brand.vue +348 -301
- package/pages/c/_cluster/settings/performance.vue +61 -38
- package/pages/home.vue +70 -21
- package/pages/prefs.vue +25 -23
- package/pkg/tsconfig.json +9 -9
- package/pkg/vue.config.js +1 -1
- package/promptRemove/mixin/roleDeletionCheck.js +2 -2
- package/scripts/clean +0 -0
- package/scripts/extension/bundle +0 -0
- package/scripts/extension/helm/scripts/package +0 -0
- package/scripts/extension/helm/scripts/patch +0 -0
- package/scripts/extension/helm/scripts/version +0 -0
- package/scripts/extension/helmpatch +0 -0
- package/scripts/extension/parse-tag-name +0 -0
- package/scripts/extension/publish +0 -0
- package/scripts/publish-shell.sh +86 -60
- package/scripts/serve-pkgs +0 -0
- package/scripts/sync-shell-deps +0 -0
- package/scripts/typegen.sh +44 -28
- package/store/i18n.js +5 -5
- package/store/prefs.js +17 -5
- package/store/type-map.js +2 -1
- package/types/shell/index.d.ts +1 -1
- package/utils/error.js +4 -0
- package/utils/router.js +3 -3
- package/vue.config.js +1 -6
- package/components/rancherResourceDetail/Masthead.vue +0 -769
- package/components/rancherResourceDetail/__tests__/Masthead.test.ts +0 -65
- package/components/rancherResourceDetail/index.vue +0 -591
- package/components/rancherResourceList/Masthead.vue +0 -375
- package/components/rancherResourceList/ResourceLoadingIndicator.vue +0 -140
- package/components/rancherResourceList/index.vue +0 -307
- package/components/rancherResourceList/resource-list.config.js +0 -7
- package/components/rancherResourceTable.vue +0 -783
- package/components/rancherSortableTable/THead.vue +0 -561
- package/components/rancherSortableTable/actions.js +0 -153
- package/components/rancherSortableTable/advanced-filtering.js +0 -272
- package/components/rancherSortableTable/debug.js +0 -117
- package/components/rancherSortableTable/filtering.js +0 -290
- package/components/rancherSortableTable/grouping.js +0 -48
- package/components/rancherSortableTable/index.vue +0 -2712
- package/components/rancherSortableTable/paging.js +0 -155
- package/components/rancherSortableTable/selection.js +0 -629
- package/components/rancherSortableTable/sortable-config.ts +0 -4
- package/components/rancherSortableTable/sorting.js +0 -129
- package/types/cloud-shell/index.d.ts +0 -11014
- /package/components/{rancherResourceList → ResourceList}/Masthead-btn.vue +0 -0
|
@@ -52,7 +52,10 @@ export default {
|
|
|
52
52
|
helper.update(args);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
const topLevelPermissions = sessionStorage.getItem('TOPLEVELPERMISSIONS') || ''
|
|
56
|
+
|
|
55
57
|
return {
|
|
58
|
+
topLevelPermissions,
|
|
56
59
|
shown: false,
|
|
57
60
|
displayVersion,
|
|
58
61
|
fullVersion,
|
|
@@ -460,12 +463,14 @@ export default {
|
|
|
460
463
|
|
|
461
464
|
<template>
|
|
462
465
|
<div>
|
|
463
|
-
<!--
|
|
466
|
+
<!-- ====================== 遮罩层(点击可关闭菜单) ====================== -->
|
|
464
467
|
<div
|
|
465
468
|
v-if="shown"
|
|
466
469
|
class="side-menu-glass"
|
|
467
470
|
@click="hide()"
|
|
468
471
|
/>
|
|
472
|
+
|
|
473
|
+
<!-- ====================== 菜单主容器(带淡入淡出过渡) ====================== -->
|
|
469
474
|
<transition name="fade">
|
|
470
475
|
<!-- Side menu -->
|
|
471
476
|
<div
|
|
@@ -476,8 +481,11 @@ export default {
|
|
|
476
481
|
role="navigation"
|
|
477
482
|
:aria-label="t('nav.ariaLabel.topLevelMenu')"
|
|
478
483
|
>
|
|
479
|
-
|
|
484
|
+
|
|
485
|
+
<!-- ====================== 菜单头部(Logo + 菜单按钮) ====================== -->
|
|
480
486
|
<div class="title">
|
|
487
|
+
|
|
488
|
+
<!-- 菜单按钮(汉堡图标) -->
|
|
481
489
|
<div
|
|
482
490
|
data-testid="top-level-menu"
|
|
483
491
|
:aria-label="t('nav.expandCollapseAppBar')"
|
|
@@ -488,6 +496,8 @@ export default {
|
|
|
488
496
|
@keyup.space="toggle()"
|
|
489
497
|
@click="toggle()"
|
|
490
498
|
>
|
|
499
|
+
|
|
500
|
+
<!-- 汉堡菜单SVG图标 -->
|
|
491
501
|
<svg
|
|
492
502
|
class="menu-icon"
|
|
493
503
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -500,19 +510,22 @@ export default {
|
|
|
500
510
|
fill="none"
|
|
501
511
|
/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" /></svg>
|
|
502
512
|
</div>
|
|
503
|
-
|
|
513
|
+
|
|
514
|
+
<!-- 品牌Logo -->
|
|
515
|
+
<div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'" class="side-menu-logo">
|
|
504
516
|
<BrandImage
|
|
505
517
|
data-testid="side-menu__brand-img"
|
|
506
518
|
:alt="t('nav.alt.mainMenuRancherLogo')"
|
|
507
|
-
file-name="
|
|
519
|
+
file-name="logo.png"
|
|
508
520
|
/>
|
|
509
521
|
</div>
|
|
510
522
|
</div>
|
|
511
523
|
|
|
512
|
-
<!--
|
|
524
|
+
<!-- ====================== 菜单内容区 ====================== -->
|
|
513
525
|
<div class="body">
|
|
514
|
-
<div>
|
|
515
|
-
|
|
526
|
+
<div v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
|
|
527
|
+
|
|
528
|
+
<!-- 首页按钮 -->
|
|
516
529
|
<div @click="hide()">
|
|
517
530
|
<router-link
|
|
518
531
|
class="option cluster selector home"
|
|
@@ -520,6 +533,8 @@ export default {
|
|
|
520
533
|
role="link"
|
|
521
534
|
:aria-label="t('nav.ariaLabel.homePage')"
|
|
522
535
|
>
|
|
536
|
+
|
|
537
|
+
<!-- 首页图标 -->
|
|
523
538
|
<svg
|
|
524
539
|
v-clean-tooltip="getTooltipConfig(t('nav.home'))"
|
|
525
540
|
class="top-menu-icon"
|
|
@@ -536,12 +551,14 @@ export default {
|
|
|
536
551
|
</div>
|
|
537
552
|
</router-link>
|
|
538
553
|
</div>
|
|
539
|
-
|
|
554
|
+
|
|
555
|
+
<!-- 集群搜索框 -->
|
|
540
556
|
<div
|
|
541
557
|
v-if="showClusterSearch"
|
|
542
558
|
class="clusters-search"
|
|
543
559
|
>
|
|
544
560
|
<div class="clusters-search-count">
|
|
561
|
+
<!-- 当前搜索到的集群数量 -->
|
|
545
562
|
<span>{{ clusterFilterCount }}</span>
|
|
546
563
|
{{ t('nav.search.clusters') }}
|
|
547
564
|
<i
|
|
@@ -560,10 +577,14 @@ export default {
|
|
|
560
577
|
:tabindex="!shown ? -1 : 0"
|
|
561
578
|
:aria-label="t('nav.search.ariaLabel')"
|
|
562
579
|
>
|
|
580
|
+
|
|
581
|
+
<!-- 搜索图标 -->
|
|
563
582
|
<i
|
|
564
583
|
class="magnifier icon icon-search"
|
|
565
584
|
:class="{ active: clusterFilter }"
|
|
566
585
|
/>
|
|
586
|
+
|
|
587
|
+
<!-- 清空按钮 -->
|
|
567
588
|
<i
|
|
568
589
|
v-if="clusterFilter"
|
|
569
590
|
class="icon icon-close"
|
|
@@ -573,9 +594,11 @@ export default {
|
|
|
573
594
|
</div>
|
|
574
595
|
</div>
|
|
575
596
|
|
|
576
|
-
<!-- Harvester
|
|
597
|
+
<!-- ====================== Harvester 相关功能区 ====================== -->
|
|
577
598
|
<template v-if="hciApps.length">
|
|
578
599
|
<div class="category" />
|
|
600
|
+
|
|
601
|
+
<!-- 跳转 Harvester Dashboard -->
|
|
579
602
|
<div>
|
|
580
603
|
<a
|
|
581
604
|
v-if="isRancherInHarvester"
|
|
@@ -591,6 +614,8 @@ export default {
|
|
|
591
614
|
</div>
|
|
592
615
|
</a>
|
|
593
616
|
</div>
|
|
617
|
+
|
|
618
|
+
<!-- Harvester 应用列表 -->
|
|
594
619
|
<div
|
|
595
620
|
v-for="(a, i) in appBar.hciApps"
|
|
596
621
|
:key="i"
|
|
@@ -613,14 +638,14 @@ export default {
|
|
|
613
638
|
</div>
|
|
614
639
|
</template>
|
|
615
640
|
|
|
616
|
-
<!--
|
|
617
|
-
<template v-if="!!allClustersCount">
|
|
641
|
+
<!-- ====================== 集群列表 ====================== -->
|
|
642
|
+
<template v-if="topLevelPermissions && topLevelPermissions === 'superadmin' && !!allClustersCount">
|
|
618
643
|
<div
|
|
619
644
|
ref="clusterList"
|
|
620
645
|
class="clusters"
|
|
621
646
|
:style="pinnedClustersHeight"
|
|
622
647
|
>
|
|
623
|
-
<!--
|
|
648
|
+
<!-- 已固定集群 -->
|
|
624
649
|
<div
|
|
625
650
|
v-if="showPinClusters && pinFiltered.length"
|
|
626
651
|
class="clustersPinned"
|
|
@@ -631,11 +656,13 @@ export default {
|
|
|
631
656
|
:data-testid="`pinned-ready-cluster-${index}`"
|
|
632
657
|
@click="hide()"
|
|
633
658
|
>
|
|
634
|
-
|
|
659
|
+
|
|
660
|
+
<!-- 可用集群按钮 -->
|
|
661
|
+
<span
|
|
635
662
|
v-if="c.ready"
|
|
636
663
|
v-shortkey.push="{windows: ['alt'], mac: ['option']}"
|
|
637
664
|
:data-testid="`pinned-menu-cluster-${ c.id }`"
|
|
638
|
-
class="cluster selector option"
|
|
665
|
+
class="clusterBtn cluster selector option"
|
|
639
666
|
:class="{'active-menu-link': c.isMenuActive }"
|
|
640
667
|
:to="c.clusterRoute"
|
|
641
668
|
role="button"
|
|
@@ -665,7 +692,9 @@ export default {
|
|
|
665
692
|
:cluster="c"
|
|
666
693
|
:tab-order="shown ? 0 : -1"
|
|
667
694
|
/>
|
|
668
|
-
</
|
|
695
|
+
</span>
|
|
696
|
+
|
|
697
|
+
<!-- 不可用集群 -->
|
|
669
698
|
<span
|
|
670
699
|
v-else
|
|
671
700
|
class="option cluster selector disabled"
|
|
@@ -694,6 +723,8 @@ export default {
|
|
|
694
723
|
/>
|
|
695
724
|
</span>
|
|
696
725
|
</div>
|
|
726
|
+
|
|
727
|
+
<!-- 分割线 -->
|
|
697
728
|
<div
|
|
698
729
|
v-if="clustersFiltered.length > 0"
|
|
699
730
|
class="category-title"
|
|
@@ -702,7 +733,7 @@ export default {
|
|
|
702
733
|
</div>
|
|
703
734
|
</div>
|
|
704
735
|
|
|
705
|
-
<!--
|
|
736
|
+
<!-- 搜索结果集群列表 -->
|
|
706
737
|
<div class="clustersList">
|
|
707
738
|
<div
|
|
708
739
|
v-for="(c, index) in appBar.clustersFiltered"
|
|
@@ -710,11 +741,13 @@ export default {
|
|
|
710
741
|
:data-testid="`top-level-menu-cluster-${index}`"
|
|
711
742
|
@click="hide()"
|
|
712
743
|
>
|
|
713
|
-
|
|
744
|
+
|
|
745
|
+
<!-- 可用集群 -->
|
|
746
|
+
<span
|
|
714
747
|
v-if="c.ready"
|
|
715
748
|
v-shortkey.push="{windows: ['alt'], mac: ['option']}"
|
|
716
749
|
:data-testid="`menu-cluster-${ c.id }`"
|
|
717
|
-
class="cluster selector option"
|
|
750
|
+
class="cluster selector option clusterBtn"
|
|
718
751
|
:class="{'active-menu-link': c.isMenuActive }"
|
|
719
752
|
:to="c.clusterRoute"
|
|
720
753
|
role="button"
|
|
@@ -745,7 +778,9 @@ export default {
|
|
|
745
778
|
:tab-order="shown ? 0 : -1"
|
|
746
779
|
:cluster="c"
|
|
747
780
|
/>
|
|
748
|
-
</
|
|
781
|
+
</span>
|
|
782
|
+
|
|
783
|
+
<!-- 不可用集群 -->
|
|
749
784
|
<span
|
|
750
785
|
v-else
|
|
751
786
|
class="option cluster selector disabled"
|
|
@@ -777,7 +812,7 @@ export default {
|
|
|
777
812
|
</div>
|
|
778
813
|
</div>
|
|
779
814
|
|
|
780
|
-
<!--
|
|
815
|
+
<!-- 无匹配集群提示 -->
|
|
781
816
|
<div
|
|
782
817
|
v-if="clustersFiltered.length === 0 && searchActive"
|
|
783
818
|
data-testid="top-level-menu-no-results"
|
|
@@ -787,7 +822,7 @@ export default {
|
|
|
787
822
|
</div>
|
|
788
823
|
</div>
|
|
789
824
|
|
|
790
|
-
<!--
|
|
825
|
+
<!-- 查看所有集群按钮 -->
|
|
791
826
|
<router-link
|
|
792
827
|
v-if="allClustersCount > maxClustersToShow"
|
|
793
828
|
class="clusters-all"
|
|
@@ -806,104 +841,129 @@ export default {
|
|
|
806
841
|
</router-link>
|
|
807
842
|
</template>
|
|
808
843
|
|
|
809
|
-
<!--
|
|
810
|
-
<div class="category">
|
|
844
|
+
<!-- ====================== 多集群应用区 ====================== -->
|
|
845
|
+
<div :style="!(topLevelPermissions && topLevelPermissions === 'superadmin') ? { placeContent: 'flex-start', display: 'flex', flexDirection: 'column' } : {}" class="category">
|
|
846
|
+
<!-- 多集群应用 -->
|
|
811
847
|
<template v-if="multiClusterApps.length">
|
|
812
|
-
<
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
<hr role="none">
|
|
816
|
-
<span>
|
|
817
|
-
{{ t('nav.categories.multiCluster') }}
|
|
818
|
-
</span>
|
|
819
|
-
</div>
|
|
820
|
-
<div
|
|
821
|
-
v-for="(a, i) in appBar.multiClusterApps"
|
|
822
|
-
:key="i"
|
|
823
|
-
@click="hide()"
|
|
824
|
-
>
|
|
825
|
-
<router-link
|
|
826
|
-
class="option"
|
|
827
|
-
:class="{'active-menu-link': a.isMenuActive }"
|
|
828
|
-
:to="a.to"
|
|
829
|
-
role="link"
|
|
830
|
-
:aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
|
|
831
|
-
>
|
|
832
|
-
<IconOrSvg
|
|
833
|
-
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
834
|
-
class="app-icon"
|
|
835
|
-
:icon="a.icon"
|
|
836
|
-
:src="a.svg"
|
|
837
|
-
/>
|
|
838
|
-
<span class="option-link">{{ a.label }}</span>
|
|
839
|
-
</router-link>
|
|
840
|
-
</div>
|
|
841
|
-
</template>
|
|
842
|
-
|
|
843
|
-
<!-- Configuration apps menu -->
|
|
844
|
-
<template v-if="configurationApps.length">
|
|
845
|
-
<div
|
|
846
|
-
class="category-title"
|
|
847
|
-
>
|
|
848
|
-
<hr role="none">
|
|
849
|
-
<span>
|
|
850
|
-
{{ t('nav.categories.configuration') }}
|
|
851
|
-
</span>
|
|
852
|
-
</div>
|
|
853
|
-
<div
|
|
854
|
-
v-for="(a, i) in appBar.configurationApps"
|
|
855
|
-
:key="i"
|
|
856
|
-
@click="hide()"
|
|
857
|
-
>
|
|
858
|
-
<router-link
|
|
859
|
-
class="option"
|
|
860
|
-
:class="{'active-menu-link': a.isMenuActive }"
|
|
861
|
-
:to="a.to"
|
|
862
|
-
role="link"
|
|
863
|
-
:aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
|
|
848
|
+
<template v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
|
|
849
|
+
<div
|
|
850
|
+
class="category-title"
|
|
864
851
|
>
|
|
865
|
-
<
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
<div
|
|
872
|
-
|
|
873
|
-
|
|
852
|
+
<hr role="none">
|
|
853
|
+
<span>
|
|
854
|
+
{{ t('nav.categories.multiCluster') }}
|
|
855
|
+
</span>
|
|
856
|
+
</div>
|
|
857
|
+
<template v-for="(a, i) in appBar.multiClusterApps" :key="i">
|
|
858
|
+
<div
|
|
859
|
+
v-if="a.value === 'harvesterManager'"
|
|
860
|
+
@click="hide()"
|
|
861
|
+
>
|
|
862
|
+
<router-link
|
|
863
|
+
class="option"
|
|
864
|
+
:class="{'active-menu-link': a.isMenuActive }"
|
|
865
|
+
:to="a.to"
|
|
866
|
+
role="link"
|
|
867
|
+
:aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
|
|
868
|
+
>
|
|
869
|
+
<IconOrSvg
|
|
870
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
871
|
+
class="app-icon"
|
|
872
|
+
:icon="a.icon"
|
|
873
|
+
:src="a.svg"
|
|
874
|
+
/>
|
|
875
|
+
<span class="option-link">{{ a.label }}</span>
|
|
876
|
+
</router-link>
|
|
877
|
+
</div>
|
|
878
|
+
</template>
|
|
879
|
+
</template>
|
|
880
|
+
<template v-else>
|
|
881
|
+
<template v-for="(a, i) in appBar.multiClusterApps" :key="i">
|
|
882
|
+
<div
|
|
883
|
+
v-if="a.value === 'harvesterManager'"
|
|
884
|
+
@click="hide()"
|
|
885
|
+
>
|
|
886
|
+
<router-link
|
|
887
|
+
class="option"
|
|
888
|
+
:class="{'active-menu-link': a.isMenuActive }"
|
|
889
|
+
:to="a.to"
|
|
890
|
+
role="link"
|
|
891
|
+
:aria-label="`${t('nav.ariaLabel.multiClusterApps')} ${ a.label }`"
|
|
892
|
+
>
|
|
893
|
+
<IconOrSvg
|
|
894
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
895
|
+
class="app-icon"
|
|
896
|
+
:icon="a.icon"
|
|
897
|
+
:src="a.svg"
|
|
898
|
+
/>
|
|
899
|
+
<span class="option-link">{{ a.label }}</span>
|
|
900
|
+
</router-link>
|
|
901
|
+
</div>
|
|
902
|
+
</template>
|
|
903
|
+
</template>
|
|
874
904
|
</template>
|
|
875
|
-
</div>
|
|
876
|
-
</div>
|
|
877
905
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
906
|
+
<!-- 配置类应用 -->
|
|
907
|
+
<div>
|
|
908
|
+
<template v-if="configurationApps.length">
|
|
909
|
+
<template v-if="topLevelPermissions && topLevelPermissions === 'superadmin'">
|
|
910
|
+
<div
|
|
911
|
+
class="category-title"
|
|
912
|
+
>
|
|
913
|
+
<hr role="none">
|
|
914
|
+
<span>
|
|
915
|
+
{{ t('nav.categories.configuration') }}
|
|
916
|
+
</span>
|
|
917
|
+
</div>
|
|
918
|
+
<div
|
|
919
|
+
v-for="(a, i) in appBar.configurationApps"
|
|
920
|
+
:key="i"
|
|
921
|
+
@click="hide()"
|
|
922
|
+
>
|
|
923
|
+
<router-link
|
|
924
|
+
class="option"
|
|
925
|
+
:class="{'active-menu-link': a.isMenuActive }"
|
|
926
|
+
:to="a.to"
|
|
927
|
+
role="link"
|
|
928
|
+
:aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
|
|
929
|
+
>
|
|
930
|
+
<IconOrSvg
|
|
931
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
932
|
+
class="app-icon"
|
|
933
|
+
:icon="a.icon"
|
|
934
|
+
:src="a.svg"
|
|
935
|
+
/>
|
|
936
|
+
<div>{{ a.label }}</div>
|
|
937
|
+
</router-link>
|
|
938
|
+
</div>
|
|
939
|
+
</template>
|
|
940
|
+
<template v-else>
|
|
941
|
+
<template v-for="(a, i) in appBar.configurationApps" :key="i">
|
|
942
|
+
<div
|
|
943
|
+
v-if="a.value === 'settings' || a.value === 'auth'"
|
|
944
|
+
@click="hide()"
|
|
945
|
+
>
|
|
946
|
+
<router-link
|
|
947
|
+
class="option"
|
|
948
|
+
:class="{'active-menu-link': a.isMenuActive }"
|
|
949
|
+
:to="a.to"
|
|
950
|
+
role="link"
|
|
951
|
+
:aria-label="`${t('nav.ariaLabel.configurationApps')} ${ a.label }`"
|
|
952
|
+
>
|
|
953
|
+
<IconOrSvg
|
|
954
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
955
|
+
class="app-icon"
|
|
956
|
+
:icon="a.icon"
|
|
957
|
+
:src="a.svg"
|
|
958
|
+
/>
|
|
959
|
+
<div>{{ a.label }}</div>
|
|
960
|
+
</router-link>
|
|
961
|
+
</div>
|
|
962
|
+
</template>
|
|
963
|
+
</template>
|
|
964
|
+
<div style="height: 40px;"></div>
|
|
965
|
+
</template>
|
|
966
|
+
</div>
|
|
907
967
|
</div>
|
|
908
968
|
</div>
|
|
909
969
|
</div>
|
|
@@ -962,6 +1022,10 @@ export default {
|
|
|
962
1022
|
$option-padding-left: 14px;
|
|
963
1023
|
$option-height: $icon-size + $option-padding + $option-padding;
|
|
964
1024
|
|
|
1025
|
+
.clusterBtn {
|
|
1026
|
+
background-color: var(--nav-icon-badge-bg);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
965
1029
|
.side-menu {
|
|
966
1030
|
.menu {
|
|
967
1031
|
position: absolute;
|
|
@@ -1058,7 +1122,6 @@ export default {
|
|
|
1058
1122
|
flex: 1;
|
|
1059
1123
|
display: flex;
|
|
1060
1124
|
flex-direction: column;
|
|
1061
|
-
margin: 10px 0;
|
|
1062
1125
|
width: 300px;
|
|
1063
1126
|
overflow: auto;
|
|
1064
1127
|
|
|
@@ -1066,7 +1129,7 @@ export default {
|
|
|
1066
1129
|
align-items: center;
|
|
1067
1130
|
cursor: pointer;
|
|
1068
1131
|
display: flex;
|
|
1069
|
-
color: var(--
|
|
1132
|
+
color: var(--primary);
|
|
1070
1133
|
font-size: 14px;
|
|
1071
1134
|
height: $option-height;
|
|
1072
1135
|
white-space: nowrap;
|
|
@@ -1076,7 +1139,7 @@ export default {
|
|
|
1076
1139
|
border: none;
|
|
1077
1140
|
|
|
1078
1141
|
.cluster-badge-logo-text {
|
|
1079
|
-
color: var(--
|
|
1142
|
+
color: var(--primary);
|
|
1080
1143
|
font-weight: 500;
|
|
1081
1144
|
}
|
|
1082
1145
|
|
|
@@ -1148,7 +1211,7 @@ export default {
|
|
|
1148
1211
|
.rancher-provider-icon,
|
|
1149
1212
|
svg {
|
|
1150
1213
|
margin-right: 16px;
|
|
1151
|
-
fill: var(--
|
|
1214
|
+
fill: var(--primary);
|
|
1152
1215
|
}
|
|
1153
1216
|
|
|
1154
1217
|
.top-menu-icon {
|
package/components/nav/Type.vue
CHANGED
|
@@ -109,6 +109,7 @@ export default {
|
|
|
109
109
|
</script>
|
|
110
110
|
|
|
111
111
|
<template>
|
|
112
|
+
<!-- 当 type 有 route 时,渲染一个 Vue Router 自定义链接 -->
|
|
112
113
|
<router-link
|
|
113
114
|
v-if="type.route"
|
|
114
115
|
:key="type.name"
|
|
@@ -116,18 +117,24 @@ export default {
|
|
|
116
117
|
custom
|
|
117
118
|
:to="type.route"
|
|
118
119
|
>
|
|
120
|
+
|
|
121
|
+
<!-- 导航项容器 -->
|
|
119
122
|
<li
|
|
120
123
|
class="child nav-type"
|
|
121
124
|
:class="{'root': isRoot, [`depth-${depth}`]: true, 'router-link-active': isActive, 'router-link-exact-active': isExactActive}"
|
|
122
125
|
@click="navigate"
|
|
123
126
|
@keypress.enter="navigate"
|
|
124
127
|
>
|
|
128
|
+
|
|
129
|
+
<!-- 如果是精确匹配激活状态,则显示 TabTitle 组件 -->
|
|
125
130
|
<TabTitle
|
|
126
131
|
v-if="isExactActive"
|
|
127
132
|
:show-child="false"
|
|
128
133
|
>
|
|
129
134
|
{{ type.labelKey ? t(type.labelKey) : (type.labelDisplay || type.label) }}
|
|
130
135
|
</TabTitle>
|
|
136
|
+
|
|
137
|
+
<!-- 链接主体 -->
|
|
131
138
|
<a
|
|
132
139
|
role="link"
|
|
133
140
|
:aria-label="type.labelKey ? t(type.labelKey) : (type.labelDisplay || type.label)"
|
|
@@ -138,30 +145,40 @@ export default {
|
|
|
138
145
|
@mouseenter="setNear(true)"
|
|
139
146
|
@mouseleave="setNear(false)"
|
|
140
147
|
>
|
|
148
|
+
<!-- 文本标签:优先使用多语言 key -->
|
|
141
149
|
<span
|
|
142
150
|
v-if="type.labelKey"
|
|
143
151
|
class="label"
|
|
144
152
|
><t :k="type.labelKey" /></span>
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
class="
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
|
|
154
|
+
<!-- 没有 labelKey 时,直接使用 HTML 文本 -->
|
|
155
|
+
<div v-else style="display: flex; align-items: center;" class="labelKey_menu">
|
|
156
|
+
<i v-if="!type.labelDisplay || (type.labelDisplay && type.labelDisplay.indexOf('</i>') === -1)" class="icon icon-fw icon-globe" style="color: var(--muted);width: 32px;text-align: left;"></i>
|
|
157
|
+
<span
|
|
158
|
+
v-clean-html="type.labelDisplay.replace('设置', '基础设置') || type.label"
|
|
159
|
+
class="label"
|
|
160
|
+
:class="{'no-icon': !type.icon}"
|
|
161
|
+
/>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<!-- 右侧附加信息(收藏按钮 / 命名空间图标 / 计数) -->
|
|
151
165
|
<!-- <span
|
|
152
166
|
v-if="showFavorite || namespaceIcon || showCount"
|
|
153
167
|
class="count"
|
|
154
168
|
>
|
|
169
|
+
|
|
155
170
|
<Favorite
|
|
156
171
|
v-if="showFavorite"
|
|
157
172
|
:resource="type.name"
|
|
158
173
|
/>
|
|
174
|
+
|
|
159
175
|
<i
|
|
160
176
|
v-if="namespaceIcon"
|
|
161
177
|
class="icon icon-namespace"
|
|
162
178
|
:class="{'ns-and-icon': showCount}"
|
|
163
179
|
data-testid="type-namespaced"
|
|
164
180
|
/>
|
|
181
|
+
|
|
165
182
|
<span
|
|
166
183
|
v-if="showCount"
|
|
167
184
|
data-testid="type-count"
|
|
@@ -170,6 +187,8 @@ export default {
|
|
|
170
187
|
</a>
|
|
171
188
|
</li>
|
|
172
189
|
</router-link>
|
|
190
|
+
|
|
191
|
+
<!-- 当 type 没有 route 但有外部 link 时 -->
|
|
173
192
|
<li
|
|
174
193
|
v-else-if="type.link"
|
|
175
194
|
class="child nav-type nav-link"
|
|
@@ -185,6 +204,8 @@ export default {
|
|
|
185
204
|
<span class="label">{{ type.label }} <i class="icon icon-external-link" /></span>
|
|
186
205
|
</a>
|
|
187
206
|
</li>
|
|
207
|
+
|
|
208
|
+
<!-- 兜底情况:既没有 route,也没有 link -->
|
|
188
209
|
<li v-else>
|
|
189
210
|
{{ type }}?
|
|
190
211
|
</li>
|
|
@@ -234,12 +255,12 @@ export default {
|
|
|
234
255
|
A {
|
|
235
256
|
display: grid;
|
|
236
257
|
grid-template-areas: "label count";
|
|
237
|
-
grid-template-columns: auto
|
|
258
|
+
grid-template-columns: auto 20px;
|
|
238
259
|
grid-column-gap: 5px;
|
|
239
260
|
font-size: 14px;
|
|
240
261
|
line-height: 24px;
|
|
241
262
|
/* padding: 7.5px 7px 7.5px 10px; */
|
|
242
|
-
padding: 0px 16px 0px
|
|
263
|
+
padding: 0px 16px 0px 30px;
|
|
243
264
|
height: 50px;
|
|
244
265
|
margin: 0 0 0 -3px;
|
|
245
266
|
overflow: hidden;
|
|
@@ -248,7 +269,7 @@ export default {
|
|
|
248
269
|
color: var(--body-text);
|
|
249
270
|
|
|
250
271
|
&:hover {
|
|
251
|
-
background: var(--nav-active);
|
|
272
|
+
background: var(--nav-active) !important;
|
|
252
273
|
color: var(--nav-hover-color);
|
|
253
274
|
/* background: var(--nav-hover); */
|
|
254
275
|
text-decoration: none;
|
|
@@ -271,13 +292,13 @@ export default {
|
|
|
271
292
|
font-size: 12px;
|
|
272
293
|
text-align: right;
|
|
273
294
|
justify-items: center;
|
|
274
|
-
|
|
295
|
+
line-height: 50px;
|
|
275
296
|
}
|
|
276
297
|
|
|
277
298
|
&.nav-type:not(.depth-0) {
|
|
278
299
|
A {
|
|
279
300
|
font-size: 13px;
|
|
280
|
-
padding: 5.5px 7px 5.5px
|
|
301
|
+
padding: 5.5px 7px 5.5px 40px;
|
|
281
302
|
}
|
|
282
303
|
|
|
283
304
|
::v-deep .label I {
|
|
@@ -286,4 +307,20 @@ export default {
|
|
|
286
307
|
}
|
|
287
308
|
}
|
|
288
309
|
|
|
310
|
+
.labelKey_menu{
|
|
311
|
+
display: flex;
|
|
312
|
+
align-items: center;
|
|
313
|
+
}
|
|
314
|
+
.labelKey_menu:hover{
|
|
315
|
+
i{
|
|
316
|
+
color: var(--nav-hover-color) !important;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
.router-link-active{
|
|
320
|
+
.labelKey_menu{
|
|
321
|
+
i{
|
|
322
|
+
color: var(--nav-hover-color) !important;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
289
326
|
</style>
|
|
@@ -76,6 +76,6 @@ export const useClickOutside = <T extends OnClickOutsideOptions>(
|
|
|
76
76
|
|
|
77
77
|
onBeforeUnmount(() => {
|
|
78
78
|
window.removeEventListener('click', listener as any);
|
|
79
|
-
window.removeEventListener('
|
|
79
|
+
window.removeEventListener('pointerdown', setShouldListen);
|
|
80
80
|
});
|
|
81
81
|
};
|