mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 10:50:38 +09:00
[codex] Refine markdown issue reference rendering (#4382)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Task references are a core part of how operators understand issue relationships across the UI > - Those references appear both in markdown bodies and in sidebar relationship panels > - The rendering had drifted between surfaces, and inline markdown pills were reading awkwardly inside prose and lists > - This pull request unifies the underlying issue-reference treatment, routes issue descriptions through `MarkdownBody`, and switches inline markdown references to a cleaner text-link presentation > - The benefit is more consistent issue-reference UX with better readability in markdown-heavy views ## What Changed - unified sidebar and markdown issue-reference rendering around the shared issue-reference components - routed resting issue descriptions through `MarkdownBody` so description previews inherit the richer issue-reference treatment - replaced inline markdown pill chrome with a cleaner inline reference presentation for prose contexts - added and updated UI tests for `MarkdownBody` and `InlineEditor` ## Verification - `pnpm exec vitest run --project @paperclipai/ui ui/src/components/MarkdownBody.test.tsx ui/src/components/InlineEditor.test.tsx` ## Risks - Moderate UI risk: issue-reference rendering now differs intentionally between inline markdown and relationship sidebars, so regressions would show up as styling or hover-preview mismatches > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex GPT-5-based coding agent with tool use and code execution in the Codex CLI environment ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
7ad225a198
commit
4fdbbeced3
9 changed files with 314 additions and 44 deletions
|
|
@ -33,7 +33,7 @@ vi.mock("../api/issues", () => ({
|
|||
issuesApi: mockIssuesApi,
|
||||
}));
|
||||
|
||||
function renderMarkdown(children: string, seededIssues: Array<{ identifier: string; status: string }> = []) {
|
||||
function renderMarkdown(children: string, seededIssues: Array<{ identifier: string; status: string; title?: string }> = []) {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
|
|
@ -47,6 +47,7 @@ function renderMarkdown(children: string, seededIssues: Array<{ identifier: stri
|
|||
id: issue.identifier,
|
||||
identifier: issue.identifier,
|
||||
status: issue.status,
|
||||
title: issue.title,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -156,9 +157,22 @@ describe("MarkdownBody", () => {
|
|||
expect(html).toContain('href="/issues/PAP-1271"');
|
||||
expect(html).toContain("text-green-600");
|
||||
expect(html).toContain(">PAP-1271<");
|
||||
expect(html).toContain('data-mention-kind="issue"');
|
||||
expect(html).toContain("paperclip-markdown-issue-ref");
|
||||
expect(html).not.toContain("paperclip-mention-chip--issue");
|
||||
});
|
||||
|
||||
it("uses concise issue aria labels until a distinct title is available", () => {
|
||||
const html = renderMarkdown("Depends on PAP-1271 and PAP-1272.", [
|
||||
{ identifier: "PAP-1271", status: "done" },
|
||||
{ identifier: "PAP-1272", status: "blocked", title: "Fix hover state" },
|
||||
]);
|
||||
|
||||
expect(html).toContain('aria-label="Issue PAP-1271"');
|
||||
expect(html).toContain('aria-label="Issue PAP-1272: Fix hover state"');
|
||||
expect(html).not.toContain('aria-label="Issue PAP-1271: PAP-1271"');
|
||||
});
|
||||
|
||||
it("rewrites full issue URLs to internal issue links", () => {
|
||||
const html = renderMarkdown("See http://localhost:3100/PAP/issues/PAP-1179.", [
|
||||
{ identifier: "PAP-1179", status: "blocked" },
|
||||
|
|
@ -167,9 +181,33 @@ describe("MarkdownBody", () => {
|
|||
expect(html).toContain('href="/issues/PAP-1179"');
|
||||
expect(html).toContain("text-red-600");
|
||||
expect(html).toContain(">http://localhost:3100/PAP/issues/PAP-1179<");
|
||||
expect(html).toContain('data-mention-kind="issue"');
|
||||
expect(html).not.toContain("paperclip-mention-chip--issue");
|
||||
});
|
||||
|
||||
it("linkifies plain internal issue paths in markdown text", () => {
|
||||
const html = renderMarkdown("See /issues/PAP-1179 and /PAP/issues/pap-1180 for context.", [
|
||||
{ identifier: "PAP-1179", status: "blocked" },
|
||||
{ identifier: "PAP-1180", status: "done" },
|
||||
]);
|
||||
|
||||
expect(html).toContain('href="/issues/PAP-1179"');
|
||||
expect(html).toContain('href="/issues/PAP-1180"');
|
||||
expect(html).toContain(">/issues/PAP-1179<");
|
||||
expect(html).toContain(">/PAP/issues/pap-1180<");
|
||||
expect(html).toContain("text-red-600");
|
||||
expect(html).toContain("text-green-600");
|
||||
});
|
||||
|
||||
it("does not auto-link non-issue internal route paths", () => {
|
||||
const html = renderMarkdown("Use /issues/new for the creation form, /issues/PAP-42extra as text, and /api/issues for data.");
|
||||
|
||||
expect(html).toContain("Use /issues/new for the creation form, /issues/PAP-42extra as text, and /api/issues for data.");
|
||||
expect(html).not.toContain('href="/issues/new"');
|
||||
expect(html).not.toContain('href="/issues/PAP-42"');
|
||||
expect(html).not.toContain('data-mention-kind="issue"');
|
||||
});
|
||||
|
||||
it("rewrites issue scheme links to internal issue links", () => {
|
||||
const html = renderMarkdown("See issue://PAP-1310 and issue://:PAP-1311.", [
|
||||
{ identifier: "PAP-1310", status: "done" },
|
||||
|
|
@ -192,6 +230,22 @@ describe("MarkdownBody", () => {
|
|||
expect(html).toContain('href="/issues/PAP-1271"');
|
||||
expect(html).toContain('<code style="overflow-wrap:anywhere;word-break:break-word">PAP-1271</code>');
|
||||
expect(html).toContain("text-green-600");
|
||||
expect(html).toContain("paperclip-markdown-issue-ref");
|
||||
});
|
||||
|
||||
it("keeps trailing punctuation outside auto-linked issue references", () => {
|
||||
const html = renderMarkdown("See PAP-1271: /issues/PAP-1272] and issue://PAP-1273.", [
|
||||
{ identifier: "PAP-1271", status: "done" },
|
||||
{ identifier: "PAP-1272", status: "blocked" },
|
||||
{ identifier: "PAP-1273", status: "todo" },
|
||||
]);
|
||||
|
||||
expect(html).toContain('<a href="/issues/PAP-1271"');
|
||||
expect(html).toContain('>PAP-1271</a>:');
|
||||
expect(html).toContain('<a href="/issues/PAP-1272"');
|
||||
expect(html).toContain('>/issues/PAP-1272</a>]');
|
||||
expect(html).toContain('<a href="/issues/PAP-1273"');
|
||||
expect(html).toContain('>issue://PAP-1273</a>.');
|
||||
});
|
||||
|
||||
it("can opt out of issue reference linkification for offline previews", () => {
|
||||
|
|
@ -277,7 +331,7 @@ describe("MarkdownBody", () => {
|
|||
expect(html).toContain('style="max-width:100%;overflow-x:auto"');
|
||||
});
|
||||
|
||||
it("renders internal issue links and bare identifiers as issue chips", () => {
|
||||
it("renders internal issue links and bare identifiers as inline issue refs", () => {
|
||||
const html = renderMarkdown(`See PAP-42 and [linked task](${buildIssueReferenceHref("PAP-77")}) for follow-up.`, [
|
||||
{ identifier: "PAP-42", status: "done" },
|
||||
{ identifier: "PAP-77", status: "blocked" },
|
||||
|
|
@ -286,5 +340,7 @@ describe("MarkdownBody", () => {
|
|||
expect(html).toContain('href="/issues/PAP-42"');
|
||||
expect(html).toContain('href="/issues/PAP-77"');
|
||||
expect(html).toContain('data-mention-kind="issue"');
|
||||
expect(html).toContain("paperclip-markdown-issue-ref");
|
||||
expect(html).not.toContain("paperclip-mention-chip--issue");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue