Fix: revisions-API brukte created_at men kolonnen heter edited_at
Ga 500 Internal Error når frontend forsøkte å laste revisjoner. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0b52266e70
commit
bc0da66d2a
2 changed files with 95 additions and 23 deletions
|
|
@ -122,11 +122,24 @@
|
||||||
editBody = '';
|
editBody = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let confirmingDelete = $state(false);
|
||||||
|
|
||||||
function handleDelete(e: MouseEvent) {
|
function handleDelete(e: MouseEvent) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
confirmingDelete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmDelete(e: MouseEvent) {
|
||||||
|
e.stopPropagation();
|
||||||
|
confirmingDelete = false;
|
||||||
callbacks.onDelete?.(message.id);
|
callbacks.onDelete?.(message.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelDelete(e: MouseEvent) {
|
||||||
|
e.stopPropagation();
|
||||||
|
confirmingDelete = false;
|
||||||
|
}
|
||||||
|
|
||||||
function handleReply(e: MouseEvent) {
|
function handleReply(e: MouseEvent) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
callbacks.onReply?.(message.id);
|
callbacks.onReply?.(message.id);
|
||||||
|
|
@ -154,7 +167,7 @@
|
||||||
interface Revision {
|
interface Revision {
|
||||||
id: string;
|
id: string;
|
||||||
body: string;
|
body: string;
|
||||||
created_at: string;
|
edited_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let revisions = $state<Revision[]>([]);
|
let revisions = $state<Revision[]>([]);
|
||||||
|
|
@ -253,32 +266,44 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<!-- Flytende toolbar — utenfor layout-flyten -->
|
<!-- Flytende toolbar — gruppert: handlinger | forvaltning -->
|
||||||
<div class="messagebox__toolbar">
|
<div class="messagebox__toolbar">
|
||||||
{#if callbacks.onReply}
|
<div class="messagebox__toolbar-group">
|
||||||
<button class="messagebox__toolbar-btn" title="Svar" onclick={handleReply}>💬</button>
|
{#if callbacks.onReply}
|
||||||
{/if}
|
<button class="messagebox__toolbar-btn" title="Svar" onclick={handleReply}>💬</button>
|
||||||
{#if callbacks.onConvertToKanban}
|
{/if}
|
||||||
<button class="messagebox__toolbar-btn" title="Kanban-kort" onclick={handleConvertToKanban}>📋</button>
|
{#if isOwnMessage && !editing && callbacks.onEdit}
|
||||||
{/if}
|
|
||||||
{#if callbacks.onConvertToCalendar}
|
|
||||||
<button class="messagebox__toolbar-btn" title="Kalenderhendelse" onclick={handleConvertToCalendar}>📅</button>
|
|
||||||
{/if}
|
|
||||||
{#if callbacks.onMagic}
|
|
||||||
<button class="messagebox__toolbar-btn" title="AI-behandling" onclick={handleMagic} disabled={isAiProcessing}>✨</button>
|
|
||||||
{/if}
|
|
||||||
{#if callbacks.onTogglePin}
|
|
||||||
<button class="messagebox__toolbar-btn" title={message.pinned ? 'Løsne' : 'Fest'} onclick={handleTogglePin}>📌</button>
|
|
||||||
{/if}
|
|
||||||
{#if isOwnMessage && !editing}
|
|
||||||
{#if callbacks.onEdit}
|
|
||||||
<button class="messagebox__toolbar-btn" title="Rediger" onclick={startEdit}>✏️</button>
|
<button class="messagebox__toolbar-btn" title="Rediger" onclick={startEdit}>✏️</button>
|
||||||
{/if}
|
{/if}
|
||||||
{#if callbacks.onDelete}
|
{#if callbacks.onConvertToKanban}
|
||||||
<button class="messagebox__toolbar-btn messagebox__toolbar-btn--danger" title="Slett" onclick={handleDelete}>🗑️</button>
|
<button class="messagebox__toolbar-btn" title="Opprett kanban-kort" onclick={handleConvertToKanban}>📋</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if callbacks.onConvertToCalendar}
|
||||||
|
<button class="messagebox__toolbar-btn" title="Opprett kalenderhendelse" onclick={handleConvertToCalendar}>📅</button>
|
||||||
|
{/if}
|
||||||
|
{#if callbacks.onMagic}
|
||||||
|
<button class="messagebox__toolbar-btn" title="AI-behandling" onclick={handleMagic} disabled={isAiProcessing}>✨</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if callbacks.onTogglePin || (isOwnMessage && !editing && callbacks.onDelete)}
|
||||||
|
<div class="messagebox__toolbar-divider"></div>
|
||||||
|
<div class="messagebox__toolbar-group">
|
||||||
|
{#if callbacks.onTogglePin}
|
||||||
|
<button class="messagebox__toolbar-btn" title={message.pinned ? 'Løsne' : 'Fest'} onclick={handleTogglePin}>📌</button>
|
||||||
|
{/if}
|
||||||
|
{#if isOwnMessage && !editing && callbacks.onDelete}
|
||||||
|
<button class="messagebox__toolbar-btn messagebox__toolbar-btn--danger" title="Slett" onclick={handleDelete}>🗑️</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{#if confirmingDelete}
|
||||||
|
<div class="messagebox__confirm-delete">
|
||||||
|
<span>Slette melding?</span>
|
||||||
|
<button class="messagebox__confirm-btn messagebox__confirm-btn--yes" onclick={confirmDelete}>Slett</button>
|
||||||
|
<button class="messagebox__confirm-btn messagebox__confirm-btn--no" onclick={cancelDelete}>Avbryt</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{#if editing}
|
{#if editing}
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div class="messagebox__edit" onkeydown={(e) => { if (e.key === 'Escape') cancelEdit(); }}>
|
<div class="messagebox__edit" onkeydown={(e) => { if (e.key === 'Escape') cancelEdit(); }}>
|
||||||
|
|
@ -472,6 +497,53 @@
|
||||||
background: rgba(220, 38, 38, 0.25);
|
background: rgba(220, 38, 38, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.messagebox__toolbar-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__toolbar-divider {
|
||||||
|
width: 1px;
|
||||||
|
background: #2d3148;
|
||||||
|
margin: 0.1rem 0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-delete {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #f87171;
|
||||||
|
padding: 0.2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-btn {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
padding: 0.15rem 0.4rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-btn--yes {
|
||||||
|
background: rgba(220, 38, 38, 0.3);
|
||||||
|
color: #f87171;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-btn--yes:hover {
|
||||||
|
background: rgba(220, 38, 38, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-btn--no {
|
||||||
|
background: none;
|
||||||
|
color: #8b92a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagebox__confirm-btn--no:hover {
|
||||||
|
color: #e1e4e8;
|
||||||
|
}
|
||||||
|
|
||||||
/* === Inline edit === */
|
/* === Inline edit === */
|
||||||
.messagebox__edit {
|
.messagebox__edit {
|
||||||
margin-top: 0.2rem;
|
margin-top: 0.2rem;
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ export const GET: RequestHandler = async ({ params, locals }) => {
|
||||||
if (!locals.workspace || !locals.user) error(401);
|
if (!locals.workspace || !locals.user) error(401);
|
||||||
|
|
||||||
const revisions = await sql`
|
const revisions = await sql`
|
||||||
SELECT r.id, r.body, r.created_at
|
SELECT r.id, r.body, r.edited_at
|
||||||
FROM message_revisions r
|
FROM message_revisions r
|
||||||
JOIN messages m ON m.id = r.message_id
|
JOIN messages m ON m.id = r.message_id
|
||||||
JOIN nodes n ON n.id = m.id
|
JOIN nodes n ON n.id = m.id
|
||||||
WHERE r.message_id = ${params.messageId}::uuid
|
WHERE r.message_id = ${params.messageId}::uuid
|
||||||
AND n.workspace_id = ${locals.workspace.id}
|
AND n.workspace_id = ${locals.workspace.id}
|
||||||
ORDER BY r.created_at DESC
|
ORDER BY r.edited_at DESC
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return json({ revisions });
|
return json({ revisions });
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue