M3 wiki-links: [[links]] + backlinks
- Migration 0009: note_links (source_id, target_norm). Parse [[...]] from body on
create/update and rewrite the source's links. GET /api/notes/titles (owner
{id,title} index for client-side resolution); GET /api/notes/<id>/backlinks.
- Frontend: titles store; LinkedText renders [[Title]] styled on cards; editor
shows Links (outgoing, resolve/create-on-click) + Linked-from (backlinks),
clicking navigates the editor to the target note (board + search).
- notes store: fetchOne, createTitled. DB-free link-parser tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import { api } from "../api/client";
|
||||
|
||||
export interface TitleEntry {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
// Owner's {id,title} index, used to resolve [[wiki-links]] client-side.
|
||||
export const useTitlesStore = defineStore("titles", () => {
|
||||
const items = ref<TitleEntry[]>([]);
|
||||
const loaded = ref(false);
|
||||
|
||||
async function load(): Promise<void> {
|
||||
if (loaded.value) return;
|
||||
const res = await api.get<{ titles: TitleEntry[] }>("/api/notes/titles");
|
||||
items.value = res.titles;
|
||||
loaded.value = true;
|
||||
}
|
||||
|
||||
async function reload(): Promise<void> {
|
||||
loaded.value = false;
|
||||
await load();
|
||||
}
|
||||
|
||||
function resolve(title: string): TitleEntry | null {
|
||||
const norm = title.trim().toLowerCase();
|
||||
return items.value.find((t) => t.title.trim().toLowerCase() === norm) ?? null;
|
||||
}
|
||||
|
||||
return { items, loaded, load, reload, resolve };
|
||||
});
|
||||
Reference in New Issue
Block a user