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>
88 lines
2.5 KiB
Vue
88 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import { useNotesStore } from "../stores/notes";
|
|
import { useUiStore } from "../stores/ui";
|
|
import type { Note } from "../stores/notes";
|
|
import Icon from "./Icon.vue";
|
|
|
|
// A note's own actions, as the card and the editor both offer them. Pin and archive
|
|
// are everyone's own (#5176); share and trash are the owner's. A note shared with
|
|
// you is never in your Trash, so restore and delete forever are the owner's too.
|
|
// The default slot sits after Share, for the editor's history toggle.
|
|
const props = defineProps<{ note: Note; own: boolean; canShare: boolean }>();
|
|
const emit = defineEmits<{
|
|
/** A pin, archive, trash, restore or delete landed. The editor closes on it. */
|
|
(e: "acted"): void;
|
|
}>();
|
|
|
|
const notes = useNotesStore();
|
|
const ui = useUiStore();
|
|
|
|
async function act(fn: (id: string) => Promise<unknown>): Promise<void> {
|
|
await fn(props.note.id);
|
|
emit("acted");
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<button
|
|
v-if="canShare && !note.trashed"
|
|
type="button"
|
|
class="icon-btn"
|
|
:class="note.shared ? 'text-brand-700 dark:text-brand' : ''"
|
|
title="Share"
|
|
aria-label="Share"
|
|
@click="ui.openShare(note.id)"
|
|
>
|
|
<Icon name="users" />
|
|
</button>
|
|
<slot />
|
|
<template v-if="note.trashed">
|
|
<template v-if="own">
|
|
<button type="button" class="icon-btn" title="Restore" aria-label="Restore" @click="act(notes.restore)">
|
|
<Icon name="restore" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="icon-btn"
|
|
title="Delete forever"
|
|
aria-label="Delete forever"
|
|
@click="act(notes.deleteForever)"
|
|
>
|
|
<Icon name="trash" />
|
|
</button>
|
|
</template>
|
|
</template>
|
|
<template v-else>
|
|
<button
|
|
type="button"
|
|
class="icon-btn"
|
|
:class="note.pinned ? 'text-brand-700 dark:text-brand' : ''"
|
|
:title="note.pinned ? 'Unpin' : 'Pin'"
|
|
:aria-label="note.pinned ? 'Unpin' : 'Pin'"
|
|
:aria-pressed="note.pinned"
|
|
@click="act((id) => notes.setPinned(id, !note.pinned))"
|
|
>
|
|
<Icon name="pin" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="icon-btn"
|
|
:title="note.archived ? 'Unarchive' : 'Archive'"
|
|
:aria-label="note.archived ? 'Unarchive' : 'Archive'"
|
|
@click="act((id) => notes.setArchived(id, !note.archived))"
|
|
>
|
|
<Icon name="archive" />
|
|
</button>
|
|
<button
|
|
v-if="own"
|
|
type="button"
|
|
class="icon-btn"
|
|
title="Move to trash"
|
|
aria-label="Move to trash"
|
|
@click="act(notes.trash)"
|
|
>
|
|
<Icon name="trash" />
|
|
</button>
|
|
</template>
|
|
</template>
|