refactor: improve dialog and auto mode service functionality

- Refactored DialogContent component to use forwardRef for better integration with refs.
- Enhanced auto mode service by introducing an auto loop for processing features concurrently.
- Updated error handling and feature management logic to streamline operations.
- Cleaned up code formatting and improved readability across various components and services.
This commit is contained in:
Cody Seibert
2025-12-17 22:45:39 -05:00
parent 0549b8085a
commit c80ae3367a
9 changed files with 278 additions and 76 deletions

View File

@@ -49,16 +49,18 @@ function DialogOverlay({
);
}
function DialogContent({
className,
children,
showCloseButton = true,
compact = false,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
export type DialogContentProps = Omit<
React.ComponentProps<typeof DialogPrimitive.Content>,
"ref"
> & {
showCloseButton?: boolean;
compact?: boolean;
}) {
};
const DialogContent = React.forwardRef<
HTMLDivElement,
DialogContentProps
>(({ className, children, showCloseButton = true, compact = false, ...props }, ref) => {
// Check if className contains a custom max-width
const hasCustomMaxWidth =
typeof className === "string" && className.includes("max-w-");
@@ -67,6 +69,7 @@ function DialogContent({
<DialogPortal data-slot="dialog-portal">
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
data-slot="dialog-content"
className={cn(
"fixed top-[50%] left-[50%] z-50 translate-x-[-50%] translate-y-[-50%]",
@@ -110,7 +113,9 @@ function DialogContent({
</DialogPrimitive.Content>
</DialogPortal>
);
}
});
DialogContent.displayName = "DialogContent";
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (

View File

@@ -43,3 +43,4 @@ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
export { RadioGroup, RadioGroupItem };

View File

@@ -28,3 +28,4 @@ Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch };

View File

@@ -53,3 +53,4 @@ export function ArchiveAllVerifiedDialog({
);
}

View File

@@ -120,7 +120,9 @@ export async function getDragHandleForFeature(
*/
export async function clickAddFeature(page: Page): Promise<void> {
await page.click('[data-testid="add-feature-button"]');
await page.waitForSelector('[data-testid="add-feature-dialog"]', { timeout: 5000 });
await page.waitForSelector('[data-testid="add-feature-dialog"]', {
timeout: 5000,
});
}
/**
@@ -132,18 +134,22 @@ export async function fillAddFeatureDialog(
options?: { branch?: string; category?: string }
): Promise<void> {
// Fill description (using the dropzone textarea)
const descriptionInput = page.locator('[data-testid="add-feature-dialog"] textarea').first();
const descriptionInput = page
.locator('[data-testid="add-feature-dialog"] textarea')
.first();
await descriptionInput.fill(description);
// Fill branch if provided (it's a combobox autocomplete)
if (options?.branch) {
// First, select "Other branch" radio option if not already selected
const otherBranchRadio = page.locator('[data-testid="feature-radio-group"]').locator('[id="feature-other"]');
const otherBranchRadio = page
.locator('[data-testid="feature-radio-group"]')
.locator('[id="feature-other"]');
await otherBranchRadio.waitFor({ state: "visible", timeout: 5000 });
await otherBranchRadio.click();
// Wait for the branch input to appear
await page.waitForTimeout(300);
// Now click on the branch input (autocomplete)
const branchInput = page.locator('[data-testid="feature-input"]');
await branchInput.waitFor({ state: "visible", timeout: 5000 });
@@ -151,7 +157,7 @@ export async function fillAddFeatureDialog(
// Wait for the popover to open
await page.waitForTimeout(300);
// Type in the command input
const commandInput = page.locator('[cmdk-input]');
const commandInput = page.locator("[cmdk-input]");
await commandInput.fill(options.branch);
// Press Enter to select/create the branch
await commandInput.press("Enter");
@@ -161,10 +167,12 @@ export async function fillAddFeatureDialog(
// Fill category if provided (it's also a combobox autocomplete)
if (options?.category) {
const categoryButton = page.locator('[data-testid="feature-category-input"]');
const categoryButton = page.locator(
'[data-testid="feature-category-input"]'
);
await categoryButton.click();
await page.waitForTimeout(300);
const commandInput = page.locator('[cmdk-input]');
const commandInput = page.locator("[cmdk-input]");
await commandInput.fill(options.category);
await commandInput.press("Enter");
await page.waitForTimeout(200);
@@ -210,8 +218,13 @@ export async function getWorktreeSelector(page: Page): Promise<Locator> {
/**
* Click on a branch button in the worktree selector
*/
export async function selectWorktreeBranch(page: Page, branchName: string): Promise<void> {
const branchButton = page.getByRole("button", { name: new RegExp(branchName, "i") });
export async function selectWorktreeBranch(
page: Page,
branchName: string
): Promise<void> {
const branchButton = page.getByRole("button", {
name: new RegExp(branchName, "i"),
});
await branchButton.click();
await page.waitForTimeout(500); // Wait for UI to update
}
@@ -219,9 +232,13 @@ export async function selectWorktreeBranch(page: Page, branchName: string): Prom
/**
* Get the currently selected branch in the worktree selector
*/
export async function getSelectedWorktreeBranch(page: Page): Promise<string | null> {
export async function getSelectedWorktreeBranch(
page: Page
): Promise<string | null> {
// The main branch button has aria-pressed="true" when selected
const selectedButton = page.locator('[data-testid="worktree-selector"] button[aria-pressed="true"]');
const selectedButton = page.locator(
'[data-testid="worktree-selector"] button[aria-pressed="true"]'
);
const text = await selectedButton.textContent().catch(() => null);
return text?.trim() || null;
}
@@ -229,7 +246,12 @@ export async function getSelectedWorktreeBranch(page: Page): Promise<string | nu
/**
* Check if a branch button is visible in the worktree selector
*/
export async function isWorktreeBranchVisible(page: Page, branchName: string): Promise<boolean> {
const branchButton = page.getByRole("button", { name: new RegExp(branchName, "i") });
export async function isWorktreeBranchVisible(
page: Page,
branchName: string
): Promise<boolean> {
const branchButton = page.getByRole("button", {
name: new RegExp(branchName, "i"),
});
return await branchButton.isVisible().catch(() => false);
}