From 0172607a450b2acaf78c0c93637c23a71bdc374a Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Mon, 22 Dec 2025 11:21:45 +0800
Subject: [PATCH 1/6] perf: Optimize the display position of the full-screen
button
---
.../elements/content/content.component.html | 17 +++++++++++++++--
.../elements/content/content.component.scss | 19 ++++++++++++++++---
src/app/elements/content/content.component.ts | 18 ++++++++++++++++++
.../nav/setting/setting.component.html | 1 +
4 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/app/elements/content/content.component.html b/src/app/elements/content/content.component.html
index a6d3890b7..d97fdd3f8 100644
--- a/src/app/elements/content/content.component.html
+++ b/src/app/elements/content/content.component.html
@@ -3,10 +3,12 @@
+
+
+
+ @if (viewList.length > 0) {
+
+ }
) {
moveItemInArray(this.viewIds, event.previousIndex, event.currentIndex);
}
+
+ handleFullscreen() {
+ const ele: any = document.getElementsByClassName('window active')[0];
+
+ if (!ele) return;
+
+ const requestFullscreen =
+ ele.requestFullscreen ||
+ ele.webkitRequestFullscreen ||
+ ele.mozRequestFullScreen ||
+ ele.msRequestFullscreen;
+
+ if (!requestFullscreen) {
+ throw new Error('不支持全屏api');
+ }
+
+ requestFullscreen.call(ele);
+ }
}
diff --git a/src/app/elements/nav/setting/setting.component.html b/src/app/elements/nav/setting/setting.component.html
index 2d2c6551a..b506ab337 100644
--- a/src/app/elements/nav/setting/setting.component.html
+++ b/src/app/elements/nav/setting/setting.component.html
@@ -109,6 +109,7 @@
+
From c768b7f5c38ec13536f45cd171cba671b7006ef5 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Wed, 14 Jan 2026 11:01:20 +0800
Subject: [PATCH 2/6] fix: Fix the issue of the tab drag icon being out of
order (#1494)
---
src/app/elements/content/content.component.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/elements/content/content.component.ts b/src/app/elements/content/content.component.ts
index a95b748ea..e3c8dc72a 100644
--- a/src/app/elements/content/content.component.ts
+++ b/src/app/elements/content/content.component.ts
@@ -211,8 +211,8 @@ export class ElementContentComponent implements OnInit, OnDestroy {
this.tabsRef.nativeElement.scrollLeft = this.tabsRef.nativeElement.scrollWidth;
}
- trackByFn(index, item) {
- return item.id;
+ trackByFn(index, id) {
+ return id;
}
rTabMenuItems() {
From 6774185621700ad3ac0b45a302bf47dcc015c1db Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Tue, 20 Jan 2026 11:15:15 +0800
Subject: [PATCH 3/6] fix: Fix the issue where automatic connection cannot be
selected
---
.../connect-dialog/select-account/select-account.component.ts | 2 +-
src/app/services/app.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/app/elements/connect/connect-dialog/select-account/select-account.component.ts b/src/app/elements/connect/connect-dialog/select-account/select-account.component.ts
index 8d23781bf..cfb7a6a4c 100644
--- a/src/app/elements/connect/connect-dialog/select-account/select-account.component.ts
+++ b/src/app/elements/connect/connect-dialog/select-account/select-account.component.ts
@@ -57,7 +57,7 @@ export class ElementSelectAccountComponent implements OnInit, OnDestroy {
private _cdRef: ChangeDetectorRef
) {
this.usernamePlaceholder = this._i18n.instant('Username');
- this.rememberAuthDisabled = !this._settingSvc.globalSetting.SECURITY_LUNA_REMEMBER_AUTH;
+ this.rememberAuthDisabled = false;
}
get noSecretAccounts() {
diff --git a/src/app/services/app.ts b/src/app/services/app.ts
index 899a80a26..afa11b072 100644
--- a/src/app/services/app.ts
+++ b/src/app/services/app.ts
@@ -258,6 +258,7 @@ export class AppService {
connectOption,
direct: connectData.direct
};
+
this.setAccountLocalAuth(asset, account, manualAuthInfo);
this._localStorage.set(key, saveData);
}
@@ -346,7 +347,7 @@ export class AppService {
newAuth.alias = account.alias;
}
- if (!auth.secret || !auth.rememberAuth || !this._settingSvc.globalSetting.SECURITY_LUNA_REMEMBER_AUTH) {
+ if (!auth.secret || !auth.rememberAuth) {
newAuth.secret = '';
} else {
newAuth.secret = this.encrypt(auth.secret);
From d4079a4b4e97bef0339cf5fec75f9b2c42e5b72b Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Wed, 21 Jan 2026 13:45:40 +0800
Subject: [PATCH 4/6] fix: Fix the issue of missing tab icon
---
.../content-tab/content-tab.component.scss | 10 +++
.../content-tab/content-tab.component.ts | 70 +++++++++++++++++--
2 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/src/app/elements/content/content-tab/content-tab.component.scss b/src/app/elements/content/content-tab/content-tab.component.scss
index b8241599b..162cf2e59 100644
--- a/src/app/elements/content/content-tab/content-tab.component.scss
+++ b/src/app/elements/content/content-tab/content-tab.component.scss
@@ -75,9 +75,19 @@ li {
.view_icon {
margin-right: 5px;
font-style: normal;
+ width: 16px;
+ height: 16px;
+ display: inline-block;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 16px 16px;
+ vertical-align: middle;
&::before {
display: inline-block;
+ width: 16px;
+ line-height: 16px;
+ text-align: center;
color: var(--el-icon-color);
font-family: FontAwesome;
}
diff --git a/src/app/elements/content/content-tab/content-tab.component.ts b/src/app/elements/content/content-tab/content-tab.component.ts
index 57d5cdb18..ea0660950 100644
--- a/src/app/elements/content/content-tab/content-tab.component.ts
+++ b/src/app/elements/content/content-tab/content-tab.component.ts
@@ -3,8 +3,10 @@ import {
ElementRef,
EventEmitter,
Input,
+ OnChanges,
OnInit,
Output,
+ SimpleChanges,
ViewChild
} from '@angular/core';
import { View, ViewAction } from '@app/model';
@@ -15,20 +17,23 @@ import { View, ViewAction } from '@app/model';
templateUrl: 'content-tab.component.html',
styleUrls: ['content-tab.component.scss']
})
-export class ElementContentTabComponent implements OnInit {
+export class ElementContentTabComponent implements OnInit, OnChanges {
@Input() view: View;
@Output() onAction: EventEmitter = new EventEmitter();
@ViewChild('inputElement', { static: false }) inputElement: ElementRef;
- public iconCls: string;
+ public iconCls: string[] = [];
private shouldFocusInput = false;
private clickTimeout: any;
+ private static faIconCache = new Map();
ngOnInit(): void {
- if (!this.view.asset) {
- this.iconCls = 'fa-linux';
- } else {
- this.iconCls = 'fa-' + this.view.asset.type.value;
+ this.updateIconClasses();
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.view) {
+ this.updateIconClasses();
}
}
@@ -70,4 +75,57 @@ export class ElementContentTabComponent implements OnInit {
this.view.editable = false;
}, 200);
}
+
+ private updateIconClasses(): void {
+ const iconKey = this.view?.asset?.type?.value || 'linux';
+ const faClass = `fa-${iconKey}`;
+ const fallbackClass = this.getFallbackIconClass(iconKey);
+ const hasFontAwesome = this.hasFontAwesomeIcon(faClass);
+
+ this.iconCls = hasFontAwesome ? ['fa', faClass] : [fallbackClass];
+ }
+
+ private getFallbackIconClass(iconKey: string): string {
+ const normalizedKey = iconKey || 'linux';
+ const overrides: Record = {
+ general: 'switch_ico_docu',
+ website: 'website_ico_docu',
+ sqlserver: 'sqlserver_ico_docu',
+ postgresql: 'postgresql_ico_docu',
+ mysql: 'mysql_ico_docu',
+ mariadb: 'mariadb_ico_docu',
+ mongodb: 'mongodb_ico_docu',
+ webcloud: 'WebCloud_ico_docu',
+ web_cloud: 'WebCloud_ico_docu',
+ 'web-cloud': 'WebCloud_ico_docu'
+ };
+
+ return overrides[normalizedKey] || `${normalizedKey}_ico_docu`;
+ }
+
+ private hasFontAwesomeIcon(iconClass: string): boolean {
+ const cached = ElementContentTabComponent.faIconCache.get(iconClass);
+ if (cached !== undefined) {
+ return cached;
+ }
+
+ if (typeof document === 'undefined' || typeof window === 'undefined') {
+ return true;
+ }
+
+ const el = document.createElement('i');
+ el.className = `view_icon fa ${iconClass}`;
+ el.style.position = 'absolute';
+ el.style.opacity = '0';
+ el.style.pointerEvents = 'none';
+ document.body.appendChild(el);
+
+ const content = window.getComputedStyle(el, '::before').getPropertyValue('content');
+ document.body.removeChild(el);
+
+ const normalizedContent = (content || '').replace(/['"]/g, '');
+ const hasContent = normalizedContent !== '' && normalizedContent !== 'none' && normalizedContent !== 'normal';
+ ElementContentTabComponent.faIconCache.set(iconClass, hasContent);
+ return hasContent;
+ }
}
From 9e768e93e75d3b0699641913e7fa1fc923e07e55 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Wed, 21 Jan 2026 14:35:16 +0800
Subject: [PATCH 5/6] fix: Fix the issue with the icon position (#1498)
---
.../content/content-tab/content-tab.component.scss | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/app/elements/content/content-tab/content-tab.component.scss b/src/app/elements/content/content-tab/content-tab.component.scss
index 162cf2e59..8d803b7c4 100644
--- a/src/app/elements/content/content-tab/content-tab.component.scss
+++ b/src/app/elements/content/content-tab/content-tab.component.scss
@@ -75,12 +75,13 @@ li {
.view_icon {
margin-right: 5px;
font-style: normal;
- width: 16px;
- height: 16px;
- display: inline-block;
+ display: flex;
+ width: 14px;
+ height: 14px;
+ align-items: center;
background-repeat: no-repeat;
background-position: center;
- background-size: 16px 16px;
+ background-size: 14px 14px;
vertical-align: middle;
&::before {
From c2e4c3ee0baf357b1ece6067c9a1ed5a1394e832 Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Wed, 21 Jan 2026 18:19:32 +0800
Subject: [PATCH 6/6] fix: Fix the issue where the connection method is missing
due to frequent clicking of nodes
---
src/app/services/app.ts | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/app/services/app.ts b/src/app/services/app.ts
index afa11b072..568ad469c 100644
--- a/src/app/services/app.ts
+++ b/src/app/services/app.ts
@@ -30,6 +30,8 @@ export class AppService {
private protocolPreferKey = 'ProtocolPreferLoginType';
private accountPreferKey = 'PreferAccount';
private protocolConnectTypesMap: object = {};
+ private connectMethodsRequestSeq = 0;
+ private connectMethodsAppliedSeq = 0;
private checkIntervalId: number;
private newLoginHasOpen = false; // 避免多次打开新登录页
private checkSecond = 120;
@@ -202,13 +204,21 @@ export class AppService {
getConnectMethods(): Promise {
const url = '/api/v1/terminal/components/connect-methods/';
+ const requestSeq = ++this.connectMethodsRequestSeq;
// 当用户先打开 luna 并进行操作时如果后在 lina 中去设置连接方式的 ACL 此时并不生效,因此修改为在 toPromise 后直接赋值
return this._http
.get(url)
.toPromise()
.then(response => {
+ // 每次发起请求都自增 connectMethodsRequestSeq,记录当前请求序号 requestSeq
+ // 响应回来时,如果 requestSeq 小于已经应用过的 connectMethodsAppliedSeq,说明这是“过期响应”,直接丢弃
+ // 只有最新的响应才会更新 protocolConnectTypesMap,并把 connectMethodsAppliedSeq 同步为最新
+ if (requestSeq < this.connectMethodsAppliedSeq) {
+ return;
+ }
this.protocolConnectTypesMap = response;
+ this.connectMethodsAppliedSeq = requestSeq;
})
.catch(error => {
this._logger.error('Get connect methods error:', error);