feat: add operational timeline workspace

This commit is contained in:
2026-08-19 16:42:41 +08:00
parent d2f2895c36
commit 45f1ebee7e
19 changed files with 1127 additions and 105 deletions
@@ -28,6 +28,7 @@ export type WorkbenchTopBarProps = {
alerts: WorkbenchAlert[];
user: WorkbenchUser;
conditionFeedVisible: boolean;
timelineVisible: boolean;
taskTickerAvailable: boolean;
taskTickerVisible: boolean;
devPanelEnabled: boolean;
@@ -35,6 +36,7 @@ export type WorkbenchTopBarProps = {
onSelectScenario: (scenarioId: string) => void;
onSelectAlert: (alert: WorkbenchAlert) => void;
onToggleConditionFeed: () => void;
onToggleTimeline: () => void;
onToggleTaskTicker: () => void;
onToggleDevPanel: () => void;
onPreviewScenario: () => void;
@@ -59,6 +61,7 @@ export function WorkbenchTopBar({
alerts,
user,
conditionFeedVisible,
timelineVisible,
taskTickerAvailable,
taskTickerVisible,
devPanelEnabled,
@@ -66,6 +69,7 @@ export function WorkbenchTopBar({
onSelectScenario,
onSelectAlert,
onToggleConditionFeed,
onToggleTimeline,
onToggleTaskTicker,
onToggleDevPanel,
onPreviewScenario,
@@ -144,6 +148,12 @@ export function WorkbenchTopBar({
</div>
<div className="flex shrink-0 items-center gap-2">
<div className="lg:hidden">
<TimelineToggle compact visible={timelineVisible} onToggle={onToggleTimeline} />
</div>
<div className="hidden lg:block">
<TimelineToggle visible={timelineVisible} onToggle={onToggleTimeline} />
</div>
{onCreateTestAnalysis ? (
<div className="hidden lg:block">
<button
@@ -257,6 +267,33 @@ function ConditionFeedToggle({ visible, onToggle }: { visible: boolean; onToggle
);
}
function TimelineToggle({
visible,
compact = false,
onToggle
}: {
visible: boolean;
compact?: boolean;
onToggle: () => void;
}) {
return (
<button
type="button"
aria-label={visible ? "隐藏运行时间轴" : "显示运行时间轴"}
aria-pressed={visible}
data-selection-tone="soft"
title={visible ? "隐藏运行时间轴" : "显示运行时间轴"}
onClick={onToggle}
className={cn("group", compact ? "px-1.5" : "px-2", headerControlButtonClassName)}
>
<span className={headerControlIconClassName}>
<Clock3 size={14} aria-hidden="true" />
</span>
{!compact ? <span className={compactHeaderTextClassName}></span> : null}
</button>
);
}
function HeaderReadout({
icon: Icon,
label,