From 3de6c6088badc6a234897c8ad7dd4ed5411dfcc1 Mon Sep 17 00:00:00 2001 From: Sandro Date: Sun, 1 Nov 2026 16:51:27 +0100 Subject: [PATCH] style: folders without arrow, hashtag row cut off with an expander Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 9 ++++- README.md | 2 +- frontend/package-lock.json | 4 +- frontend/package.json | 2 +- frontend/src/features/triage/TasksView.tsx | 40 ++++++++++++++++++- .../src/features/workspace/WorkspaceView.tsx | 12 ++---- 6 files changed, 53 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f550997..e4a305d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V ## [Unreleased] +## [0.45.1] - 2026-11-01 + +### Changed +- Workspace: Ordner haben keinen Aufklapp-Pfeil mehr; das offene bzw. geschlossene Ordnersymbol zeigt den Zustand. Leere und gefüllte Ordner stehen damit bündig, Notizen in einem Ordner sind gleich weit eingerückt wie Unterordner. +- Aufgaben am PC: Die Hashtag-Zeile scrollt nicht mehr seitlich. Passen nicht alle Hashtags hinein, endet sie mit „…“; ein Klick darauf zeigt alle in mehreren Zeilen, „Weniger“ klappt sie wieder ein. + ## [0.45.0] - 2026-11-01 ### Added @@ -728,7 +734,8 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V - Geteilte Listen (Einkaufs-, Pack- und Checklisten) mit `#Kategorie`-Gruppierung, Mengenangaben und Echtzeit-Abhaken. - Benutzer-, Gruppen- und Admin-Verwaltung (Ersteinrichtungs-Assistent, Einladungscodes, Profilbilder, persönliche API-Keys & Webhook-Ingest `/api/v1/webhooks/ingest`, JSON-Datenexport) sowie CSS-Theme-Engine mit 4 Themes (`Dark`, `Light`, `High Contrast`, `Soft`) und PWA-Unterstützung. -[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.45.0...dev +[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.45.1...dev +[0.45.1]: https://git.dsit.me/sandrodach/MindSift/compare/v0.45.0...v0.45.1 [0.45.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.44.0...v0.45.0 [0.44.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.43.0...v0.44.0 [0.43.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.42.0...v0.43.0 diff --git a/README.md b/README.md index 2204782..1eb6aef 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Self-Hosted](https://img.shields.io/badge/100%25-Self--Hosted-2563eb?style=flat-square)](#) [![Docker](https://img.shields.io/badge/Deployment-Single%20Container-2496ed?style=flat-square&logo=docker&logoColor=white)](#-schnellstart) [![SQLite](https://img.shields.io/badge/Daten-SQLite-003b57?style=flat-square&logo=sqlite&logoColor=white)](#-deine-daten-gehören-dir) -[![Version](https://img.shields.io/badge/Version-v0.45.0-16a34a?style=flat-square)](CHANGELOG.md) +[![Version](https://img.shields.io/badge/Version-v0.45.1-16a34a?style=flat-square)](CHANGELOG.md) **MindSift** ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9404214..194871d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "mindsift-frontend", - "version": "0.45.0", + "version": "0.45.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mindsift-frontend", - "version": "0.45.0", + "version": "0.45.1", "license": "Unlicense", "dependencies": { "@fontsource-variable/inter": "5.3.0", diff --git a/frontend/package.json b/frontend/package.json index bc10609..5ac60e1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "mindsift-frontend", "private": true, - "version": "0.45.0", + "version": "0.45.1", "license": "Unlicense", "type": "module", "scripts": { diff --git a/frontend/src/features/triage/TasksView.tsx b/frontend/src/features/triage/TasksView.tsx index f02a919..ea9930e 100644 --- a/frontend/src/features/triage/TasksView.tsx +++ b/frontend/src/features/triage/TasksView.tsx @@ -203,6 +203,10 @@ export const TasksView: React.FC = ({ // Hashtag filtering, grouping and sorting state const [selectedTag, setSelectedTag] = useState(null); + // Hashtag row on desktop: whether it is cut off, and whether it is opened up into several lines + const tagRowRef = useRef(null); + const [tagsExpanded, setTagsExpanded] = useState(false); + const [tagsOverflow, setTagsOverflow] = useState(false); const [groupBy, setGroupBy] = useState<'none' | 'tag' | 'status' | 'priority' | 'due'>('none'); const [sortBy, setSortBy] = useState<'custom' | 'created' | 'due' | 'priority' | 'alpha'>('custom'); @@ -491,6 +495,17 @@ export const TasksView: React.FC = ({ return Array.from(set).sort(); }, [safeTasks]); + // Cut off? Measured while the row is one line (on resize and when the tags change) + useEffect(() => { + const el = tagRowRef.current; + if (!el || tagsExpanded) return; + const measure = () => setTagsOverflow(el.scrollWidth > el.clientWidth + 1); + measure(); + const ro = new ResizeObserver(measure); + ro.observe(el); + return () => ro.disconnect(); + }, [allAvailableTags, tagsExpanded, viewMode]); + // Filtered tasks for List view const openTasks = safeTasks.filter((t) => !t.isCompleted); const doneTasks = safeTasks.filter((t) => t.isCompleted); @@ -2055,8 +2070,11 @@ export const TasksView: React.FC = ({ {/* Hashtag Filter & Grouping / Sorting Toolbar (Desktop only - on mobile accessible via Logo Menu Filter & Sort) */}
- {/* Hashtag filter chips */} -
+ {/* Hashtag filter chips: one line, cut off with "…" when too many; "…" opens them all in lines */} +
Hashtags: @@ -2089,7 +2107,25 @@ export const TasksView: React.FC = ({ ); })} + {tagsExpanded && ( + + )}
+ {!tagsExpanded && tagsOverflow && ( + + )} {/* Kanban: manage columns and width (the list view has grouping and sorting above the list) */}
diff --git a/frontend/src/features/workspace/WorkspaceView.tsx b/frontend/src/features/workspace/WorkspaceView.tsx index 88f2f88..177f864 100644 --- a/frontend/src/features/workspace/WorkspaceView.tsx +++ b/frontend/src/features/workspace/WorkspaceView.tsx @@ -164,13 +164,7 @@ const FolderTreeItem: React.FC = ({ } className="flex items-center gap-1.5 flex-1 min-w-0 text-left h-full cursor-pointer" > - {hasContent ? ( - isExpanded ? ( - - ) : ( - - ) - ) : null} + {/* No arrow: the open/closed folder icon shows the state, and empty folders line up the same */} {isExpanded ? ( ) : ( @@ -271,7 +265,7 @@ const FolderTreeItem: React.FC = ({ {...docDropProps(d.id)} onMouseDown={(e) => e.shiftKey && e.preventDefault()} onClick={(e) => onDocRowClick(e, d.id, () => onSelectDoc(d.id))} - style={{ paddingLeft: `${(depth + 1) * 12 + 16}px` }} + style={{ paddingLeft: `${(depth + 1) * 12 + 9}px` }} className={`w-full flex items-center gap-2 pr-2 py-1.5 min-h-11 sm:min-h-0 rounded-btn text-left text-sm sm:text-xs cursor-pointer border transition-colors ${ mergeHoverId === d.id ? 'border-accent bg-accent/15 ring-2 ring-accent/30 text-main' @@ -289,7 +283,7 @@ const FolderTreeItem: React.FC = ({ {!hasContent && (
Leer