Skip to content

Commit

Permalink
feat: improve file delete confirmation message and styling (#4333)
Browse files Browse the repository at this point in the history
* fix: range select clears root directory selection on shift-click

* feat: improve file delete confirmation message and styling

* chore: use constant for max file display count

* fix: handle dialog button text based on OS in tests

* fix: update dialog button logic for Linux systems
  • Loading branch information
erha19 authored Feb 10, 2025
1 parent a25ba3a commit bfefebb
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/components/src/style/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ h5,
h6 {
margin-top: 0;
margin-bottom: 0.5em;
color: @heading-color;
color: inherit;
font-weight: 500;
}

Expand Down
6 changes: 6 additions & 0 deletions packages/design/src/browser/style/design.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,12 @@
margin: 0 5px;
}

[role='treeitem'] {
[class*='mod_actived__'] {
outline: 1px solid var(--kt-tree-inactiveSelectionBackground);
}
}

.design-kt_split_panel {
padding-bottom: 8px;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,19 @@ import {
IClipboardService,
IContextKey,
IStorage,
MessageType,
STORAGE_NAMESPACE,
StorageProvider,
ThrottledDelayer,
Throttler,
URI,
arrays,
formatLocalize,
isLinux,
localize,
path,
strings,
toMarkdown,
} from '@opensumi/ide-core-browser';
import { ResourceContextKey } from '@opensumi/ide-core-browser/lib/contextkey/resource';
import { AbstractContextMenuService, ICtxMenuRenderer, MenuId } from '@opensumi/ide-core-browser/lib/menu/next';
Expand Down Expand Up @@ -725,6 +728,10 @@ export class FileTreeModelService {
};

handleItemRangeClick = (item: File | Directory, type: TreeNodeType) => {
// 由于文件树存在选择根目录的逻辑,使用 Shift+Click 时需要清理根目录选中态
if (this.selectedFiles.length === 1 && Directory.isRoot(this.selectedFiles[0])) {
this.clearFileSelectedDecoration();
}
if (!this.focusedFile) {
this.handleItemClick(item, type);
} else if (this.focusedFile && this.focusedFile !== item) {
Expand All @@ -744,7 +751,10 @@ export class FileTreeModelService {
if (type !== TreeNodeType.CompositeTreeNode && type !== TreeNodeType.TreeNode) {
return;
}

// 由于文件树存在选择根目录的逻辑,使用 Cmd/Ctrl+Click 时需要清理根目录选中态
if (this.selectedFiles.length === 1 && Directory.isRoot(this.selectedFiles[0])) {
this.clearFileSelectedDecoration();
}
// 根据节点的选中态进行复选操作
this.toggleFileSelectedDecoration(item);
};
Expand Down Expand Up @@ -977,18 +987,29 @@ export class FileTreeModelService {
if (uris.length === 0) {
return;
}
// 默认过滤掉根目录的选择
if (this.corePreferences['explorer.confirmDelete']) {
const ok = localize('file.confirm.delete.ok');
const ok = isLinux ? localize('file.confirm.delete.ok') : localize('file.confirm.moveToTrash.ok');
const cancel = localize('file.confirm.delete.cancel');
const deleteFilesMessage = `[ ${uris
.slice(0, 5)
const MAX_FILES = 10;
let deleteFilesMessage = uris
.slice(0, MAX_FILES)
.map((uri) => uri.displayName)
.join(',')}${uris.length > 5 ? ' ...' : ''} ]`;

const confirm = await this.dialogService.warning(formatLocalize('file.confirm.delete', deleteFilesMessage), [
cancel,
ok,
]);
.join(' \n');
if (uris.length > MAX_FILES) {
deleteFilesMessage += ' \n...';
}
if (!isLinux) {
deleteFilesMessage += `\n\n<small>${localize('file.confirm.deleteTips')}</small>`;
}
const confirm = await this.dialogService.open({
message: toMarkdown(formatLocalize('file.confirm.delete', uris.length, deleteFilesMessage)),
type: MessageType.Warning,
props: {
width: 580,
},
buttons: [cancel, ok],
});
if (confirm !== ok) {
return;
}
Expand Down Expand Up @@ -1709,7 +1730,8 @@ export class FileTreeModelService {
this._nextLocationTarget = undefined;
}
};
selectChildNode(uris: URI[]) {

public selectChildNode(uris: URI[]) {
for (const uri of uris) {
const file = this.fileTreeService.getNodeByPathOrUri(uri);

Expand All @@ -1721,7 +1743,7 @@ export class FileTreeModelService {
const last = children[children.length - 1];
const firstIndex = this.treeModel.root.getIndexAtTreeNode(first);
const lastIndex = this.treeModel.root.getIndexAtTreeNode(last);

this._isMultiSelected = true;
this.activeFileDecorationByRange(firstIndex, lastIndex);
}
}
Expand Down
6 changes: 4 additions & 2 deletions packages/i18n/src/common/en-US.lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ export const localizationBundle = {
'file.open.folder': 'Open Folder',
'file.open.workspace': 'Open Workspace from File ...',
'file.action.collapse': 'Collapse',
'file.confirm.delete': 'Are you sure you want to delete the following files?\n{0}',
'file.confirm.delete.ok': 'Move to trash',
'file.confirm.delete': '### Are you sure you want to delete the following {0} files? \n{1}',
'file.confirm.deleteTips': 'You can restore files from the Trash',
'file.confirm.moveToTrash.ok': 'Move to trash',
'file.confirm.delete.ok': 'Delete',
'file.confirm.delete.cancel': 'Cancel',
'file.confirm.move': 'Are you sure you want to move file {0} to {1}?',
'file.confirm.move.ok': 'Move',
Expand Down
6 changes: 4 additions & 2 deletions packages/i18n/src/common/zh-CN.lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ export const localizationBundle = {
'file.location': '在文件树中定位',
'file.open.folder': '打开文件夹',
'file.open.workspace': '从文件打开工作区',
'file.confirm.delete': '确定删除下面列的文件?\n{0}',
'file.confirm.delete.ok': '移入回收站',
'file.confirm.delete': '###确定从工作区删除下面的 {0} 个文件? \n{1}',
'file.confirm.deleteTips': '你可以从回收站还原文件',
'file.confirm.moveToTrash.ok': '移入回收站',
'file.confirm.delete.ok': '删除',
'file.confirm.delete.cancel': '取消',
'file.confirm.move': '确定移动文件 {0} 到 {1} ?',
'file.confirm.move.ok': '移动',
Expand Down
4 changes: 2 additions & 2 deletions tools/playwright/src/tests/explorer-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from 'path';

import { expect } from '@playwright/test';

import { isWindows } from '@opensumi/ide-utils';
import { isLinux, isWindows } from '@opensumi/ide-utils';

import { OpenSumiApp } from '../app';
import { OpenSumiExplorerView } from '../explorer-view';
Expand Down Expand Up @@ -307,7 +307,7 @@ console.log(a);`,
const deleteMenu = await menu?.menuItemByName('Delete');
await deleteMenu?.click();
await app.page.waitForTimeout(200);
const confirmed = await app.getDialogButton('Move to trash');
const confirmed = await app.getDialogButton(!isLinux ? 'Move to Trash' : 'Delete');
await confirmed?.click();
await app.page.waitForTimeout(2000);
const afterDeleteNode = await explorer.getFileStatTreeNodeByPath('test/a/d');
Expand Down
4 changes: 3 additions & 1 deletion tools/playwright/src/tests/search-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import path from 'path';

import { expect } from '@playwright/test';

import { isLinux } from '@opensumi/ide-utils';

import { OpenSumiApp } from '..';
import { OpenSumiDiffEditor } from '../diff-editor';
import { OpenSumiExplorerView } from '../explorer-view';
Expand Down Expand Up @@ -219,7 +221,7 @@ test.describe('OpenSumi Search Panel', () => {
const deleteMenu = await menu?.menuItemByName('Delete');
await deleteMenu?.click();
await app.page.waitForTimeout(200);
const confirmed = await app.getDialogButton('Move to trash');
const confirmed = await app.getDialogButton(!isLinux ? 'Move to Trash' : 'Delete');
await confirmed?.click();
await app.page.waitForTimeout(2000);

Expand Down

1 comment on commit bfefebb

@opensumi
Copy link
Contributor

@opensumi opensumi bot commented on bfefebb Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Next publish successful!

3.7.1-next-1739178825.0

Please sign in to comment.