feat(workspace): the Changes panel shows on the workspace home too
The home used to hide the whole row the Changes panel lives in, so a workspace's changes showed only once a session tab was open. The home now shares that row: the panel (or its rail) sits beside it at the same width, the page is locked to the viewport and the home scrolls in its own column. The panel's Workspace context fold is left out there, since the home shows that column itself. The console's section stays mounted and hidden (CSS).
This commit is contained in:
@@ -1269,8 +1269,12 @@ export function Workspace() {
|
||||
// editor: no page padding, no cards, dividers between its regions.
|
||||
const sessionView = !!currentLane && !home;
|
||||
previewHostRef.current = sessionView;
|
||||
// The home is locked to the viewport too: the Changes panel sits beside it
|
||||
// at full height, and the home scrolls inside its own column.
|
||||
const viewportLocked =
|
||||
sessionView || (!home && (paneHasActiveRun || (!!currentLane && changesOpen && changesFull)));
|
||||
sessionView ||
|
||||
(home && !!currentLane) ||
|
||||
(!home && (paneHasActiveRun || (!!currentLane && changesOpen && changesFull)));
|
||||
|
||||
const handleLaneAction = async (id: number, action: string, body?: Record<string, unknown>) => {
|
||||
setLaneActionError(null);
|
||||
@@ -1344,27 +1348,37 @@ export function Workspace() {
|
||||
it rather than under it. It collapses to a rail instead of
|
||||
unmounting nothing — there is no live subscription inside it, so
|
||||
unmounting is safe and keeps a closed panel from polling. */}
|
||||
{home && currentLane && (
|
||||
<WorkspaceHome
|
||||
lane={currentLane}
|
||||
onRenamed={() => void refreshLanes()}
|
||||
onSourcesChange={(v) => sourcesChanged(currentLane.id, v)}
|
||||
sourcesVersion={sourcesVersion}
|
||||
onMenuAction={(action) => {
|
||||
if (action === "new-here") {
|
||||
setAddLanePrefill({ sourceRepo: currentLane.source_repo || currentLane.cwd });
|
||||
setAddLaneOpen(true);
|
||||
} else if (action === "reset" || action === "remove") {
|
||||
setDestructive({ lane: currentLane, action });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div ref={changesRowRef} className={`relative flex min-h-0 flex-1${home ? " hidden" : ""}`}>
|
||||
<div ref={changesRowRef} className="relative flex min-h-0 flex-1">
|
||||
{/* The home shares the row with the Changes panel, like the session
|
||||
view's console does — so a workspace's changes show before any
|
||||
session is open. */}
|
||||
{home && currentLane && (
|
||||
<div
|
||||
data-testid="workspace-home-column"
|
||||
className={`min-h-0 min-w-0 flex-1 overflow-y-auto${
|
||||
changesOpen && changesFull ? " hidden" : ""
|
||||
}${changesOpen && !changesFull ? " pr-5" : ""}`}
|
||||
>
|
||||
<WorkspaceHome
|
||||
lane={currentLane}
|
||||
onRenamed={() => void refreshLanes()}
|
||||
onSourcesChange={(v) => sourcesChanged(currentLane.id, v)}
|
||||
sourcesVersion={sourcesVersion}
|
||||
onMenuAction={(action) => {
|
||||
if (action === "new-here") {
|
||||
setAddLanePrefill({ sourceRepo: currentLane.source_repo || currentLane.cwd });
|
||||
setAddLaneOpen(true);
|
||||
} else if (action === "reset" || action === "remove") {
|
||||
setDestructive({ lane: currentLane, action });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<section
|
||||
data-testid="lane-detail"
|
||||
className={`flex min-h-0 min-w-0 flex-1 flex-col${
|
||||
currentLane && changesOpen && changesFull ? " hidden" : ""
|
||||
home || (currentLane && changesOpen && changesFull) ? " hidden" : ""
|
||||
}`}
|
||||
>
|
||||
{/* No header row: the console's tab bar is the header. Only a
|
||||
@@ -1884,12 +1898,13 @@ export function Workspace() {
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
)}
|
||||
{/* The workspace's context — the home's right column, compact. */}
|
||||
{/* The workspace's context — the home's right column, compact
|
||||
(not on the home itself, which shows that column). */}
|
||||
<section
|
||||
data-testid="panel-workspace-context"
|
||||
className={`-mx-3 flex shrink-0 flex-col border-t border-border px-3 ${
|
||||
contextOpen ? "max-h-[45%]" : ""
|
||||
}`}
|
||||
className={`-mx-3 shrink-0 flex-col border-t border-border px-3 ${
|
||||
home ? "hidden" : "flex"
|
||||
} ${contextOpen ? "max-h-[45%]" : ""}`}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -196,17 +196,20 @@ describe("Workspace — the Changes panel's width", () => {
|
||||
expect(size()).toHaveAttribute("aria-label", "Full screen");
|
||||
expect(screen.getByTestId("lane-changes-collapse")).toBeInTheDocument();
|
||||
|
||||
// Full width HIDES the console beside it — hidden, still mounted.
|
||||
// The workspace's home sits beside the panel (no session is open), and
|
||||
// full width HIDES it — hidden, still mounted; same for a console.
|
||||
const beside = () => screen.getByTestId("workspace-home-column");
|
||||
expect(beside().className).not.toContain("hidden");
|
||||
fireEvent.click(size());
|
||||
expect(card().className).toContain("w-full");
|
||||
expect(screen.getByTestId("lane-detail").className).toContain("hidden");
|
||||
expect(beside().className).toContain("hidden");
|
||||
expect(size()).toHaveAttribute("aria-label", "Restore size");
|
||||
expect(screen.getByTestId("lane-changes-collapse")).toBeInTheDocument();
|
||||
|
||||
// Restore brings the console back beside it.
|
||||
fireEvent.click(size());
|
||||
expect(card().className).toContain("w-[25%]");
|
||||
expect(screen.getByTestId("lane-detail").className).not.toContain("hidden");
|
||||
expect(beside().className).not.toContain("hidden");
|
||||
|
||||
// Collapsing from full screen reopens at 25/75, not back at full width.
|
||||
fireEvent.click(size());
|
||||
|
||||
@@ -1203,7 +1203,12 @@ describe("Workspace — home and session view", () => {
|
||||
it("opens a workspace on its home, hiding (not unmounting) the session view", async () => {
|
||||
await renderWorkspace();
|
||||
expect(screen.getByTestId("workspace-home")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("lane-detail").parentElement).toHaveClass("hidden");
|
||||
expect(screen.getByTestId("lane-detail")).toHaveClass("hidden");
|
||||
// The Changes panel (or its rail) sits beside the home, before any session.
|
||||
expect(screen.getByTestId("workspace-home-column").parentElement).not.toHaveClass("hidden");
|
||||
expect(
|
||||
screen.queryByTestId("lane-changes-card") ?? screen.queryByTestId("lane-changes-expand")
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
it("opens the session view for ?run=, headed by the tab bar alone", async () => {
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user