generated from coulomb/repo-seed
Per-evidence-item export: click Export → Copy as Markdown / Copy as HTML writes a portable citation card to the clipboard. Cmd/Ctrl+Shift+C exports the active evidence as Markdown. - ADR-0007 locks the Markdown + HTML output formats. - New shared types: CitationCard, openContextUrl(), resolveSourceLabel(). - Engine renderers under src/engine/rendering/: renderCitationCardMarkdown, renderCitationCardHtml — snapshot-tested, escape-safe, BEM classes for HTML. - src/work/useExportEvidence.ts wires engine + renderers + clipboard. - EvidenceSidebar gains an Export popover per row + auto-dismissing toast. - E2E test (tests/integration/citation-card-export-e2e.dom.test.tsx) walks PRD scenario steps 10-11 and asserts the clipboard payload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
37 lines
1.3 KiB
TypeScript
37 lines
1.3 KiB
TypeScript
/**
|
|
* Open-context URL — the canonical deep link that lets a citation card
|
|
* reopen the source context that backs it.
|
|
*
|
|
* Implements `wiki/ArchitectureOverview.md` §14.3. The URL shape is:
|
|
*
|
|
* /viewer?document=<documentId>&annotation=<annotationId>
|
|
*
|
|
* Both ids are mandatory. The annotation alone is insufficient because
|
|
* the router needs the document id to mount the right viewer adapter
|
|
* before resolving the annotation's selectors.
|
|
*
|
|
* This convention is stable across persistence modes — when the
|
|
* in-memory engine is replaced by a real backend (ADR-0005), the same
|
|
* URL shape is expected to still resolve.
|
|
*/
|
|
|
|
import type { AnnotationId, DocumentId } from "./ids";
|
|
|
|
export interface OpenContextUrlInput {
|
|
readonly documentId: DocumentId;
|
|
readonly annotationId: AnnotationId;
|
|
}
|
|
|
|
/**
|
|
* Build the deep link for a given (document, annotation) pair.
|
|
*
|
|
* Query-string values are percent-encoded via `encodeURIComponent` so that
|
|
* any future id scheme containing reserved characters (`&`, `=`, `#`) still
|
|
* round-trips.
|
|
*/
|
|
export function openContextUrl(input: OpenContextUrlInput): string {
|
|
const docPart = encodeURIComponent(input.documentId);
|
|
const annPart = encodeURIComponent(input.annotationId);
|
|
return `/viewer?document=${docPart}&annotation=${annPart}`;
|
|
}
|