Skip to content

Commit 44d3cc8

Browse files
fit2botibulergithub-actions[bot]
authored
perf: if not favorite folder, create one and favorite (#1561)
* perf: change favorite folder * perf: if not favorite folder, create one and favorite * perf: Update Dockerfile with new base image tag --------- Co-authored-by: ibuler <ibuler@qq.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 24be52d commit 44d3cc8

2 files changed

Lines changed: 82 additions & 31 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Use base image to build the project avoid npm install every time
2-
FROM jumpserver/luna-base:20260701_071908 AS stage-build
2+
FROM jumpserver/luna-base:20260806_071716 AS stage-build
33

44
ARG VERSION
55
ENV VERSION=$VERSION

src/app/elements/asset-tree/asset-tree.component.ts

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,13 @@ export class ElementAssetTreeComponent implements OnInit {
365365
name: options.name,
366366
fa: options.fa,
367367
hide: false,
368-
disabled: true,
369-
click: () => {}
368+
children: [
369+
{
370+
id: 'create-folder-and-favorite',
371+
name: this._i18n.instant('Create folder and favorite'),
372+
click: this.onCreateFolderAndFavorite.bind(this)
373+
}
374+
]
370375
}
371376
];
372377
}
@@ -469,6 +474,24 @@ export class ElementAssetTreeComponent implements OnInit {
469474
return String(folderOrId);
470475
}
471476

477+
private resolveCreatedFavoriteFolderId(folder: any, name: string, parentId: string = null): Promise<string> {
478+
const createdFolderId = this.resolveFolderId(folder);
479+
if (createdFolderId) {
480+
return Promise.resolve(createdFolderId);
481+
}
482+
const normalizedParentId = this.resolveFolderId(parentId);
483+
return this._http
484+
.getFavoriteFolders()
485+
.toPromise()
486+
.then(folders => {
487+
this.favoriteFolders = folders || [];
488+
const createdFolder = this.favoriteFolders.find(
489+
f => f.name === name && this.resolveFolderId(f.parent) === normalizedParentId
490+
);
491+
return this.resolveFolderId(createdFolder);
492+
});
493+
}
494+
472495
/**
473496
* Resolve the real asset id from tree/favorite nodes.
474497
*/
@@ -1064,11 +1087,15 @@ export class ElementAssetTreeComponent implements OnInit {
10641087
connectOnNewPage(node, 'auto');
10651088
}
10661089

1090+
onCreateFolderAndFavorite() {
1091+
this.onCreateFolder(null, this.rightClickSelectNode);
1092+
}
1093+
10671094
/**
10681095
* Create folder: pop an input, validate empty/duplicate name, then call backend
10691096
* @param parentId parent folder id, null means top-level
10701097
*/
1071-
onCreateFolder(parentId: string = null) {
1098+
onCreateFolder(parentId: string = null, favoriteNode: any = null) {
10721099
this.folderNameInput = '';
10731100
this._modal.create({
10741101
nzTitle: this._i18n.instant(parentId ? 'Create subfolder' : 'Create folder'),
@@ -1089,13 +1116,34 @@ export class ElementAssetTreeComponent implements OnInit {
10891116
return this._http
10901117
.createFavoriteFolder(name, parentId)
10911118
.toPromise()
1092-
.then(() => {
1119+
.then(folder => {
10931120
const msg = this._i18n.instant('Create folder') + ' ' + this._i18n.instant('success');
1121+
if (favoriteNode) {
1122+
return this.resolveCreatedFavoriteFolderId(folder, name, parentId)
1123+
.then(createdFolderId => {
1124+
if (!createdFolderId) {
1125+
this.refreshFavoriteTree();
1126+
return;
1127+
}
1128+
return this.favoriteAssetToFolder(createdFolderId, favoriteNode, 'Favorite', {
1129+
refreshTreeOnSuccess: true
1130+
}).catch(() => {
1131+
this.refreshFavoriteTree();
1132+
});
1133+
})
1134+
.then(() => {
1135+
this._toastr.success(msg, '', { nzClass: 'custom-success-notification' });
1136+
});
1137+
}
10941138
this._toastr.success(msg, '', { nzClass: 'custom-success-notification' });
10951139
this.refreshFavoriteTree();
1140+
}, error => {
1141+
if (error && error.status === 400) {
1142+
this._message.error(this._i18n.instant('Folder already exists'));
1143+
}
1144+
return false;
10961145
})
10971146
.catch(() => {
1098-
this._message.error(this._i18n.instant('Folder already exists'));
10991147
return false;
11001148
});
11011149
}
@@ -1197,54 +1245,57 @@ export class ElementAssetTreeComponent implements OnInit {
11971245
* @param folderId target folder id
11981246
*/
11991247
onFavoriteTo(folderId: string) {
1200-
this.assignFavoriteToFolder(folderId, 'Favorite');
1248+
this.favoriteAssetToFolder(folderId, this.rightClickSelectNode, 'Favorite').catch(() => {});
12011249
}
12021250

1203-
/**
1204-
* Move a favorite-tree asset leaf into another folder.
1205-
* Same backend as favorite-to; only the success toast wording differs.
1206-
*/
1251+
/** Move a favorite-tree asset leaf into another folder. */
12071252
onMoveTo(folderId: string) {
1208-
this.assignFavoriteToFolder(folderId, 'Move');
1253+
this.favoriteAssetToFolder(folderId, this.rightClickSelectNode, 'Move').catch(() => {});
12091254
}
12101255

1211-
/**
1212-
* Assign the right-clicked asset to a favorite folder (create or relocate).
1213-
* @param folderId target folder id
1214-
* @param actionKey i18n key for success toast ("Favorite" / "Move")
1215-
*/
1216-
private assignFavoriteToFolder(folderId: string, actionKey: string) {
1217-
const srcNode = this.rightClickSelectNode;
1256+
private favoriteAssetToFolder(
1257+
folderId: string,
1258+
srcNode: any,
1259+
actionKey: string = 'Favorite',
1260+
options: { refreshTreeOnSuccess?: boolean } = {}
1261+
): Promise<void> {
12181262
const normalizedFolderId = this.resolveFolderId(folderId);
12191263
const assetId = this.resolveAssetId(srcNode);
12201264
if (!normalizedFolderId || !assetId) {
1221-
return;
1265+
return Promise.resolve();
12221266
}
12231267
const currentFolderId = this.resolveFolderId(srcNode.favoriteFolderId);
12241268
if (currentFolderId && currentFolderId === normalizedFolderId) {
12251269
this._message.warning(this._i18n.instant('Already in this folder'));
1226-
return;
1270+
return Promise.resolve();
12271271
}
12281272
const favoritingKey = `${assetId}-${normalizedFolderId}`;
12291273
if (this.favoritingInFlight.has(favoritingKey)) {
1230-
return;
1274+
return Promise.resolve();
12311275
}
12321276
this.favoritingInFlight.add(favoritingKey);
1233-
this._http.favoriteAssetToFolder(assetId, normalizedFolderId).subscribe(
1234-
() => {
1277+
return this._http
1278+
.favoriteAssetToFolder(assetId, normalizedFolderId)
1279+
.toPromise()
1280+
.then(() => {
12351281
const msg = this._i18n.instant(actionKey) + ' ' + this._i18n.instant('success');
12361282
this._toastr.success(msg, '', { nzClass: 'custom-success-notification' });
12371283
this.setFavoriteAssetRecord(normalizedFolderId, assetId, srcNode);
1238-
this.moveFavoriteLeaf(normalizedFolderId, srcNode, assetId);
1239-
this.favoritingInFlight.delete(favoritingKey);
1240-
},
1241-
error => {
1242-
this.favoritingInFlight.delete(favoritingKey);
1284+
if (options.refreshTreeOnSuccess) {
1285+
this.refreshFavoriteTree();
1286+
} else {
1287+
this.moveFavoriteLeaf(normalizedFolderId, srcNode, assetId);
1288+
}
1289+
})
1290+
.catch(error => {
12431291
if (error && error.status === 400) {
12441292
this._message.warning(this._i18n.instant('Already in this folder'));
12451293
}
1246-
}
1247-
);
1294+
return Promise.reject(error);
1295+
})
1296+
.finally(() => {
1297+
this.favoritingInFlight.delete(favoritingKey);
1298+
});
12481299
}
12491300

12501301
/**

0 commit comments

Comments
 (0)