Flytt «Ny samtale», «Nytt brett», «Ny samling» til verktøymenyen

Verktøymenyen i header har nå en «Opprett»-seksjon over panellisten
med tre hurtigvalg:
- Ny samtale → oppretter kommunikasjonsnode, navigerer til /chat/[id]
- Nytt brett → oppretter samling med kanban-trait, navigerer til /collection/[id]
- Ny samling → navigerer til /collection/new for full oppsettflyt
This commit is contained in:
vegard 2026-03-19 19:37:28 +00:00
parent 696535d045
commit f28799385c
2 changed files with 78 additions and 2 deletions

View file

@ -27,7 +27,7 @@ Funnet ved manuell testing av frontend. Fikses som en samlet sesjon.
- [x] NodeEditor.svelte og NewChatDialog.svelte slettet (kun brukt av mottak).
- [x] LandingPage.svelte slettet (landingssiden er statisk HTML på synops.no).
- [ ] Alle separate ruter (/chat, /board, /calendar, /diary, /graph, /studio, /collection, /editorial, /admin) blir deep links som åpner workspace med riktig panel.
- [ ] "Ny samtale", "Nytt brett", "Ny samling" flyttes til verktøymeny i header.
- [x] "Ny samtale", "Nytt brett", "Ny samling" flyttes til verktøymeny i header.
- [ ] Dagbok, kalender, graf er paneler du henter fra verktøymenyen.
## Domene/ruting/auth (ferdig)

View file

@ -6,7 +6,7 @@
import type { Node } from '$lib/realtime';
import { getRankedNodeIds, recordVisit } from '$lib/workspace/recency.js';
import { TRAIT_PANEL_INFO } from '$lib/workspace/types.js';
import { updateNode, createNode, createEdge, deleteNode } from '$lib/api';
import { updateNode, createNode, createEdge, deleteNode, createCommunication } from '$lib/api';
import {
type ThemeConfig,
type ThemeSurface,
@ -245,6 +245,56 @@
toolMenuOpen = false;
}
// --- Quick-create actions ---
let isCreatingItem = $state(false);
async function createNewChat() {
if (!accessToken || !userId || isCreatingItem) return;
isCreatingItem = true;
toolMenuOpen = false;
try {
const { node_id } = await createCommunication(accessToken, {
title: 'Ny samtale',
participants: [userId],
visibility: 'hidden',
});
goto(`/chat/${node_id}`);
} catch (e) {
console.error('Feil ved oppretting av samtale:', e);
} finally {
isCreatingItem = false;
}
}
async function createNewBoard() {
if (!accessToken || !userId || isCreatingItem) return;
isCreatingItem = true;
toolMenuOpen = false;
try {
const { node_id } = await createNode(accessToken, {
node_kind: 'collection',
title: 'Nytt brett',
visibility: 'hidden',
metadata: { traits: { kanban: {} } },
});
await createEdge(accessToken, {
source_id: userId,
target_id: node_id,
edge_type: 'owner',
});
goto(`/collection/${node_id}`);
} catch (e) {
console.error('Feil ved oppretting av brett:', e);
} finally {
isCreatingItem = false;
}
}
function createNewCollection() {
toolMenuOpen = false;
goto('/collection/new');
}
// =========================================================================
// Settings menu (theme + sign out)
// =========================================================================
@ -467,6 +517,31 @@
{#if toolMenuOpen}
<div class="tool-menu-dropdown">
<div class="tool-menu-title">Opprett</div>
<button
class="tool-menu-item"
onclick={createNewChat}
disabled={isCreatingItem}
>
<span class="tool-menu-item-icon">💬</span>
<span class="tool-menu-item-label">Ny samtale</span>
</button>
<button
class="tool-menu-item"
onclick={createNewBoard}
disabled={isCreatingItem}
>
<span class="tool-menu-item-icon">📋</span>
<span class="tool-menu-item-label">Nytt brett</span>
</button>
<button
class="tool-menu-item"
onclick={createNewCollection}
>
<span class="tool-menu-item-icon">📁</span>
<span class="tool-menu-item-label">Ny samling</span>
</button>
<div class="tool-menu-divider"></div>
<div class="tool-menu-title">Legg til panel</div>
{#each availableTools as tool (tool.key)}
<button
@ -814,6 +889,7 @@
.tool-menu-item-icon { font-size: 15px; flex-shrink: 0; }
.tool-menu-item-label { flex: 1; }
.tool-menu-item-badge { font-size: 10px; color: var(--color-text-dim, #5a5a66); background: var(--color-surface-hover, #242428); padding: 1px 6px; border-radius: 4px; }
.tool-menu-divider { height: 1px; background: var(--color-border, #2a2a2e); margin: 4px 0; }
/* Status */
.context-status { font-size: 8px; color: #d1d5db; }