From 196fe26c726e060cd7d876c805b846830b6367ba Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Wed, 22 Jul 2026 14:36:18 +0200 Subject: [PATCH 1/3] feat(channels): expand truncated task prompts Generated-By: PostHog Code Task-Id: c77b603d-2995-4295-b17b-4e3043ed37a2 --- .../components/ChannelFeedView.test.tsx | 45 ++++++++++++++ .../canvas/components/ChannelFeedView.tsx | 59 +++++++++++++++++-- 2 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 packages/ui/src/features/canvas/components/ChannelFeedView.test.tsx diff --git a/packages/ui/src/features/canvas/components/ChannelFeedView.test.tsx b/packages/ui/src/features/canvas/components/ChannelFeedView.test.tsx new file mode 100644 index 0000000000..6e43636df6 --- /dev/null +++ b/packages/ui/src/features/canvas/components/ChannelFeedView.test.tsx @@ -0,0 +1,45 @@ +import type { Task } from "@posthog/shared/domain-types"; +import { Theme } from "@radix-ui/themes"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, expect, it, vi } from "vitest"; +import { TaskFeedRow } from "./ChannelFeedView"; + +const task = { + id: "task-1", + task_number: 1, + slug: "task-1", + title: "Investigate signup drop-off", + description: "A long prompt that needs to be expanded in the channel feed", + created_at: "2026-07-17T12:00:00.000Z", + updated_at: "2026-07-17T12:00:00.000Z", + origin_product: "user_created", + created_by: { + id: 1, + uuid: "user-1", + email: "person@example.com", + first_name: "A", + last_name: "Person", + }, +} satisfies Task; + +describe("TaskFeedRow", () => { + it("expands a truncated prompt", async () => { + vi.spyOn(HTMLElement.prototype, "scrollHeight", "get").mockReturnValue(60); + vi.spyOn(HTMLElement.prototype, "clientHeight", "get").mockReturnValue(40); + const user = userEvent.setup(); + render( + + + , + ); + + const prompt = screen.getByText(task.description); + expect(prompt).toHaveClass("line-clamp-2"); + + await user.click(screen.getByRole("button", { name: "more" })); + + expect(prompt).not.toHaveClass("line-clamp-2"); + expect(screen.getByRole("button", { name: "less" })).toBeInTheDocument(); + }); +}); diff --git a/packages/ui/src/features/canvas/components/ChannelFeedView.tsx b/packages/ui/src/features/canvas/components/ChannelFeedView.tsx index c0ddffd6bd..1e9aef5cbd 100644 --- a/packages/ui/src/features/canvas/components/ChannelFeedView.tsx +++ b/packages/ui/src/features/canvas/components/ChannelFeedView.tsx @@ -61,10 +61,12 @@ import { Fragment, memo, type ReactNode, + useCallback, useEffect, useLayoutEffect, useMemo, useRef, + useState, } from "react"; // Feed rows poll their reply counts slower than the open thread panel — the @@ -409,6 +411,55 @@ function channelTaskStarter(task: Task): UserBasic | null { : null; } +function ExpandablePrompt({ + children, + lines, +}: { + children: string; + lines: 2 | 4; +}) { + const observerRef = useRef(null); + const [expanded, setExpanded] = useState(false); + const [truncated, setTruncated] = useState(false); + + const measureRef = useCallback( + (body: HTMLDivElement | null) => { + observerRef.current?.disconnect(); + observerRef.current = null; + if (!body || expanded) return; + const measure = () => setTruncated(body.scrollHeight > body.clientHeight); + measure(); + const observer = new ResizeObserver(measure); + observer.observe(body); + observerRef.current = observer; + }, + [expanded], + ); + + return ( +
+ + {children} + + {(truncated || expanded) && ( + + )} +
+ ); +} + export function TaskFeedRow({ task, actions, @@ -451,10 +502,10 @@ export function TaskFeedRow({ - + {prompt || (starter ? "started a new task" : "A new task was started")} - + {children} @@ -569,9 +620,7 @@ function PendingFeedRow({ You now - - {pending.prompt} - + {pending.prompt} Date: Wed, 22 Jul 2026 13:04:12 +0000 Subject: [PATCH 2/3] chore(visual): update storybook baselines 2 updated Run: 97a9a415-0f01-4f2d-a295-870be136abeb Co-authored-by: k11kirky <4571455+k11kirky@users.noreply.github.com> --- apps/code/snapshots.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/code/snapshots.yml b/apps/code/snapshots.yml index 3147f9a2f7..164044a8c1 100644 --- a/apps/code/snapshots.yml +++ b/apps/code/snapshots.yml @@ -85,9 +85,9 @@ snapshots: channels-taskfeedrow--human-started--light: hash: v1.k4693efd2.84c26deb1a587fe061238b3982b555167575893bacc9cd2667d4d3f74646261f.abqc0Voe6FIQFflzDJTv1KewcZ4XxcDz1a0mFlJu7oM channels-taskfeedrow--long-prompt--dark: - hash: v1.k4693efd2.2547e88d76889aa7290c5221ff5ecb674cdb1cd9f1ae5efd211fb648a88037b6.4c9RO1upuz3VijYp2xU2MTNrW_87zWQLX5kRKCYABq4 + hash: v1.k4693efd2.b79b9d4cc5eeeb06f77766f05d21fca4997a155912d6d71f23105a6e58cf5fe6.bqN_eRKXFN0qEz1lD1h_3qWDTUpDDUsIjpvtEL8zdko channels-taskfeedrow--long-prompt--light: - hash: v1.k4693efd2.6b0f609e0155bc3b6e3149714b70d33ef83f7c2ca7b72e6d3a495b8db36828d0.eC5ZQDilDw7Y9EJqhfIdlk186GJjgGbYolZ9cm9Xtt0 + hash: v1.k4693efd2.d07cc4df0bf67388e83ff917dc8bbe73d862f10044c2ef201a2f62042f621271.HauxzRuUxumHY1wAtYSqVPdh3nFT8teGBWpYEOGC_FE channels-taskfeedrow--no-prompt--dark: hash: v1.k4693efd2.9fa967f1a9acdeba0c50a9e45ae649f118ee26938037dbefd1bb0577067b03d4.va1lGsscqLW86-5yCKc3H6pQ8Az7_HBItkgGTnTQiYU channels-taskfeedrow--no-prompt--light: From cea3fce1915242bb9405d37ac8fb644ed951f2d7 Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Wed, 22 Jul 2026 15:06:31 +0200 Subject: [PATCH 3/3] Update packages/ui/src/features/canvas/components/ChannelFeedView.tsx Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- packages/ui/src/features/canvas/components/ChannelFeedView.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui/src/features/canvas/components/ChannelFeedView.tsx b/packages/ui/src/features/canvas/components/ChannelFeedView.tsx index 1e9aef5cbd..0acad53649 100644 --- a/packages/ui/src/features/canvas/components/ChannelFeedView.tsx +++ b/packages/ui/src/features/canvas/components/ChannelFeedView.tsx @@ -450,6 +450,7 @@ function ExpandablePrompt({ {(truncated || expanded) && (