mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): simplify workspace rail badges (#1462)
Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
@@ -22,16 +22,14 @@ describe("workspaceInitials", () => {
|
||||
});
|
||||
|
||||
describe("workspaceRailIndicators", () => {
|
||||
it("shows a dot for an observed workspace with unread", () => {
|
||||
it("shows no badge for an observed workspace with unread but no mentions", () => {
|
||||
const r = workspaceRailIndicators({ hasUnread: true, state: "ready" });
|
||||
assert.equal(r.showDot, true);
|
||||
assert.equal(r.showBadge, false);
|
||||
assert.equal(r.pending, false);
|
||||
});
|
||||
|
||||
it("shows no dot for an observed workspace with no unread", () => {
|
||||
it("shows no badge for an observed workspace with no unread", () => {
|
||||
const r = workspaceRailIndicators({ hasUnread: false, state: "ready" });
|
||||
assert.equal(r.showDot, false);
|
||||
assert.equal(r.showBadge, false);
|
||||
assert.equal(r.pending, false);
|
||||
});
|
||||
@@ -42,7 +40,6 @@ describe("workspaceRailIndicators", () => {
|
||||
count: 3,
|
||||
state: "ready",
|
||||
});
|
||||
assert.equal(r.showDot, true);
|
||||
assert.equal(r.showBadge, true);
|
||||
assert.equal(r.mentionCount, 3);
|
||||
assert.equal(r.badgeLabel, "3");
|
||||
@@ -57,13 +54,12 @@ describe("workspaceRailIndicators", () => {
|
||||
assert.equal(r.badgeLabel, "99+");
|
||||
});
|
||||
|
||||
it("never reports unread for an unobserved (unknown) workspace", () => {
|
||||
it("never reports mentions for an unobserved (unknown) workspace", () => {
|
||||
const r = workspaceRailIndicators({
|
||||
hasUnread: true,
|
||||
count: 5,
|
||||
state: "unknown",
|
||||
});
|
||||
assert.equal(r.showDot, false);
|
||||
assert.equal(r.showBadge, false);
|
||||
assert.equal(r.mentionCount, 0);
|
||||
assert.equal(r.pending, true);
|
||||
@@ -72,16 +68,15 @@ describe("workspaceRailIndicators", () => {
|
||||
it("treats loading as pending, not as no-unread", () => {
|
||||
const r = workspaceRailIndicators({ hasUnread: false, state: "loading" });
|
||||
assert.equal(r.pending, true);
|
||||
assert.equal(r.showDot, false);
|
||||
assert.equal(r.showBadge, false);
|
||||
});
|
||||
|
||||
it("never reports unread on an errored observation", () => {
|
||||
it("never reports mentions on an errored observation", () => {
|
||||
const r = workspaceRailIndicators({
|
||||
hasUnread: true,
|
||||
count: 2,
|
||||
state: "error",
|
||||
});
|
||||
assert.equal(r.showDot, false);
|
||||
assert.equal(r.showBadge, false);
|
||||
assert.equal(r.mentionCount, 0);
|
||||
assert.equal(r.pending, false);
|
||||
|
||||
@@ -28,12 +28,11 @@ export function workspaceInitials(name: string): string {
|
||||
|
||||
/**
|
||||
* Presentation decisions for one workspace button, derived from its observed
|
||||
* unread state. Pure so it can be unit-tested without a DOM. The `state` guard
|
||||
* ensures we NEVER render a "no unread" affordance for a relay we could not
|
||||
* observe (`unknown`/`loading`/`error`) — only a `ready` observation is trusted.
|
||||
* mention state. Pure so it can be unit-tested without a DOM. The `state` guard
|
||||
* ensures we NEVER render a mention badge for a relay we could not observe
|
||||
* (`unknown`/`loading`/`error`) — only a `ready` observation is trusted.
|
||||
*/
|
||||
export function workspaceRailIndicators(unread: WorkspaceUnreadState): {
|
||||
showDot: boolean;
|
||||
mentionCount: number;
|
||||
showBadge: boolean;
|
||||
pending: boolean;
|
||||
@@ -43,7 +42,6 @@ export function workspaceRailIndicators(unread: WorkspaceUnreadState): {
|
||||
const mentionCount = observed ? (unread.count ?? 0) : 0;
|
||||
const showBadge = mentionCount > 0;
|
||||
return {
|
||||
showDot: observed && unread.hasUnread,
|
||||
mentionCount,
|
||||
showBadge,
|
||||
pending: unread.state === "unknown" || unread.state === "loading",
|
||||
@@ -63,7 +61,7 @@ function WorkspaceButton({
|
||||
unread: WorkspaceUnreadState;
|
||||
onSwitch: () => void;
|
||||
}) {
|
||||
const { showDot, mentionCount, showBadge, pending, badgeLabel } =
|
||||
const { mentionCount, showBadge, pending, badgeLabel } =
|
||||
workspaceRailIndicators(unread);
|
||||
|
||||
const tooltipLabel = showBadge
|
||||
@@ -81,18 +79,6 @@ function WorkspaceButton({
|
||||
onClick={onSwitch}
|
||||
type="button"
|
||||
>
|
||||
{/* Active/unread indicator pill on the left edge (Discord-style). */}
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"absolute left-[-6px] w-1 rounded-r-full bg-primary transition-all",
|
||||
isActive
|
||||
? "h-6 opacity-100"
|
||||
: showDot
|
||||
? "h-2 opacity-100"
|
||||
: "h-2 opacity-0",
|
||||
)}
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
"flex h-9 w-9 items-center justify-center rounded-2xl text-xs font-semibold transition-all",
|
||||
@@ -106,7 +92,7 @@ function WorkspaceButton({
|
||||
</span>
|
||||
{showBadge ? (
|
||||
<span
|
||||
className="absolute -bottom-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 text-2xs font-semibold text-destructive-foreground ring-2 ring-sidebar"
|
||||
className="absolute -bottom-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-2xs font-semibold text-primary-foreground ring-2 ring-sidebar"
|
||||
data-testid={`workspace-rail-mentions-${workspace.id}`}
|
||||
>
|
||||
{badgeLabel}
|
||||
@@ -121,8 +107,8 @@ function WorkspaceButton({
|
||||
|
||||
/**
|
||||
* Discord/Slack-style vertical rail of workspaces on the far left of the app.
|
||||
* Shows an unread dot and a mention-count badge for inactive workspaces
|
||||
* (observed via `useWorkspaceUnread`) and switches relays on click.
|
||||
* Shows a mention-count badge for inactive workspaces (observed via
|
||||
* `useWorkspaceUnread`) and switches relays on click.
|
||||
*
|
||||
* Hidden entirely with a single workspace — a rail of one adds no value.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user