Implements two key knowledge module features: **#62 - Backlinks Display:** - Added BacklinksList component to show entries that link to current entry - Fetches backlinks from /api/knowledge/entries/:slug/backlinks - Displays entry title, summary, and link context - Clickable links to navigate to linking entries - Loading, error, and empty states **#64 - Wiki-Link Rendering:** - Added WikiLinkRenderer component to parse and render wiki-links - Supports [[slug]] and [[slug|display text]] syntax - Converts wiki-links to clickable navigation links - Distinct styling (blue color, dotted underline) - XSS protection via HTML escaping - Memoized HTML processing for performance **Components:** - BacklinksList.tsx - Backlinks display with empty/loading/error states - WikiLinkRenderer.tsx - Wiki-link parser and renderer - Updated EntryViewer.tsx to use WikiLinkRenderer - Integrated BacklinksList into entry detail page **API:** - Added fetchBacklinks() function in knowledge.ts - Added KnowledgeBacklink type to shared types **Tests:** - Comprehensive tests for BacklinksList (8 tests) - Comprehensive tests for WikiLinkRenderer (14 tests) - All tests passing with Vitest **Type Safety:** - Strict TypeScript compliance - No 'any' types - Proper error handling
This commit is contained in:
@@ -181,6 +181,55 @@ export async function restoreVersion(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch backlinks for an entry (entries that link to this entry)
|
||||
*/
|
||||
export async function fetchBacklinks(slug: string): Promise<{
|
||||
entry: { id: string; slug: string; title: string };
|
||||
backlinks: Array<{
|
||||
id: string;
|
||||
sourceId: string;
|
||||
targetId: string;
|
||||
linkText: string;
|
||||
displayText: string;
|
||||
positionStart: number;
|
||||
positionEnd: number;
|
||||
resolved: boolean;
|
||||
context: string | null;
|
||||
createdAt: Date;
|
||||
source: {
|
||||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
summary?: string | null;
|
||||
};
|
||||
}>;
|
||||
count: number;
|
||||
}> {
|
||||
return apiGet<{
|
||||
entry: { id: string; slug: string; title: string };
|
||||
backlinks: Array<{
|
||||
id: string;
|
||||
sourceId: string;
|
||||
targetId: string;
|
||||
linkText: string;
|
||||
displayText: string;
|
||||
positionStart: number;
|
||||
positionEnd: number;
|
||||
resolved: boolean;
|
||||
context: string | null;
|
||||
createdAt: Date;
|
||||
source: {
|
||||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
summary?: string | null;
|
||||
};
|
||||
}>;
|
||||
count: number;
|
||||
}>(`/api/knowledge/entries/${slug}/backlinks`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock entries for development (until backend endpoints are ready)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user