Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export type {
BoardColumnDef,
BoardPriority,
BoardTicket,
BoardTicketActivity,
BoardTicketActivityKind,
BoardTicketAssignee,
BoardTicketPendingApproval,
} from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,7 @@ import { cn } from '../../../utils/cn';
import { formatTicketRelativeTime, formatTicketFullTimestamp } from '../../../utils/date-utils';
import { holdMoveDragEffect } from '../../../utils/drag-effect';
import { getReadableTextColor } from '../../../utils/ods-color-utils';
import {
ClockIcon,
DotsLoaderIcon,
LaptopIcon,
Flag02Icon,
MessagesIcon,
UserCheckIcon,
} from '../../icons-v2-generated';
import { LaptopIcon, Flag02Icon, MessagesIcon, UserCheckIcon } from '../../icons-v2-generated';
import { DeletedUserAvatar } from '../../ui/deleted-user-avatar';
import { SquareAvatar } from '../../ui/square-avatar';
import { Tag } from '../../ui/tag';
Expand All @@ -37,7 +30,7 @@ import { BoardTicketApproval } from './board-ticket-approval';
import { useBoardLift, useDropAim } from './drop-aim';
import { DROP_LINE_ATTRIBUTE } from './lane-geometry';
import { useIsLanding } from './pending-move';
import type { BoardPriority, BoardTicket, BoardTicketActivityKind } from './types';
import type { BoardPriority, BoardTicket } from './types';
import { TICKET_ID_ATTRIBUTE } from './use-lane-scroll-anchor';

const PRIORITY_COLOR_CLASS: Record<BoardPriority, string> = {
Expand All @@ -57,13 +50,6 @@ export const DRAG_PREVIEW_OPACITY = 0.9;
const MAX_VISIBLE_TAGS = 2;
const MAX_VISIBLE_ASSIGNEES = 3;

const ACTIVITY_DEFAULT_LABEL: Record<BoardTicketActivityKind, string> = {
'ai-working': 'AI assistant is working',
'user-typing': 'User typing',
'waiting-external': 'Waiting for client response',
stale: 'No activity',
};

/** Shared card shell (border / padding / bg). Same footprint for the draggable
* board card and the static {@link TicketCardView}. */
const TICKET_CARD_SHELL =
Expand Down Expand Up @@ -172,21 +158,6 @@ export function TicketCardBody({ ticket, columnColor, renderAssignSlot, onApprov
<span className="truncate">Escalated by User</span>
</div>
)}
{ticket.activity && (
<div
className={cn(
'flex items-center gap-[var(--spacing-system-xxs)] text-h6',
ticket.activity.kind === 'stale' ? 'text-ods-open-yellow' : 'text-ods-text-secondary',
)}
>
{ticket.activity.kind === 'stale' ? (
<ClockIcon className="size-4 shrink-0" />
) : (
<DotsLoaderIcon className="size-4 shrink-0" />
)}
<span className="truncate">{ticket.activity.label ?? ACTIVITY_DEFAULT_LABEL[ticket.activity.kind]}</span>
</div>
)}
{showNewMessage && (
<Tag
label="New Message"
Expand Down
20 changes: 0 additions & 20 deletions openframe-frontend-core/src/components/features/board/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,6 @@ export interface BoardTicketAssignee {
deleted?: boolean;
}

/**
* Live-activity footer indicator on a board card. Indicators are mutually
* exclusive by design — the consumer decides which single one a ticket shows
* (staleness has the lowest priority and must be suppressed when any other
* signal — new message, approval, escalation — is present).
*/
export type BoardTicketActivityKind = 'ai-working' | 'user-typing' | 'waiting-external' | 'stale';

export interface BoardTicketActivity {
kind: BoardTicketActivityKind;
/**
* Overrides the built-in label for the kind. Required in practice for
* 'stale', whose label carries the computed duration ("No activity for
* 2 hours") that only the consumer can know — and tick over time.
*/
label?: string;
}

export interface BoardTicket {
id: string;
title: string;
Expand All @@ -61,8 +43,6 @@ export interface BoardTicket {
* technician should pick it up.
*/
escalatedByUser?: boolean;
/** Single live-activity indicator rendered as the card's footer row. */
activity?: BoardTicketActivity;
}

export interface BoardColumnDef {
Expand Down
41 changes: 1 addition & 40 deletions openframe-frontend-core/src/stories/TicketCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
import type { PendingToolCallData } from '../components/chat/types';
import {
TicketCard,
type TicketCardProps,
type BoardTicket,
type BoardTicketActivityKind,
} from '../components/features/board';
import { TicketCard, type TicketCardProps, type BoardTicket } from '../components/features/board';

// =============================================================================
// Harness — the card registers its own drag behaviour against the DOM and needs
Expand Down Expand Up @@ -154,40 +149,6 @@ export const EscalatedByUser: Story = {
},
};

/**
* The `activity` footer row, one card per kind. The three live kinds (animated
* dots loader + grey text) fall back to their built-in labels; `stale` (clock +
* amber text) carries a consumer-computed duration label, since only the
* consumer knows the ticket's idle time — and keeps it ticking.
*/
export const ActivityIndicators: Story = {
render: () => {
const activities: { kind: BoardTicketActivityKind; label?: string }[] = [
{ kind: 'ai-working' },
{ kind: 'user-typing' },
{ kind: 'waiting-external' },
{ kind: 'stale', label: 'No activity for 2 hours' },
];
return (
<div className="flex w-[320px] flex-col gap-[var(--spacing-system-sf)] rounded-lg bg-ods-card p-[var(--spacing-system-sf)]">
{activities.map(activity => (
<TicketCard
key={activity.kind}
columnId="ACTIVE"
ticket={{
...BASE_TICKET,
id: `ticket-activity-${activity.kind}`,
priority: undefined,
tags: undefined,
activity,
}}
/>
))}
</div>
);
},
};

/**
* Pending CLIENT approval — collapsed grey "Pending client approval" row with a
* loader glyph. Expand it to reach the shared approve/reject affordance.
Expand Down
Loading