feat: select text across bullets and delete it like a text editor; Ctrl+Z in tasks; notes and lists without emoji; custom done columns complete tasks
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m33s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m33s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e2b9daba75
commit
6fb98d4002
27 files changed
+535
-64
No files matched your search
@@ -25,6 +25,7 @@ import {
|
||||
Redo2,
|
||||
MoreHorizontal,
|
||||
CalendarDays,
|
||||
SmilePlus,
|
||||
} from 'lucide-react';
|
||||
import { Document, DocumentBlock, User } from '../../lib/types';
|
||||
import { api } from '../../lib/api';
|
||||
@@ -708,6 +709,19 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
[docId, canEdit, applyLocalBlocks]
|
||||
);
|
||||
|
||||
// A selection over several bullets was deleted (OutlinerTree): one change, so Strg+Z undoes it at once
|
||||
const handleReplaceRange = useCallback(
|
||||
(first: DocumentBlock, deleteIds: string[], movedChildren: DocumentBlock[]) => {
|
||||
if (!canEdit) return;
|
||||
const changed = new Map([first, ...movedChildren].map((b) => [b.id, b]));
|
||||
const gone = new Set(deleteIds);
|
||||
applyLocalBlocks((prev) =>
|
||||
ensureNonEmptyBlocks(docId, prev.filter((b) => !gone.has(b.id)).map((b) => changed.get(b.id) || b))
|
||||
);
|
||||
},
|
||||
[docId, canEdit, applyLocalBlocks]
|
||||
);
|
||||
|
||||
// Swaps a bullet (with its children) with the previous or next one on the same level, within the same
|
||||
// parent. By id, not by index, so it also works while zoomed into a branch (the tree then sees a slice).
|
||||
const handleMoveSibling = useCallback(
|
||||
@@ -1254,6 +1268,7 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
onCreateBlock={handleCreateBlock}
|
||||
onInsertBlocks={handleInsertBlocks}
|
||||
onDeleteBlock={handleDeleteBlock}
|
||||
onReplaceRange={handleReplaceRange}
|
||||
onMoveBlock={handleMoveBlock}
|
||||
onMoveSibling={handleMoveSibling}
|
||||
onOpenTask={onOpenTask}
|
||||
@@ -1286,12 +1301,15 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
}`}
|
||||
title={inJournal ? undefined : 'Icon ändern'}
|
||||
>
|
||||
{/* Journal days: a quiet calendar in the theme's text colour instead of the colourful emoji */}
|
||||
{/* Journal days: a quiet calendar in the theme's text colour instead of the colourful emoji;
|
||||
a note without an icon shows a faint "choose icon" to editors only */}
|
||||
{inJournal ? (
|
||||
<CalendarDays className="w-6 h-6 sm:w-7 sm:h-7 text-muted" strokeWidth={1.75} />
|
||||
) : (
|
||||
doc?.icon || '🗒️'
|
||||
)}
|
||||
) : doc?.icon ? (
|
||||
doc.icon
|
||||
) : canEdit ? (
|
||||
<SmilePlus className="w-6 h-6 sm:w-7 sm:h-7 text-faint" strokeWidth={1.5} aria-label="Icon wählen" />
|
||||
) : null}
|
||||
</button>
|
||||
{showEmojiPicker && canEdit && (
|
||||
<EmojiPickerModal
|
||||
@@ -1352,6 +1370,7 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
onCreateBlock={handleCreateBlock}
|
||||
onInsertBlocks={handleInsertBlocks}
|
||||
onDeleteBlock={handleDeleteBlock}
|
||||
onReplaceRange={handleReplaceRange}
|
||||
onMoveBlock={handleMoveBlock}
|
||||
onMoveSibling={handleMoveSibling}
|
||||
onOpenTask={onOpenTask}
|
||||
|
||||
Reference in new issue
Block a user