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:
@@ -4,6 +4,7 @@ import { useUiStore } from "../stores/ui";
|
||||
import BaseButton from "../components/BaseButton.vue";
|
||||
import BaseInput from "../components/BaseInput.vue";
|
||||
import Icon from "../components/Icon.vue";
|
||||
import PageHeader from "../components/PageHeader.vue";
|
||||
import DesktopMenuEntry from "../components/DesktopMenuEntry.vue";
|
||||
import {
|
||||
SUGGESTED_CAPTURE_SHORTCUT,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
type UpdateStatus,
|
||||
} from "../desktop/bridge";
|
||||
import { errorMessage } from "../api/errors";
|
||||
import { formatDateTime } from "../notes/datetime";
|
||||
|
||||
// Opt-in server sync for the desktop app. Being UNLINKED is the normal resting
|
||||
// state, not an incomplete setup — the app is local-first and fully usable having
|
||||
@@ -309,11 +311,6 @@ async function disconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
function fmt(iso: string | null): string {
|
||||
if (!iso) return "never";
|
||||
return new Date(iso).toLocaleString();
|
||||
}
|
||||
|
||||
// A background cycle finished — redraw from it, so this screen is never staler
|
||||
// than the board behind it.
|
||||
let stopSyncListener: (() => void) | null = null;
|
||||
@@ -335,23 +332,7 @@ onBeforeUnmount(() => stopSyncListener?.());
|
||||
|
||||
<template>
|
||||
<div class="mx-auto min-h-full max-w-2xl px-4 py-8">
|
||||
<header class="mb-8 flex items-center gap-3">
|
||||
<RouterLink to="/" class="icon-btn" title="Back to board" aria-label="Back to board">
|
||||
<svg
|
||||
class="h-[18px] w-[18px]"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="m15 18-6-6 6-6" />
|
||||
</svg>
|
||||
</RouterLink>
|
||||
<h1 class="text-xl font-bold tracking-tight">Sync</h1>
|
||||
</header>
|
||||
<PageHeader title="Sync" />
|
||||
|
||||
<div v-if="loading" class="py-10 text-center text-sm text-neutral-400">Loading…</div>
|
||||
|
||||
@@ -366,7 +347,7 @@ onBeforeUnmount(() => stopSyncListener?.());
|
||||
</p>
|
||||
<p v-if="linkedAs" class="mt-0.5 text-xs text-neutral-400">as {{ linkedAs }}</p>
|
||||
<p class="mt-1 text-xs text-neutral-400">
|
||||
Last synced {{ fmt(status?.last_sync_at ?? null) }}
|
||||
Last synced {{ formatDateTime(status?.last_sync_at ?? null) }}
|
||||
<span v-if="pending"> · unsent changes on this device</span>
|
||||
</p>
|
||||
<p class="mt-0.5 text-xs text-neutral-400">
|
||||
|
||||
Reference in New Issue
Block a user