M2 checklists: note kind + items backend + editor/card UI
- Migration 0006: notes.kind ('text'|'list') + note_items (text, checked,
position). Item API: add/update(toggle)/delete/reorder; PATCH note kind; note
responses include kind + items[] (merged in one query alongside labels).
- notes store: kind/items on Note, setKind/addItem/updateItem/deleteItem.
- NoteChecklist component (toggle/add/edit/delete items); rendered read-only-ish
on cards (checkboxes toggle) and editable in the editor.
- Editor: convert text<->checklist (body lines become items on convert to list).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -3,6 +3,7 @@ import { useNotesStore } from "../stores/notes";
|
||||
import { NOTE_CARD_CLASSES, type NoteColor } from "../notes/colors";
|
||||
import type { Note } from "../stores/notes";
|
||||
import Icon from "./Icon.vue";
|
||||
import NoteChecklist from "./NoteChecklist.vue";
|
||||
|
||||
defineProps<{ note: Note }>();
|
||||
const emit = defineEmits<{ (e: "open", note: Note): void }>();
|
||||
@@ -18,9 +19,27 @@ function cardClass(color: NoteColor): string {
|
||||
class="group relative mb-4 break-inside-avoid rounded-xl border p-3 shadow-sm transition hover:shadow-md"
|
||||
:class="cardClass(note.color)"
|
||||
>
|
||||
<!-- Checklist notes can't nest interactive controls in a <button>, so use a
|
||||
focusable div; text notes keep a semantic button. -->
|
||||
<template v-if="note.kind === 'list'">
|
||||
<div
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-brand"
|
||||
@click="emit('open', note)"
|
||||
@keydown.enter="emit('open', note)"
|
||||
>
|
||||
<h3 v-if="note.title" class="mb-1 break-words text-sm font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{{ note.title }}
|
||||
</h3>
|
||||
</div>
|
||||
<NoteChecklist class="mt-1" :note-id="note.id" :items="note.items" @click="emit('open', note)" />
|
||||
</template>
|
||||
|
||||
<button
|
||||
v-else
|
||||
type="button"
|
||||
class="block w-full cursor-text text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-transparent rounded"
|
||||
class="block w-full cursor-text rounded text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
|
||||
@click="emit('open', note)"
|
||||
>
|
||||
<h3 v-if="note.title" class="mb-1 break-words text-sm font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
|
||||
Reference in New Issue
Block a user