web: shared note actions, reminder chips, page header, formatters and settings seam

From the audit (#5179, web half).

- NoteActions: share, pin, archive and trash (restore and delete forever
  when trashed), as both the card and the editor offer them. The editor's
  history toggle goes in its slot, and it closes on `acted`.
- ReminderActions: the Done / 1h / 1d chips on the card and in the editor,
  which are now the same chips.
- PageHeader: the back-to-board header that Settings, Sync and Linked
  devices each wrote out, now with a `back` icon from the shared set.
- notes/datetime: formatShortDateTime (was formatReminder and the editor's
  revLabel) and formatDateTime (the two `fmt` copies).
- notes/colors: labelDotClasses (the sidebar's and the tag manager's
  labelDot).
- Drawer links use exact-active-class instead of route.name ternaries.
- BoardView binds its three grids from one gridBinds object.
- Settings goes through repo.settings (rest, plus a local adapter that
  answers "needs a server") and shows load failures through AsyncState.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 20:02:18 -04:00
co-authored by Claude Opus 5.5
parent 05c82c2362
commit e75e3d37d0
17 changed files with 348 additions and 422 deletions
+14 -28
View File
@@ -281,6 +281,17 @@ async function onDrop(targetId: string) {
order.splice(toIdx, 0, from);
await notes.reorder(order);
}
/** What every grid on this board takes besides its notes: the keyboard focus, and
* opening and reordering cards. */
const gridBinds = computed(() => ({
activeId: focusedId.value,
reorderable: true,
onOpen: openEditor,
onDragstart: onDragStart,
onDragend: onDragEnd,
onDrop,
}));
</script>
<template>
@@ -340,42 +351,17 @@ async function onDrop(targetId: string) {
<template v-if="isMainBoard">
<section v-if="pinnedNotes.length">
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-neutral-400">Pinned</h2>
<NoteGrid
:notes="pinnedNotes"
:active-id="focusedId"
reorderable
@open="openEditor"
@dragstart="onDragStart"
@dragend="onDragEnd"
@drop="onDrop"
/>
<NoteGrid :notes="pinnedNotes" v-bind="gridBinds" />
</section>
<section v-if="otherNotes.length" :class="pinnedNotes.length ? 'mt-8' : ''">
<h2 v-if="pinnedNotes.length" class="mb-2 text-xs font-semibold uppercase tracking-wide text-neutral-400">
Others
</h2>
<NoteGrid
:notes="otherNotes"
:active-id="focusedId"
reorderable
@open="openEditor"
@dragstart="onDragStart"
@dragend="onDragEnd"
@drop="onDrop"
/>
<NoteGrid :notes="otherNotes" v-bind="gridBinds" />
</section>
</template>
<NoteGrid
v-else
:notes="notes.items"
:active-id="focusedId"
reorderable
@open="openEditor"
@dragstart="onDragStart"
@dragend="onDragEnd"
@drop="onDrop"
/>
<NoteGrid v-else :notes="notes.items" v-bind="gridBinds" />
</template>
</AsyncState>
</div>