mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 20:43:36 +00:00
Add number key toggle for output modal
When the output modal is open: - Pressing the same number key closes the modal - Pressing a different number key switches to that feature's output Also adds test utilities for testing number key interactions and fixes the setupMockProjectWithInProgressFeatures utility to properly set __mockFeatures for the mock electron API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,8 @@ interface AgentOutputModalProps {
|
||||
onClose: () => void;
|
||||
featureDescription: string;
|
||||
featureId: string;
|
||||
/** Called when a number key (0-9) is pressed while the modal is open */
|
||||
onNumberKeyPress?: (key: string) => void;
|
||||
}
|
||||
|
||||
export function AgentOutputModal({
|
||||
@@ -23,6 +25,7 @@ export function AgentOutputModal({
|
||||
onClose,
|
||||
featureDescription,
|
||||
featureId,
|
||||
onNumberKeyPress,
|
||||
}: AgentOutputModalProps) {
|
||||
const [output, setOutput] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -169,6 +172,29 @@ export function AgentOutputModal({
|
||||
autoScrollRef.current = isAtBottom;
|
||||
};
|
||||
|
||||
// Handle number key presses while modal is open
|
||||
useEffect(() => {
|
||||
if (!open || !onNumberKeyPress) return;
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
// Check if a number key (0-9) was pressed without modifiers
|
||||
if (
|
||||
!event.ctrlKey &&
|
||||
!event.altKey &&
|
||||
!event.metaKey &&
|
||||
/^[0-9]$/.test(event.key)
|
||||
) {
|
||||
event.preventDefault();
|
||||
onNumberKeyPress(event.key);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, [open, onNumberKeyPress]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onClose}>
|
||||
<DialogContent
|
||||
|
||||
@@ -698,6 +698,30 @@ export function BoardView() {
|
||||
setShowOutputModal(true);
|
||||
};
|
||||
|
||||
// Handle number key press when output modal is open
|
||||
const handleOutputModalNumberKeyPress = useCallback((key: string) => {
|
||||
// Convert key to index: 1-9 -> 0-8, 0 -> 9
|
||||
const index = key === "0" ? 9 : parseInt(key, 10) - 1;
|
||||
|
||||
// Get the feature at that index from in-progress features
|
||||
const targetFeature = inProgressFeaturesForShortcuts[index];
|
||||
|
||||
if (!targetFeature) {
|
||||
// No feature at this index, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// If pressing the same number key as the currently open feature, close the modal
|
||||
if (targetFeature.id === outputFeature?.id) {
|
||||
setShowOutputModal(false);
|
||||
}
|
||||
// If pressing a different number key, switch to that feature's output
|
||||
else {
|
||||
setOutputFeature(targetFeature);
|
||||
// Modal stays open, just showing different content
|
||||
}
|
||||
}, [inProgressFeaturesForShortcuts, outputFeature?.id]);
|
||||
|
||||
const handleForceStopFeature = async (feature: Feature) => {
|
||||
try {
|
||||
await autoMode.stopFeature(feature.id);
|
||||
@@ -1209,6 +1233,7 @@ export function BoardView() {
|
||||
onClose={() => setShowOutputModal(false)}
|
||||
featureDescription={outputFeature?.description || ""}
|
||||
featureId={outputFeature?.id || ""}
|
||||
onNumberKeyPress={handleOutputModalNumberKeyPress}
|
||||
/>
|
||||
|
||||
{/* Delete All Verified Dialog */}
|
||||
|
||||
@@ -894,6 +894,10 @@ export async function setupMockProjectWithInProgressFeatures(
|
||||
};
|
||||
|
||||
localStorage.setItem("automaker-storage", JSON.stringify(mockState));
|
||||
|
||||
// Also store features in a global variable that the mock electron API can use
|
||||
// This is needed because the board-view loads features from the file system
|
||||
(window as any).__mockFeatures = mockFeatures;
|
||||
},
|
||||
options
|
||||
);
|
||||
@@ -1255,6 +1259,29 @@ export async function pressShortcut(page: Page, key: string): Promise<void> {
|
||||
await page.keyboard.press(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of session items in the session list
|
||||
*/
|
||||
export async function countSessionItems(page: Page): Promise<number> {
|
||||
const sessionList = page.locator('[data-testid="session-list"] [data-testid^="session-item-"]');
|
||||
return await sessionList.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a new session to be created (by checking if a session item appears)
|
||||
*/
|
||||
export async function waitForNewSession(
|
||||
page: Page,
|
||||
options?: { timeout?: number }
|
||||
): Promise<void> {
|
||||
// Wait for any session item to appear
|
||||
const sessionItem = page.locator('[data-testid^="session-item-"]').first();
|
||||
await sessionItem.waitFor({
|
||||
timeout: options?.timeout ?? 5000,
|
||||
state: "visible",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a shortcut key indicator is visible for a navigation item
|
||||
*/
|
||||
@@ -1650,3 +1677,27 @@ export async function setupMockProjectWithSkipTestsFeatures(
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Press a number key (0-9) on the keyboard
|
||||
*/
|
||||
export async function pressNumberKey(page: Page, num: number): Promise<void> {
|
||||
await page.keyboard.press(num.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the modal title/description text to verify which feature's output is being shown
|
||||
*/
|
||||
export async function getAgentOutputModalDescription(page: Page): Promise<string | null> {
|
||||
const modal = page.locator('[data-testid="agent-output-modal"]');
|
||||
const description = modal.locator('[id="radix-\\:r.+\\:-description"]').first();
|
||||
return await description.textContent().catch(() => null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the dialog description content in the agent output modal
|
||||
*/
|
||||
export async function getOutputModalDescription(page: Page): Promise<string | null> {
|
||||
const modalDescription = page.locator('[data-testid="agent-output-modal"] [data-slot="dialog-description"]');
|
||||
return await modalDescription.textContent().catch(() => null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user