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
22 changes: 22 additions & 0 deletions apps/desktop/src/renderer/desktop/desktop-shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,28 @@ test("the Issues page's sidebar row and its command stand only while the account
assert.equal(opens, 2);
});

test("the side panel's toggle stands over the Issues list once an issue has been peeked there, as over the Inbox once an item is chosen", async () => {
const control = tasksControl();
const toggles = (container: HTMLElement) =>
[...container.querySelectorAll("button")].some((button) =>
["Show panel", "Hide panel"].includes(button.getAttribute("aria-label") ?? ""),
);
handState(experimentsOn(EXPERIMENT.ISSUES));
const unpeeked = mount(false, false, { issuesView: { ...control.issuesView, open: true } });
await settle();
const before = toggles(unpeeked);
act(() => root?.unmount());
document.body.innerHTML = "";

const peeked = mount(false, false, {
issuesView: { ...control.issuesView, open: true, peeked: "issue-1" },
});
await settle();

assert.equal(before, false, "nothing peeked, no panel to show");
assert.equal(toggles(peeked), true);
});

test("the Automations page's sidebar row and its command stand only while the account has its experiment on", async () => {
handState({});
const off = mount(false);
Expand Down
21 changes: 17 additions & 4 deletions apps/desktop/src/renderer/desktop/desktop-shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ import { ChipCards, type TaskFocus, WorkspaceDirectory } from "../tasks/chip-car
import { MentionedAgents } from "../tasks/mentioned-agent-card";
import { NewTaskDialog } from "../tasks/new-task-dialog";
import { SIDE_PANEL_TAB } from "../tasks/use-side-panel";
import { AUTOMATIONS_PAGE, type AutomationsPlace, type TasksControl } from "../tasks/use-tasks-tab";
import {
AUTOMATIONS_PAGE,
type AutomationsPlace,
ISSUES_PAGE,
type TasksControl,
} from "../tasks/use-tasks-tab";
import { Tooltip } from "../tooltip";
import { DesktopAgentPage } from "./desktop-agent-page";
import { DesktopChat } from "./desktop-chat";
Expand Down Expand Up @@ -543,8 +548,8 @@ export function DesktopShell({
// Note that the shell says whether the panel's toggle stands, because the
// toolbar beneath it leaves the toggle room then and only then. Factory,
// the Automations page, and Chat stand in the plan's place, so they draw
// no panel to toggle; an agent's page draws the agent's own, and the Inbox
// the chosen item's task's.
// no panel to toggle; an agent's page draws the agent's own, the Inbox
// the chosen item's task's, and the Issues list the issue it peeked.
const inboxOpen = tasks.inboxView.open;
const pageAgent = tasks.agentView.agentId;
const pagePerson = tasks.personView.userId;
Expand All @@ -553,8 +558,16 @@ export function DesktopShell({
const chatOpen = tasks.chatView.open && chatOn;
const issuesOpen = tasks.issuesView.open && issuesOn;
const planToggle = tasks.page === TASKS_PAGE.DOCUMENT && !standingIn;
// The Issues list draws the panel beside it once an issue has been peeked there, as the Inbox does once an item is chosen.
const issuePeeked =
issuesOpen &&
tasks.issuesView.place.kind === ISSUES_PAGE.LIST &&
tasks.issuesView.peeked !== undefined;
const panelToggle =
planToggle || pageAgent !== undefined || (inboxOpen && tasks.inboxView.chosen !== undefined);
planToggle ||
pageAgent !== undefined ||
(inboxOpen && tasks.inboxView.chosen !== undefined) ||
issuePeeked;
const taskDrawn = planToggle && tasks.region.kind === DOCUMENT_REGION.READY;
// Note that a panel filling the window hides the task's column, call bar
// and all, so the captions float in its place then.
Expand Down
16 changes: 13 additions & 3 deletions apps/desktop/src/renderer/desktop/issue-detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { usePerson } from "@luke/panel/member-directory";
import { useMinute } from "@luke/panel/tasks/task-time";
import { APP_COMMAND } from "@luke/settings/shortcuts";
import {
ArrowUpRightIcon,
BREADCRUMBS_VARIANT,
Breadcrumbs,
ConfirmDialog,
Expand All @@ -25,7 +26,7 @@ import { ExperimentTag } from "../experiment-marks";
import { DocumentByline, DocumentScroll } from "../tasks/document-frame";
import { RelativeTime } from "../tasks/relative-time";
import { Tooltip } from "../tooltip";
import { ActionMenu } from "./action-menu";
import { ActionMenu, type MenuAction } from "./action-menu";
import {
archiveAnswered,
archiveItem,
Expand Down Expand Up @@ -86,8 +87,9 @@ export function IssueCrumbs({
}

/**
* The issue's ⋯ menu, on its page's toolbar and on its peek's head: Start
* task… and Start agent…, Copy link, and Archive, which asks first and, once kept, hands back to
* The issue's ⋯ menu, on its page's toolbar and in its peek's top row: Open
* as page where it stands in the peek, Start task… and Start agent…, Copy
* link, and Archive, which asks first and, once kept, hands back to
* `onArchived`, since the issue no longer stands where it was drawn.
*/
export function IssueMenu({
Expand All @@ -96,6 +98,7 @@ export function IssueMenu({
surfaceOpen = true,
onChange,
onArchived,
onOpenPage,
}: {
issue: Issue;
identifier: string;
Expand All @@ -104,8 +107,14 @@ export function IssueMenu({
/** Sends a change, answering whether it was kept. */
onChange: (change: IssueChange) => Promise<boolean>;
onArchived: () => void;
/** Opens the issue on its own page, from the peek; none on the page itself. */
onOpenPage?: (() => void) | undefined;
}): React.JSX.Element {
const menu = useMenu(surfaceOpen);
const openPage: MenuAction | undefined =
onOpenPage === undefined
? undefined
: { label: "Open as page", icon: <ArrowUpRightIcon />, onSelect: onOpenPage };
const starts = useStartItems(issue, identifier);
const copyLink = useCopyLinkItem()({ kind: LINK_PLACE.ISSUE, issueId: issue.id });
const archiving = useConfirmDialog({ subject: true, surfaceOpen }, () =>
Expand All @@ -125,6 +134,7 @@ export function IssueMenu({
label={ISSUE_ACTIONS_LABEL}
menu={menu.drawn}
groups={[
...(openPage === undefined ? [] : [[openPage]]),
...(starts.length === 0 ? [] : [starts]),
...(copyLink === undefined ? [] : [[copyLink]]),
[archive],
Expand Down
Loading
Loading