Compare commits
2 Commits
05a633458d
...
0a8f374506
| Author | SHA1 | Date |
|---|---|---|
|
|
0a8f374506 | |
|
|
ba4e7f3803 |
|
|
@ -2268,10 +2268,20 @@ html.theme-notebook [data-group-card] .line-through::after {
|
||||||
the app's type scale so notes blend into dialogs instead of looking
|
the app's type scale so notes blend into dialogs instead of looking
|
||||||
pasted in.
|
pasted in.
|
||||||
--------------------------------------------------------------------------- */
|
--------------------------------------------------------------------------- */
|
||||||
.wmde-markdown {
|
/* Prefixed with `html` so this out-specificity the library's own
|
||||||
|
`.wmde-markdown` rules regardless of stylesheet order -- its CSS ships in
|
||||||
|
a lazy chunk that injects after globals.css, and at equal specificity the
|
||||||
|
later sheet would win the cascade. `html.theme-cyberpunk .wmde-markdown`
|
||||||
|
(0,2,1) still overrides this (0,1,1) where the theme wants its own look. */
|
||||||
|
html .wmde-markdown {
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
letter-spacing: -0.006em;
|
letter-spacing: -0.006em;
|
||||||
|
/* The library's GitHub-style palette paints a hard canvas background onto
|
||||||
|
the preview root; make it transparent so styled markdown sits flush with
|
||||||
|
whatever card/box it is rendered inside. */
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--foreground);
|
||||||
}
|
}
|
||||||
.w-md-editor {
|
.w-md-editor {
|
||||||
--md-editor-font-family: var(--font-sans);
|
--md-editor-font-family: var(--font-sans);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { ChevronDown, ChevronRight, Pencil, Plus, Sparkles, Trash2, X, XIcon } from "lucide-react";
|
import { ChevronDown, ChevronRight, Eye, Pencil, Plus, Sparkles, Trash2, X, XIcon } from "lucide-react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
@ -113,6 +113,10 @@ export function GroupSessionDialog({
|
||||||
|
|
||||||
const [noteDraft, setNoteDraft] = useState(group.noteContent);
|
const [noteDraft, setNoteDraft] = useState(group.noteContent);
|
||||||
const [todoDrafts, setTodoDrafts] = useState<TodoDraft[]>(() => toDrafts(group.todos));
|
const [todoDrafts, setTodoDrafts] = useState<TodoDraft[]>(() => toDrafts(group.todos));
|
||||||
|
// Notes default to a rendered markdown preview; the pencil by the label
|
||||||
|
// flips into the full editor (and back). Kept out of the todo row state
|
||||||
|
// so it never collides with per-row edit toggles.
|
||||||
|
const [notesEditing, setNotesEditing] = useState(false);
|
||||||
const [aiOpen, setAiOpen] = useState(false);
|
const [aiOpen, setAiOpen] = useState(false);
|
||||||
const [todoAiOpen, setTodoAiOpen] = useState(false);
|
const [todoAiOpen, setTodoAiOpen] = useState(false);
|
||||||
const [savingAll, setSavingAll] = useState(false);
|
const [savingAll, setSavingAll] = useState(false);
|
||||||
|
|
@ -133,6 +137,7 @@ export function GroupSessionDialog({
|
||||||
if (next) {
|
if (next) {
|
||||||
setNoteDraft(group.noteContent);
|
setNoteDraft(group.noteContent);
|
||||||
setTodoDrafts(toDrafts(group.todos));
|
setTodoDrafts(toDrafts(group.todos));
|
||||||
|
setNotesEditing(false);
|
||||||
} else {
|
} else {
|
||||||
// Fire-and-forget: close immediately, flush any pending autosaves in
|
// Fire-and-forget: close immediately, flush any pending autosaves in
|
||||||
// the background. board-context's mutators already toast on failure,
|
// the background. board-context's mutators already toast on failure,
|
||||||
|
|
@ -247,13 +252,45 @@ export function GroupSessionDialog({
|
||||||
|
|
||||||
<div className="flex-1 space-y-6 overflow-y-auto overscroll-contain p-4">
|
<div className="flex-1 space-y-6 overflow-y-auto overscroll-contain p-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-sm font-medium">Notes</Label>
|
<div className="flex items-center gap-2">
|
||||||
<MDEditor
|
<Label className="text-sm font-medium">Notes</Label>
|
||||||
value={noteDraft}
|
<Button
|
||||||
onChange={(v) => setNoteDraft(v ?? "")}
|
type="button"
|
||||||
height={280}
|
variant="ghost"
|
||||||
preview="edit"
|
size="icon-sm"
|
||||||
/>
|
onClick={() => setNotesEditing((v) => !v)}
|
||||||
|
aria-label={notesEditing ? "Preview notes" : "Edit notes"}
|
||||||
|
>
|
||||||
|
{notesEditing ? <Eye className="size-4" /> : <Pencil className="size-4" />}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{notesEditing ? (
|
||||||
|
<MDEditor
|
||||||
|
value={noteDraft}
|
||||||
|
onChange={(v) => setNoteDraft(v ?? "")}
|
||||||
|
height={280}
|
||||||
|
preview="edit"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
// Rendered as a distinct group-note panel -- full group tint,
|
||||||
|
// stronger rule, no indent -- so it reads as notes for the
|
||||||
|
// whole group rather than another to-do row.
|
||||||
|
<div
|
||||||
|
className="max-h-72 overflow-y-auto rounded-lg border p-4"
|
||||||
|
style={{
|
||||||
|
borderColor: ruleColor,
|
||||||
|
backgroundColor: panelBackground,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{noteDraft.trim() ? (
|
||||||
|
<MarkdownPreview source={noteDraft} />
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
No notes yet — use the pencil above to add some.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -556,7 +593,7 @@ function SessionTodoRow({
|
||||||
onClick={() => setEditingDetails((v) => !v)}
|
onClick={() => setEditingDetails((v) => !v)}
|
||||||
aria-label={`${editingDetails ? "Preview" : "Edit"} details for "${draft.title || "new to-do"}"`}
|
aria-label={`${editingDetails ? "Preview" : "Edit"} details for "${draft.title || "new to-do"}"`}
|
||||||
>
|
>
|
||||||
<Pencil className="size-4" />
|
{editingDetails ? <Eye className="size-4" /> : <Pencil className="size-4" />}
|
||||||
</Button>
|
</Button>
|
||||||
{onCollapse && (
|
{onCollapse && (
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -572,7 +609,7 @@ function SessionTodoRow({
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
className="shrink-0"
|
className="ml-auto shrink-0 text-destructive hover:bg-destructive/10 hover:text-destructive"
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
aria-label={`Delete "${draft.title || "new to-do"}"`}
|
aria-label={`Delete "${draft.title || "new to-do"}"`}
|
||||||
>
|
>
|
||||||
|
|
@ -581,15 +618,18 @@ function SessionTodoRow({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{editingDetails ? (
|
{editingDetails ? (
|
||||||
|
// ml-6 indents the details block (checkbox's 16px + the 8px gap) so
|
||||||
|
// its left edge lines up with the title above instead of the checkbox.
|
||||||
<MDEditor
|
<MDEditor
|
||||||
value={draft.details}
|
value={draft.details}
|
||||||
onChange={(v) => onChangeLocal({ details: v ?? "" })}
|
onChange={(v) => onChangeLocal({ details: v ?? "" })}
|
||||||
height={160}
|
height={160}
|
||||||
preview="edit"
|
preview="edit"
|
||||||
|
className="ml-6"
|
||||||
/>
|
/>
|
||||||
) : draft.details ? (
|
) : draft.details ? (
|
||||||
<div
|
<div
|
||||||
className="max-h-40 overflow-y-auto rounded-md border p-2"
|
className="ml-6 max-h-40 overflow-y-auto rounded-md border p-2"
|
||||||
style={{ borderColor: `color-mix(in srgb, ${accentColor} 25%, transparent)` }}
|
style={{ borderColor: `color-mix(in srgb, ${accentColor} 25%, transparent)` }}
|
||||||
>
|
>
|
||||||
<MarkdownPreview source={draft.details} />
|
<MarkdownPreview source={draft.details} />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue