Files
buzz/desktop/src/features/projects/ui/ProjectPanelState.tsx
thomaspblock f0192ea976 polish(projects): streamline overview navigation and state (#6600)
## Summary
- make the Projects overview follow the active section with consistent
context, empty states, and row alignment
- add an animated section-local search that preserves sort and
responsive tab behavior
- simplify sidebar and list controls while keeping large project
collections incrementally mounted

This is Part 6 of the channel-first Projects stack, based on #6597. The
final part contains project workspace aggregation and the default
project-home template.

## Testing
- focused search, activity digest, agent selection, related-channel, and
overview-context tests: 26/26 passed
- Desktop unit suite: 5,451/5,451 passed
- E2E-mode Desktop build passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

## Post-Deploy Monitoring & Validation
- exercise every Projects overview section, search transition, selection
state, and right context rail in staging Desktop
- healthy signals: stable tabs, aligned rows, correct section context,
and responsive large-list interaction
- failure signals: search flicker, stale context, wrapped toolbar rows,
missing empty actions, or input lag; mitigate by reverting this PR

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
2026-08-23 22:14:45 -04:00

46 lines
1.1 KiB
TypeScript

import { CircleAlert, CircleDashed } from "lucide-react";
import type * as React from "react";
import { cn } from "@/shared/lib/cn";
export function ProjectPanelState({
action,
className,
description,
error = false,
panel = true,
testId,
title,
}: {
action?: React.ReactNode;
className?: string;
description?: string;
error?: boolean;
panel?: boolean;
testId?: string;
title: string;
}) {
const Icon = error ? CircleAlert : CircleDashed;
return (
<div
className={cn(
"flex min-h-64 w-full flex-1 flex-col items-center justify-center gap-3 px-6 py-12 text-center",
className,
)}
data-project-detail-panel={panel ? "" : undefined}
data-testid={testId}
>
<Icon className="h-9 w-9 text-muted-foreground/35" />
<div className="max-w-sm space-y-1">
<p className="text-sm font-medium text-foreground">{title}</p>
{description ? (
<p className="text-sm leading-5 text-muted-foreground">
{description}
</p>
) : null}
</div>
{action}
</div>
);
}