feat(notes): en note deles ved at ligge i et projekt
Ikke en adgangsliste af sin egen. Projekter har allerede medlemmer, roller og invitationer — alt sammen afprøvet, og alt sammen noget folk har lært her i forvejen. En anden måde at give adgang på er et andet sted at gøre det forkert, og de to ville være uenige den dag, den ene blev ændret. To ting, prøven fandt, som begge var rigtige fejl. Projektsiden viste kun noter, der NÆVNTE projektet, ikke dem, der lå i det — så en note, man lige havde delt derind, dukkede ikke op. Nu vises begge slags. Og noteoversigten viste kun dem uden projekt, så en note forsvandt fra listen i det øjeblik, den blev delt. Det fik deling til at se ud som sletning. Listen viser nu alt, man kan se: sine egne løse, og dem i de projekter, man er med i. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1b02eecdab
commit
1bbae698d5
@@ -108,6 +108,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the note into a project, which is what sharing it means: everybody who
|
||||
* can read the project can read the note, and an editor can change it. Choosing
|
||||
* the empty option takes it back out and makes it the author's alone again.
|
||||
*/
|
||||
async function share(projectId) {
|
||||
if (!selected) return;
|
||||
const id = selected.id;
|
||||
try {
|
||||
const saved = await api.updateNote(id, { project_id: projectId });
|
||||
notes = notes.map((n) => (n.id === id ? saved : n));
|
||||
if (selected?.id === id) selected = saved;
|
||||
app.toast(projectId ? t('notes.shared') : t('notes.unshared'));
|
||||
} catch (e) {
|
||||
app.toast(humanMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
async function remove(note) {
|
||||
if (!confirm(t('notes.deleteNote', { name: note.title || t('notes.untitled') }))) return;
|
||||
try {
|
||||
@@ -192,6 +210,22 @@
|
||||
{/each}
|
||||
</span>
|
||||
{/if}
|
||||
<!-- Sharing a note is filing it in a project.
|
||||
Not an access list of its own: projects already have members, roles
|
||||
and invitations, all of them tested and all of them things people
|
||||
have already learnt here. A second way to give somebody access is a
|
||||
second place to get it wrong, and the two would disagree on the day
|
||||
one of them was changed. -->
|
||||
<label class="share">
|
||||
<span class="hint">{t('notes.shareWith')}</span>
|
||||
<select value={selected.project_id ?? ''} onchange={(e) => share(e.currentTarget.value)}>
|
||||
<option value="">{t('notes.private')}</option>
|
||||
{#each app.projects.filter((p) => !p.is_inbox) as project (project.id)}
|
||||
<option value={project.id}>{project.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<div class="actions">
|
||||
<button class="button" onclick={save}>{t('notes.save')}</button>
|
||||
<button class="button danger" onclick={() => remove(selected)}>{t('notes.delete')}</button>
|
||||
@@ -436,6 +470,17 @@
|
||||
font-family: var(--mono, ui-monospace, monospace);
|
||||
}
|
||||
|
||||
.share {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--s1);
|
||||
}
|
||||
|
||||
.share select {
|
||||
font-size: var(--text-xs);
|
||||
padding: 2px var(--s1);
|
||||
}
|
||||
|
||||
/* Real buttons. They were bare words, which on a Mac reads as a web page rather
|
||||
than as something you can press. */
|
||||
.actions {
|
||||
|
||||
Reference in New Issue
Block a user