fix: decouple timeline from workspace layout
The regression recurred because a floating timeline height was still exported as shared layout space and its z-index exceeded artifacts and notices. Reserve zero layout height and define the timeline below artifact and notification overlays.
This commit is contained in:
@@ -925,13 +925,7 @@ export function MapWorkbenchPage({
|
|||||||
{
|
{
|
||||||
...WORKBENCH_LAYOUT_CSS_VARIABLES,
|
...WORKBENCH_LAYOUT_CSS_VARIABLES,
|
||||||
"--workbench-agent-current-width": `${currentAgentWidth}px`,
|
"--workbench-agent-current-width": `${currentAgentWidth}px`,
|
||||||
"--workbench-timeline-height": `${
|
"--workbench-timeline-height": `${OPERATIONAL_TIMELINE_LAYOUT.overlayReservedHeight}px`
|
||||||
!timelineVisible
|
|
||||||
? 0
|
|
||||||
: !isLargeScreen
|
|
||||||
? OPERATIONAL_TIMELINE_LAYOUT.mobileSummaryHeight + timelineBottom
|
|
||||||
: OPERATIONAL_TIMELINE_LAYOUT[timelineMode].height + timelineBottom
|
|
||||||
}px`
|
|
||||||
} as CSSProperties
|
} as CSSProperties
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -1094,7 +1088,7 @@ export function MapWorkbenchPage({
|
|||||||
{shouldShowTaskTicker ? (
|
{shouldShowTaskTicker ? (
|
||||||
<motion.div
|
<motion.div
|
||||||
key="agent-task-ticker-shell"
|
key="agent-task-ticker-shell"
|
||||||
className="fixed left-1/2 right-auto top-24 z-20 w-[calc(100%-1.5rem)] [translate:-50%_0] md:absolute md:w-[var(--workbench-ticker-width)] 2xl:w-[var(--workbench-ticker-width-wide)]"
|
className="fixed left-1/2 right-auto top-24 z-50 w-[calc(100%-1.5rem)] [translate:-50%_0] md:absolute md:w-[var(--workbench-ticker-width)] 2xl:w-[var(--workbench-ticker-width-wide)]"
|
||||||
style={{ transformOrigin: "top center" }}
|
style={{ transformOrigin: "top center" }}
|
||||||
initial={
|
initial={
|
||||||
prefersReducedMotion
|
prefersReducedMotion
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
canCenterTimelineBesideMapScale,
|
canCenterTimelineBesideMapScale,
|
||||||
clusterOperationalEvents,
|
clusterOperationalEvents,
|
||||||
createOperationalEvents,
|
createOperationalEvents,
|
||||||
|
OPERATIONAL_TIMELINE_LAYOUT,
|
||||||
resolveTimelineScaleLayout
|
resolveTimelineScaleLayout
|
||||||
} from "./operational-timeline-model";
|
} from "./operational-timeline-model";
|
||||||
|
|
||||||
@@ -15,6 +16,10 @@ const workOrder: ScheduledConditionItem = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe("operational timeline model", () => {
|
describe("operational timeline model", () => {
|
||||||
|
it("does not reserve workspace layout space for the floating timeline", () => {
|
||||||
|
expect(OPERATIONAL_TIMELINE_LAYOUT.overlayReservedHeight).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
it("creates linked plan and actual events for active work orders", () => {
|
it("creates linked plan and actual events for active work orders", () => {
|
||||||
const events = createOperationalEvents([workOrder]);
|
const events = createOperationalEvents([workOrder]);
|
||||||
expect(events.map((event) => event.lane)).toEqual(["plan", "actual"]);
|
expect(events.map((event) => event.lane)).toEqual(["plan", "actual"]);
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ export const OPERATIONAL_TIMELINE_LAYOUT = {
|
|||||||
mapScaleSafeWidth: 520,
|
mapScaleSafeWidth: 520,
|
||||||
floatingGap: 48,
|
floatingGap: 48,
|
||||||
edgeInset: 24,
|
edgeInset: 24,
|
||||||
scaleCollisionOffset: 56
|
scaleCollisionOffset: 56,
|
||||||
|
overlayReservedHeight: 0
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type TimelineScaleLayout = {
|
export type TimelineScaleLayout = {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function ArtifactPeekBar({
|
|||||||
<aside
|
<aside
|
||||||
aria-label="Agent 成果预览"
|
aria-label="Agent 成果预览"
|
||||||
className={cn(
|
className={cn(
|
||||||
"acrylic-panel pointer-events-auto absolute bottom-[calc(var(--workbench-timeline-height)+1rem)] z-30 flex min-h-[76px] w-[min(680px,calc(100%-2rem))] items-center gap-3 rounded-2xl border px-3 py-2.5 text-slate-900",
|
"acrylic-panel pointer-events-auto absolute top-28 z-40 flex min-h-[76px] w-[min(680px,calc(100%-2rem))] items-center gap-3 rounded-2xl border px-3 py-2.5 text-slate-900",
|
||||||
"left-1/2 -translate-x-1/2",
|
"left-1/2 -translate-x-1/2",
|
||||||
surfaceMode === "map_split" && "2xl:left-[25%]"
|
surfaceMode === "map_split" && "2xl:left-[25%]"
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ export function WorkbenchMainFrame({
|
|||||||
id="artifact-workspace"
|
id="artifact-workspace"
|
||||||
aria-label={`${activeArtifact.title}工作区`}
|
aria-label={`${activeArtifact.title}工作区`}
|
||||||
aria-hidden={!showArtifact}
|
aria-hidden={!showArtifact}
|
||||||
className={cn("relative min-h-0 min-w-0 overflow-hidden", !showArtifact && "hidden")}
|
className={cn(
|
||||||
|
"relative z-30 min-h-0 min-w-0 overflow-hidden",
|
||||||
|
!showArtifact && "hidden"
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<AnalysisArtifactWorkspace
|
<AnalysisArtifactWorkspace
|
||||||
artifact={activeArtifact}
|
artifact={activeArtifact}
|
||||||
@@ -119,7 +122,7 @@ export function WorkbenchMainFrame({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className="pointer-events-auto absolute left-3 z-40 mx-auto min-h-0"
|
className="pointer-events-auto absolute left-3 z-20 mx-auto min-h-0"
|
||||||
initial={false}
|
initial={false}
|
||||||
animate={{
|
animate={{
|
||||||
bottom: timelineBottom,
|
bottom: timelineBottom,
|
||||||
|
|||||||
Reference in New Issue
Block a user