feat(workspace): recursive folder tree, link modal redesign, todo grouping & line jumping, hashtag child listing
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 23s

This commit is contained in:
sandrodach committed 2026-10-27 07:09:48 +01:00
1 parent 6c1898d489
commit 4850f9dfad
6 files changed
+811 -232

No files matched your search

@@ -18,6 +18,7 @@ export interface OutlinerTreeProps {
onMoveBlock: (blockId: string, newIndex: number, level?: number) => void;
onTagClick?: (tag: string) => void;
onWikiLinkClick?: (pageTitle: string) => void;
initialFocusedBlockId?: string | null;
}
export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
@@ -34,14 +35,38 @@ export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
onMoveBlock,
onTagClick,
onWikiLinkClick,
initialFocusedBlockId,
}) => {
const [focusedBlockId, setFocusedBlockId] = useState<string | null>(null);
const [highlightedBlockId, setHighlightedBlockId] = useState<string | null>(
initialFocusedBlockId || null
);
const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);
const textareaMapRef = useRef<Map<string, HTMLTextAreaElement>>(new Map());
const pendingFocusRef = useRef<{ blockId: string; cursor: 'start' | 'end' } | null>(null);
useEffect(() => {
if (initialFocusedBlockId) {
setHighlightedBlockId(initialFocusedBlockId);
const timer = setTimeout(() => {
focusBlockInput(initialFocusedBlockId, 'end');
const el = textareaMapRef.current.get(initialFocusedBlockId);
if (el) {
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}, 80);
const fadeTimer = setTimeout(() => {
setHighlightedBlockId(null);
}, 2500);
return () => {
clearTimeout(timer);
clearTimeout(fadeTimer);
};
}
}, [initialFocusedBlockId]);
const registerTextareaRef = useCallback((blockId: string, el: HTMLTextAreaElement | null) => {
if (el) {
textareaMapRef.current.set(blockId, el);
@@ -304,6 +329,7 @@ export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
onDragOverBlock={handleDragOverBlock}
onDropBlock={handleDropBlock}
isDragTarget={dragOverIndex === index && draggedIndex !== index}
isTargeted={highlightedBlockId === block.id}
registerTextareaRef={registerTextareaRef}
/>
))}