Merge dev into main (v0.34.0)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 28s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 28s
This commit is contained in:
commit
ef574945b8
5 files changed
+39
-14
No files matched your search
+7
-1
@@ -6,6 +6,11 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.34.0] - 2026-11-01
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Aufgaben-Detailansicht am PC in zwei Spalten: links breit Titel, Unteraufgaben und Detailnotizen (mit größerem Eingabefeld), rechts schmal alle Einstellungen (Status, Priorität, Fälligkeit, Wiederholung, Liste, Zugewiesen, Hashtags, Herkunft). Am Handy bleibt die Ansicht, wie sie war.
|
||||||
|
|
||||||
## [0.33.0] - 2026-11-01
|
## [0.33.0] - 2026-11-01
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@@ -596,7 +601,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.
|
- 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.
|
- 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.33.0...dev
|
[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.34.0...dev
|
||||||
|
[0.34.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.33.0...v0.34.0
|
||||||
[0.33.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.32.0...v0.33.0
|
[0.33.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.32.0...v0.33.0
|
||||||
[0.32.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.31.0...v0.32.0
|
[0.32.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.31.0...v0.32.0
|
||||||
[0.31.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.30.0...v0.31.0
|
[0.31.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.30.0...v0.31.0
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[](#)
|
[](#)
|
||||||
[](#-schnellstart)
|
[](#-schnellstart)
|
||||||
[](#-deine-daten-gehören-dir)
|
[](#-deine-daten-gehören-dir)
|
||||||
[](CHANGELOG.md)
|
[](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.
|
**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.
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"version": "0.33.0",
|
"version": "0.34.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"version": "0.33.0",
|
"version": "0.34.0",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/inter": "5.3.0",
|
"@fontsource-variable/inter": "5.3.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.33.0",
|
"version": "0.34.0",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 !m-0 modal-overlay z-50 flex items-center justify-center p-3 sm:p-4 overflow-y-auto">
|
<div className="fixed inset-0 !m-0 modal-overlay z-50 flex items-center justify-center p-3 sm:p-4 overflow-y-auto">
|
||||||
<div
|
<div
|
||||||
className="w-full max-w-2xl panel-surface shadow-panel border border-border my-auto flex flex-col max-h-[92vh] max-h-[92dvh] overflow-hidden"
|
className="w-full max-w-2xl lg:max-w-5xl panel-surface shadow-panel border border-border my-auto flex flex-col max-h-[92vh] max-h-[92dvh] overflow-hidden"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{/* Top Header */}
|
{/* Top Header */}
|
||||||
@@ -323,9 +323,14 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
{/* Scrollable Body (all controls disabled for read-only shares) */}
|
{/* Scrollable Body (all controls disabled for read-only shares) */}
|
||||||
{/* The scroll container is a div: a scrolling <fieldset> is unreliable in mobile browsers */}
|
{/* The scroll container is a div: a scrolling <fieldset> is unreliable in mobile browsers */}
|
||||||
<div className="flex-1 min-h-0 overflow-y-auto overscroll-contain [-webkit-overflow-scrolling:touch]">
|
<div className="flex-1 min-h-0 overflow-y-auto overscroll-contain [-webkit-overflow-scrolling:touch]">
|
||||||
<fieldset disabled={readOnly} className="p-4 space-y-4 min-w-0 border-0 m-0">
|
{/* Desktop (lg): two columns, wide left (title, subtasks, notes), narrow right (all settings).
|
||||||
|
Phones and tablets keep the single column in the same order as before. */}
|
||||||
|
<fieldset
|
||||||
|
disabled={readOnly}
|
||||||
|
className="p-4 space-y-4 lg:space-y-0 lg:grid lg:grid-cols-[minmax(0,1fr)_18rem] lg:grid-rows-[auto_auto_1fr] lg:gap-x-6 lg:gap-y-4 min-w-0 border-0 m-0"
|
||||||
|
>
|
||||||
{/* Task Title */}
|
{/* Task Title */}
|
||||||
<div>
|
<div className="lg:col-start-1 lg:row-start-1">
|
||||||
{isEditingTitle ? (
|
{isEditingTitle ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<textarea
|
<textarea
|
||||||
@@ -388,8 +393,10 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Settings: right column on the desktop */}
|
||||||
|
<div className="space-y-4 lg:col-start-2 lg:row-start-1 lg:row-span-3 lg:border-l lg:border-border lg:pl-5">
|
||||||
{/* Kanban Status Buttons */}
|
{/* Kanban Status Buttons */}
|
||||||
<div className="space-y-1.5 pt-1 border-t border-border">
|
<div className="space-y-1.5 pt-1 border-t border-border lg:border-t-0 lg:pt-0">
|
||||||
<label className="block text-xs font-semibold text-main">
|
<label className="block text-xs font-semibold text-main">
|
||||||
Zustand / Kanban-Status:
|
Zustand / Kanban-Status:
|
||||||
</label>
|
</label>
|
||||||
@@ -424,7 +431,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
<label className="block text-xs font-semibold text-main">
|
<label className="block text-xs font-semibold text-main">
|
||||||
Priorität:
|
Priorität:
|
||||||
</label>
|
</label>
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-1.5">
|
<div className="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-2 gap-1.5">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -487,7 +494,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Due Date & List Selection Row */}
|
{/* Due Date & List Selection Row */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 pt-1 border-t border-border">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-3 pt-1 border-t border-border">
|
||||||
{/* Due Date */}
|
{/* Due Date */}
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<label className="block text-xs font-semibold text-main flex items-center gap-1">
|
<label className="block text-xs font-semibold text-main flex items-center gap-1">
|
||||||
@@ -704,8 +711,17 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Origin: in the right column on the desktop (phones show it in the footer) */}
|
||||||
|
{originDetails(task.origin, task.createdAt) && (
|
||||||
|
<div className="hidden lg:block space-y-1 pt-1 border-t border-border">
|
||||||
|
<label className="block text-xs font-semibold text-main">Herkunft:</label>
|
||||||
|
<p className="text-[11px] text-muted leading-snug">{originDetails(task.origin, task.createdAt)}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Subtasks Checklist */}
|
{/* Subtasks Checklist */}
|
||||||
<div className="space-y-2 pt-1 border-t border-border">
|
<div className="space-y-2 pt-1 border-t border-border lg:col-start-1 lg:row-start-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<label className="block text-xs font-semibold text-main flex items-center gap-1.5">
|
<label className="block text-xs font-semibold text-main flex items-center gap-1.5">
|
||||||
<CheckSquare className="w-3.5 h-3.5 text-accent" />
|
<CheckSquare className="w-3.5 h-3.5 text-accent" />
|
||||||
@@ -792,7 +808,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Notes Section */}
|
{/* Notes Section */}
|
||||||
<div className="space-y-2 pt-1 border-t border-border">
|
<div className="space-y-2 pt-1 border-t border-border lg:col-start-1 lg:row-start-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<label className="block text-xs font-semibold text-main flex items-center gap-1.5">
|
<label className="block text-xs font-semibold text-main flex items-center gap-1.5">
|
||||||
<FileText className="w-3.5 h-3.5 text-accent" />
|
<FileText className="w-3.5 h-3.5 text-accent" />
|
||||||
@@ -822,7 +838,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
autoFocus
|
autoFocus
|
||||||
ref={growNotes}
|
ref={growNotes}
|
||||||
onInput={(e) => growNotes(e.currentTarget)}
|
onInput={(e) => growNotes(e.currentTarget)}
|
||||||
className="w-full input-field p-2.5 text-xs font-mono leading-relaxed resize-none min-h-[100px] overflow-hidden"
|
className="w-full input-field p-2.5 text-xs font-mono leading-relaxed resize-none min-h-[100px] lg:min-h-[260px] overflow-hidden"
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-end gap-1.5">
|
<div className="flex justify-end gap-1.5">
|
||||||
<button
|
<button
|
||||||
@@ -880,7 +896,10 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
|||||||
{/* Modal Footer */}
|
{/* Modal Footer */}
|
||||||
<div className="flex items-center justify-between px-4 py-2.5 border-t border-border bg-panel">
|
<div className="flex items-center justify-between px-4 py-2.5 border-t border-border bg-panel">
|
||||||
<div className="text-[11px] text-faint min-w-0 pr-3">
|
<div className="text-[11px] text-faint min-w-0 pr-3">
|
||||||
|
<span className="lg:hidden">
|
||||||
{originDetails(task.origin, task.createdAt) || `Erstellt: ${new Date(task.createdAt).toLocaleDateString('de-DE')}`}
|
{originDetails(task.origin, task.createdAt) || `Erstellt: ${new Date(task.createdAt).toLocaleDateString('de-DE')}`}
|
||||||
|
</span>
|
||||||
|
<span className="hidden lg:inline">Erstellt: {new Date(task.createdAt).toLocaleDateString('de-DE')}</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
Reference in new issue
Block a user