feat(web): improve comment panel and trigger UI

This commit is contained in:
CREDO23 2026-01-19 14:37:38 +02:00
parent d99722cfdc
commit f008acecfc
8 changed files with 56 additions and 24 deletions

View file

@ -18,7 +18,7 @@ import { transformComment, transformMember } from "./utils";
export function CommentPanelContainer({
messageId,
isOpen,
maxHeight = 400,
maxHeight,
}: CommentPanelContainerProps) {
const { data: commentsData, isLoading: isCommentsLoading } = useComments({
messageId,
@ -70,7 +70,6 @@ export function CommentPanelContainer({
return (
<CommentPanel
messageId={messageId}
threads={commentThreads}
members={members}
membersLoading={isMembersLoading}
@ -84,4 +83,3 @@ export function CommentPanelContainer({
/>
);
}

View file

@ -1,8 +1,5 @@
export interface CommentPanelContainerProps {
messageId: number;
searchSpaceId: number;
isOpen: boolean;
onClose?: () => void;
maxHeight?: number;
}

View file

@ -53,4 +53,3 @@ export function transformMember(membership: Membership): MemberOption {
avatarUrl: membership.user_avatar_url ?? null,
};
}

View file

@ -17,7 +17,7 @@ export function CommentPanel({
onEditComment,
onDeleteComment,
isSubmitting = false,
maxHeight = 400,
maxHeight,
}: CommentPanelProps) {
const [isComposerOpen, setIsComposerOpen] = useState(false);
@ -44,13 +44,17 @@ export function CommentPanel({
const hasThreads = threads.length > 0;
const showEmptyState = !hasThreads && !isComposerOpen;
// Ensure minimum usable height for empty state + composer button
const minHeight = 180;
const effectiveMaxHeight = maxHeight ? Math.max(maxHeight, minHeight) : undefined;
return (
<div className="flex w-80 flex-col rounded-lg border bg-card">
<div
className="flex w-85 flex-col rounded-lg border bg-card"
style={effectiveMaxHeight ? { maxHeight: effectiveMaxHeight } : undefined}
>
{hasThreads && (
<div
className="overflow-y-auto"
style={{ maxHeight }}
>
<div className="min-h-0 flex-1 overflow-y-auto scrollbar-thin">
<div className="space-y-4 p-4">
{threads.map((thread) => (
<CommentThread

View file

@ -2,7 +2,6 @@ import type { CommentThreadData } from "../comment-thread/types";
import type { MemberOption } from "../member-mention-picker/types";
export interface CommentPanelProps {
messageId: number;
threads: CommentThreadData[];
members: MemberOption[];
membersLoading?: boolean;

View file

@ -5,25 +5,32 @@ import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { CommentTriggerProps } from "./types";
export function CommentTrigger({ commentCount, isOpen, onClick }: CommentTriggerProps) {
export function CommentTrigger({ commentCount, isOpen, onClick, disabled }: CommentTriggerProps) {
const hasComments = commentCount > 0;
return (
<Button
variant={isOpen ? "secondary" : "ghost"}
size="sm"
variant={hasComments ? "outline" : isOpen ? "secondary" : "ghost"}
size="icon"
disabled={disabled}
className={cn(
"h-8 gap-1.5 px-2 transition-opacity",
isOpen ? "text-foreground" : "text-muted-foreground",
!hasComments && !isOpen && "opacity-0 group-hover:opacity-100"
"relative size-10 rounded-full transition-all duration-200",
hasComments
? "border-primary/50 bg-primary/5 text-primary hover:bg-primary/10 hover:border-primary"
: isOpen
? "text-foreground"
: "text-muted-foreground hover:text-foreground",
!hasComments && !isOpen && "opacity-0 group-hover:opacity-100",
disabled && "cursor-not-allowed opacity-50"
)}
onClick={onClick}
>
<MessageSquare className={cn("size-4", isOpen && "fill-current")} />
<MessageSquare className={cn("size-5", (hasComments || isOpen) && "fill-current")} />
{hasComments && (
<span className="min-w-5 text-xs font-medium">{commentCount}</span>
<span className="absolute -top-1 -right-1 flex size-5 items-center justify-center rounded-full bg-primary text-[10px] font-bold text-primary-foreground">
{commentCount > 9 ? "9+" : commentCount}
</span>
)}
</Button>
);
}

View file

@ -2,5 +2,5 @@ export interface CommentTriggerProps {
commentCount: number;
isOpen: boolean;
onClick: () => void;
disabled?: boolean;
}