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
+7 -1
View File
@@ -16,7 +16,7 @@ import type { Device } from "../stores/devices";
import type { TitleEntry } from "../stores/titles";
import type { User } from "../stores/session";
import type { PublicConfig } from "../stores/config";
import type { DeviceToken, Directory, ImportResult, NoteShare, Repo } from "./repo";
import type { DeviceToken, Directory, ImportResult, NoteShare, Repo, ServerSetting } from "./repo";
const NEEDS_SERVER = "That's not available offline — connect a server to use it.";
@@ -91,6 +91,12 @@ export const local: Repo = {
// Sharing is between accounts on a server, so these go to the linked one (#5175).
// Unlinked, each rejects with the core's explanation, which the dialog shows.
settings: {
list: () => Promise.reject<ServerSetting[]>(new Error(NEEDS_SERVER)),
save: () => Promise.reject<ServerSetting[]>(new Error(NEEDS_SERVER)),
sendTestEmail: () => Promise.reject<{ to: string }>(new Error(NEEDS_SERVER)),
},
shares: {
directory: () => invoke<Directory>("shares_directory"),
list: (noteId) => invoke<NoteShare[]>("shares_list", { noteId }),