Skip to content

Commit 7460ae3

Browse files
committed
fix(note): 左侧组行多选整拖落库与选择模式内批量栏(REQ-287 收尾)
1 parent 33aff9a commit 7460ae3

2 files changed

Lines changed: 22 additions & 9 deletions

File tree

‎app/src/components/GroupSidebar.tsx‎

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import {
2626
import RouteInfoPopover from "./RouteInfoPopover";
2727
import GroupSidebarRow from "./GroupSidebarRow";
2828
import GroupCreateDialog from "./GroupCreateDialog";
29+
// REQ-287:多选拖拽载荷读取(text/note-ids JSON + 单 id 兜底)
30+
import { crateDndReadIds } from "./NoteTreeSection";
2931
import { blobToBase64 } from "../utils/blobToBase64";
3032

3133
interface Props {
@@ -206,15 +208,24 @@ export default function GroupSidebar({
206208
Object.entries(folded).forEach(([kind, value]) => writeFolded(window.localStorage, kind, value));
207209
}, [folded]);
208210

209-
/** 拖拽归组(组行 drop;noteId 来自 NoteListView 行 dragStart) */
211+
/** 拖拽归组(组行 drop;载荷支持多选 JSON + 单 id 兜底——REQ-287 整组拖走) */
210212
const handleGroupDrop = (g: NoteGroup, e: React.DragEvent) => {
211213
e.preventDefault();
212214
setDragOverId(null);
213-
const noteId = Number(e.dataTransfer.getData("text/note-id"));
214-
if (!noteId) return;
215-
invoke("move_note_to_group", { noteId, groupId: g.id })
216-
.then(() => onChanged())
217-
.catch((err) => setStatus(`归组失败: ${err}`));
215+
const ids = crateDndReadIds(e.dataTransfer);
216+
if (ids.length === 0) return;
217+
void (async () => {
218+
let failed = 0;
219+
for (const noteId of ids) {
220+
try {
221+
await invoke("move_note_to_group", { noteId, groupId: g.id });
222+
} catch {
223+
failed += 1;
224+
}
225+
}
226+
if (failed > 0) setStatus(`归组失败 ${failed}/${ids.length} 条`);
227+
onChanged();
228+
})();
218229
};
219230

220231
/** v0.14.1:行内重命名提交(rename_note_group 命令自 v0.11.0 存在,本版接线) */
@@ -248,7 +259,8 @@ export default function GroupSidebar({
248259
onRename={(name) => void handleRename(g, name)}
249260
onOpenSystem={(id) => onOpenSystem(id)}
250261
onDragOver={(e) => {
251-
if (e.dataTransfer.types.includes("text/note-id")) {
262+
// REQ-287:多选载荷(note-ids JSON)+ 单 id 兜底均可落组
263+
if (e.dataTransfer.types.includes("text/note-ids") || e.dataTransfer.types.includes("text/note-id")) {
252264
e.preventDefault();
253265
setDragOverId(g.id);
254266
}

‎app/src/components/NoteListView.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,12 +442,13 @@ export default function NoteListView({
442442
))}
443443
</div>
444444

445-
{/* 批量操作栏(去勾选框后的批量入口:删除 + 移动到组) */}
446-
{selection.size > 0 && !selectionMode && (
445+
{/* 批量操作栏(去勾选框后的批量入口:删除 + 移动到组;选择模式下同样可用) */}
446+
{selection.size > 0 && (
447447
<div style={{ borderTop: "1px solid #e5e7eb", padding: 8, display: "flex", gap: 6, alignItems: "center", background: "#fff" }}>
448448
<span style={{ fontSize: 12, color: "#3730a3" }}>已选 {selection.size} 个</span>
449449
<button data-testid="batch-move-btn" style={ghostBtn} onClick={() => setBatchMenu({ ids: [...selection], x: 0, y: 0 })}>移动到组</button>
450450
<button data-testid="batch-delete-btn" style={{ ...ghostBtn, borderColor: "#fca5a5", color: "#dc2626" }} onClick={() => void (async () => { if (await onBatchDelete([...selection])) clearSelection(); })()}>批量删除</button>
451+
{selectionMode && <button data-testid="batch-done-btn" style={{ ...ghostBtn, color: "#3730a3" }} onClick={exitBatch}>完成</button>}
451452
<button style={{ ...ghostBtn, marginLeft: "auto" }} onClick={clearSelection}>取消</button>
452453
</div>
453454
)}

0 commit comments

Comments
 (0)