Skip to content

Commit 05384e8

Browse files
authored
Merge pull request #1502 from jumpserver/dev
v4.10.15
2 parents 394b7f5 + c2e4c3e commit 05384e8

8 files changed

Lines changed: 140 additions & 15 deletions

File tree

src/app/elements/connect/connect-dialog/select-account/select-account.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class ElementSelectAccountComponent implements OnInit, OnDestroy {
5757
private _cdRef: ChangeDetectorRef
5858
) {
5959
this.usernamePlaceholder = this._i18n.instant('Username');
60-
this.rememberAuthDisabled = !this._settingSvc.globalSetting.SECURITY_LUNA_REMEMBER_AUTH;
60+
this.rememberAuthDisabled = false;
6161
}
6262

6363
get noSecretAccounts() {

src/app/elements/content/content-tab/content-tab.component.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,20 @@ li {
7575
.view_icon {
7676
margin-right: 5px;
7777
font-style: normal;
78+
display: flex;
79+
width: 14px;
80+
height: 14px;
81+
align-items: center;
82+
background-repeat: no-repeat;
83+
background-position: center;
84+
background-size: 14px 14px;
85+
vertical-align: middle;
7886

7987
&::before {
8088
display: inline-block;
89+
width: 16px;
90+
line-height: 16px;
91+
text-align: center;
8192
color: var(--el-icon-color);
8293
font-family: FontAwesome;
8394
}

src/app/elements/content/content-tab/content-tab.component.ts

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import {
33
ElementRef,
44
EventEmitter,
55
Input,
6+
OnChanges,
67
OnInit,
78
Output,
9+
SimpleChanges,
810
ViewChild
911
} from '@angular/core';
1012
import { View, ViewAction } from '@app/model';
@@ -15,20 +17,23 @@ import { View, ViewAction } from '@app/model';
1517
templateUrl: 'content-tab.component.html',
1618
styleUrls: ['content-tab.component.scss']
1719
})
18-
export class ElementContentTabComponent implements OnInit {
20+
export class ElementContentTabComponent implements OnInit, OnChanges {
1921
@Input() view: View;
2022
@Output() onAction: EventEmitter<ViewAction> = new EventEmitter<ViewAction>();
2123
@ViewChild('inputElement', { static: false }) inputElement: ElementRef;
2224

23-
public iconCls: string;
25+
public iconCls: string[] = [];
2426
private shouldFocusInput = false;
2527
private clickTimeout: any;
28+
private static faIconCache = new Map<string, boolean>();
2629

2730
ngOnInit(): void {
28-
if (!this.view.asset) {
29-
this.iconCls = 'fa-linux';
30-
} else {
31-
this.iconCls = 'fa-' + this.view.asset.type.value;
31+
this.updateIconClasses();
32+
}
33+
34+
ngOnChanges(changes: SimpleChanges): void {
35+
if (changes.view) {
36+
this.updateIconClasses();
3237
}
3338
}
3439

@@ -70,4 +75,57 @@ export class ElementContentTabComponent implements OnInit {
7075
this.view.editable = false;
7176
}, 200);
7277
}
78+
79+
private updateIconClasses(): void {
80+
const iconKey = this.view?.asset?.type?.value || 'linux';
81+
const faClass = `fa-${iconKey}`;
82+
const fallbackClass = this.getFallbackIconClass(iconKey);
83+
const hasFontAwesome = this.hasFontAwesomeIcon(faClass);
84+
85+
this.iconCls = hasFontAwesome ? ['fa', faClass] : [fallbackClass];
86+
}
87+
88+
private getFallbackIconClass(iconKey: string): string {
89+
const normalizedKey = iconKey || 'linux';
90+
const overrides: Record<string, string> = {
91+
general: 'switch_ico_docu',
92+
website: 'website_ico_docu',
93+
sqlserver: 'sqlserver_ico_docu',
94+
postgresql: 'postgresql_ico_docu',
95+
mysql: 'mysql_ico_docu',
96+
mariadb: 'mariadb_ico_docu',
97+
mongodb: 'mongodb_ico_docu',
98+
webcloud: 'WebCloud_ico_docu',
99+
web_cloud: 'WebCloud_ico_docu',
100+
'web-cloud': 'WebCloud_ico_docu'
101+
};
102+
103+
return overrides[normalizedKey] || `${normalizedKey}_ico_docu`;
104+
}
105+
106+
private hasFontAwesomeIcon(iconClass: string): boolean {
107+
const cached = ElementContentTabComponent.faIconCache.get(iconClass);
108+
if (cached !== undefined) {
109+
return cached;
110+
}
111+
112+
if (typeof document === 'undefined' || typeof window === 'undefined') {
113+
return true;
114+
}
115+
116+
const el = document.createElement('i');
117+
el.className = `view_icon fa ${iconClass}`;
118+
el.style.position = 'absolute';
119+
el.style.opacity = '0';
120+
el.style.pointerEvents = 'none';
121+
document.body.appendChild(el);
122+
123+
const content = window.getComputedStyle(el, '::before').getPropertyValue('content');
124+
document.body.removeChild(el);
125+
126+
const normalizedContent = (content || '').replace(/['"]/g, '');
127+
const hasContent = normalizedContent !== '' && normalizedContent !== 'none' && normalizedContent !== 'normal';
128+
ElementContentTabComponent.faIconCache.set(iconClass, hasContent);
129+
return hasContent;
130+
}
73131
}

src/app/elements/content/content.component.html

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
<span (click)="toggleMenu.emit()" class="mobile-menu-icon">
44
<i class="fa fa-sitemap"></i>
55
</span>
6+
67
<div class="scroll-button">
7-
<a (click)="scrollLeft()" class="left"><i class="fa fa-caret-left"></i></a>
8-
<a (click)="scrollRight()" class="right"><i class="fa fa-caret-right"></i></a>
8+
<a (click)="scrollLeft()" class="left action-btn"><i class="fa fa-caret-left"></i></a>
9+
<a (click)="scrollRight()" class="right action-btn"><i class="fa fa-caret-right"></i></a>
910
</div>
11+
1012
<div #tabs class="tabs">
1113
<ul
1214
(cdkDropListDropped)="onItemDropped($event)"
@@ -27,6 +29,17 @@
2729
</elements-content-tab>
2830
</ul>
2931
</div>
32+
33+
@if (viewList.length > 0) {
34+
<nz-icon
35+
nz-tooltip
36+
[nzTooltipTitle]="'Full screen' | translate"
37+
nzType="fullscreen"
38+
nzTheme="outline"
39+
class="action-btn fullscreen-icon"
40+
(click)="handleFullscreen()"
41+
/>
42+
}
3043
</div>
3144
<div [ngClass]="{ 'batch-input': showBatchCommand }" id="winContainer">
3245
<div

src/app/elements/content/content.component.scss

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33
border-left: 1px solid var(--el-border-color-x);
44

55
.tab-bar {
6-
a {
7-
color: white;
6+
display: flex;
7+
justify-content: space-between;
8+
align-items: center;
9+
flex-wrap: nowrap;
10+
width: 100%;
11+
background-color: var(--el-tab-bg-color);
12+
13+
.action-btn {
14+
cursor: pointer;
15+
color: #fff;
816
}
917

1018
.scroll-button {
@@ -30,6 +38,7 @@
3038

3139
.tabs {
3240
display: flex;
41+
flex: 1;
3342
position: relative;
3443
height: 30px;
3544
overflow-y: hidden;
@@ -42,7 +51,7 @@
4251
min-width: 100%;
4352
padding-left: 0;
4453
margin: 0;
45-
background-color: var(--el-tab-bg-color);
54+
4655

4756
.drag-box {
4857
display: inline-flex;
@@ -60,6 +69,10 @@
6069
}
6170
}
6271
}
72+
73+
.fullscreen-icon {
74+
margin: 0 12px;
75+
}
6376
}
6477

6578
#winContainer {

src/app/elements/content/content.component.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ export class ElementContentComponent implements OnInit, OnDestroy {
211211
this.tabsRef.nativeElement.scrollLeft = this.tabsRef.nativeElement.scrollWidth;
212212
}
213213

214-
trackByFn(index, item) {
215-
return item.id;
214+
trackByFn(index, id) {
215+
return id;
216216
}
217217

218218
rTabMenuItems() {
@@ -350,4 +350,22 @@ export class ElementContentComponent implements OnInit, OnDestroy {
350350
onItemDropped(event: CdkDragDrop<string[]>) {
351351
moveItemInArray(this.viewIds, event.previousIndex, event.currentIndex);
352352
}
353+
354+
handleFullscreen() {
355+
const ele: any = document.getElementsByClassName('window active')[0];
356+
357+
if (!ele) return;
358+
359+
const requestFullscreen =
360+
ele.requestFullscreen ||
361+
ele.webkitRequestFullscreen ||
362+
ele.mozRequestFullScreen ||
363+
ele.msRequestFullscreen;
364+
365+
if (!requestFullscreen) {
366+
throw new Error('不支持全屏api');
367+
}
368+
369+
requestFullscreen.call(ele);
370+
}
353371
}

src/app/elements/nav/setting/setting.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
</nz-form-item>
110110
</div>
111111
</div>
112+
112113
<div *ngIf="type === 'cli'">
113114
<nz-form-item>
114115
<nz-form-label [nzSm]="8" [nzXs]="24">

src/app/services/app.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export class AppService {
3030
private protocolPreferKey = 'ProtocolPreferLoginType';
3131
private accountPreferKey = 'PreferAccount';
3232
private protocolConnectTypesMap: object = {};
33+
private connectMethodsRequestSeq = 0;
34+
private connectMethodsAppliedSeq = 0;
3335
private checkIntervalId: number;
3436
private newLoginHasOpen = false; // 避免多次打开新登录页
3537
private checkSecond = 120;
@@ -202,13 +204,21 @@ export class AppService {
202204

203205
getConnectMethods(): Promise<void> {
204206
const url = '/api/v1/terminal/components/connect-methods/';
207+
const requestSeq = ++this.connectMethodsRequestSeq;
205208

206209
// 当用户先打开 luna 并进行操作时如果后在 lina 中去设置连接方式的 ACL 此时并不生效,因此修改为在 toPromise 后直接赋值
207210
return this._http
208211
.get(url)
209212
.toPromise()
210213
.then(response => {
214+
// 每次发起请求都自增 connectMethodsRequestSeq,记录当前请求序号 requestSeq
215+
// 响应回来时,如果 requestSeq 小于已经应用过的 connectMethodsAppliedSeq,说明这是“过期响应”,直接丢弃
216+
// 只有最新的响应才会更新 protocolConnectTypesMap,并把 connectMethodsAppliedSeq 同步为最新
217+
if (requestSeq < this.connectMethodsAppliedSeq) {
218+
return;
219+
}
211220
this.protocolConnectTypesMap = response;
221+
this.connectMethodsAppliedSeq = requestSeq;
212222
})
213223
.catch(error => {
214224
this._logger.error('Get connect methods error:', error);
@@ -258,6 +268,7 @@ export class AppService {
258268
connectOption,
259269
direct: connectData.direct
260270
};
271+
261272
this.setAccountLocalAuth(asset, account, manualAuthInfo);
262273
this._localStorage.set(key, saveData);
263274
}
@@ -346,7 +357,7 @@ export class AppService {
346357
newAuth.alias = account.alias;
347358
}
348359

349-
if (!auth.secret || !auth.rememberAuth || !this._settingSvc.globalSetting.SECURITY_LUNA_REMEMBER_AUTH) {
360+
if (!auth.secret || !auth.rememberAuth) {
350361
newAuth.secret = '';
351362
} else {
352363
newAuth.secret = this.encrypt(auth.secret);

0 commit comments

Comments
 (0)