FN-8032: align GitLab import detail actions

Keep GitLab import details consistent with the shared padded FloatingWindow layout.\n\n- Move the GitLab preview into the shared heading and scrolling-content structure\n- Place the GitLab import control in the shared bottom action bar for mobile reachability\n- Cover cross-provider detail layout and shared mobile-sheet invariants\n\nFiles changed:\n .../dashboard/app/components/GitHubImportModal.tsx | 20 ++++++++++----\n .../__tests__/GitHubImportModal.test.tsx           | 32 +++++++++++++++++++---\n 2 files changed, 42 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-8032

Fusion-Task-Lineage: 150b992a-d5fa-4001-b818-7ece031a6cb5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-16 03:40:47 -07:00
parent 2734e61d3e
commit 055f3ba75d
2 changed files with 42 additions and 10 deletions

View File

@@ -1946,12 +1946,20 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
className="floating-window--github-import-detail"
>
<div className="github-import-detail-panel">
<div className="issue-preview" data-testid="gitlab-import-preview-card">
<h4>{selectedGitlabItem.resourceKind === "merge_request" ? "!" : "#"}{selectedGitlabItem.iid} {importTranslation.display.title}</h4>
<div className="preview-meta-row"><span className={`preview-state-badge preview-state-badge--${selectedGitlabItem.state}`}>{selectedGitlabItem.state}</span><a href={selectedGitlabItem.webUrl} target="_blank" rel="noopener noreferrer">{t("git.openSource", "Open source")}</a></div>
{importTranslation.controls}
<MailboxMessageContent className="preview-body preview-body--markdown" content={importTranslation.display.body?.trim() || t("git.noDescription", "(no description)")} testId="gitlab-import-preview-body" />
<button type="button" className="btn btn-primary" onClick={handleImportGitLab} disabled={!gitlabEnabled || importing || isUrlImported(selectedGitlabItem.webUrl)}>{importing ? <Loader2 size={14} className="spin" /> : t("git.import", "Import")}</button>
<div className="github-import-pane-header">
<h4>{t("git.previewHeading", "Preview")}</h4>
</div>
<div className="github-import-pane-content">
<div className="issue-preview" data-testid="gitlab-import-preview-card">
<h4>{selectedGitlabItem.resourceKind === "merge_request" ? "!" : "#"}{selectedGitlabItem.iid} {importTranslation.display.title}</h4>
<div className="preview-meta-row"><span className={`preview-state-badge preview-state-badge--${selectedGitlabItem.state}`}>{selectedGitlabItem.state}</span><a href={selectedGitlabItem.webUrl} target="_blank" rel="noopener noreferrer">{t("git.openSource", "Open source")}</a></div>
{importTranslation.controls}
<MailboxMessageContent className="preview-body preview-body--markdown" content={importTranslation.display.body?.trim() || t("git.noDescription", "(no description)")} testId="gitlab-import-preview-body" />
</div>
</div>
{/* FNXC:GitHubImport 2026-07-16-00:37: GitLab uses the same padded, bottom-aligned detail action bar as GitHub so mobile sheets keep the primary import control reachable and consistent with other FloatingWindow modals. */}
<div className="github-import-detail-actions" data-testid="github-import-detail-actions">
<button type="button" className="btn btn-primary github-import-action" data-testid="github-import-action-top" onClick={handleImportGitLab} disabled={!gitlabEnabled || importing || isUrlImported(selectedGitlabItem.webUrl)}>{importing ? <Loader2 size={14} className="spin" /> : t("git.import", "Import")}</button>
</div>
</div>
</FloatingWindow>

View File

@@ -1807,7 +1807,10 @@ describe("GitHubImportModal", () => {
fireEvent.click(await screen.findByText(/#2 GitLab bug/));
await waitFor(() => {
expect(screen.getByTestId("gitlab-import-preview-card")).toBeTruthy();
const preview = screen.getByTestId("gitlab-import-preview-card");
expect(preview).toBeTruthy();
expect(preview.closest(".github-import-detail-panel")).toBeTruthy();
expect(preview.closest(".github-import-detail-panel")?.querySelector(".github-import-detail-actions")).toBeTruthy();
});
first.unmount();
@@ -1932,6 +1935,8 @@ describe("GitHubImportModal", () => {
fireEvent.click(screen.getByRole("radio", { name: /select issue #12/i }));
const detail = await screen.findByTestId("floating-window-github-import-detail");
expect(within(detail).getByText("Windowed issue body")).toBeTruthy();
expect(within(detail).getByTestId("github-import-action-top")).toBeTruthy();
expect(detail.querySelector(".github-import-detail-panel .github-import-detail-actions")).toBeTruthy();
expect(detail.querySelectorAll(".floating-window__resize-handle")).toHaveLength(8);
fireEvent.click(within(detail).getByTestId("floating-window-close-github-import-detail"));
await waitFor(() => expect(screen.queryByTestId("floating-window-github-import-detail")).toBeNull());
@@ -1946,6 +1951,8 @@ describe("GitHubImportModal", () => {
await screen.findByText("Test PR");
fireEvent.click(screen.getByRole("radio", { name: /select pull request #1/i }));
const detail = await screen.findByTestId("floating-window-github-import-detail");
expect(within(detail).getByTestId("github-import-action-top")).toBeTruthy();
expect(detail.querySelector(".github-import-detail-panel .github-import-detail-actions")).toBeTruthy();
expect(within(detail).getByTestId("github-import-pr-checks")).toBeTruthy();
expect(await within(detail).findByText("Looks good")).toBeTruthy();
});
@@ -1964,10 +1971,27 @@ describe("GitHubImportModal", () => {
expect(document.querySelector(".github-import-resize-handle")).toBeNull();
});
it("scopes the import detail FloatingWindow as a mobile full-screen sheet", () => {
it("keeps every provider detail panel padded with tokenized bottom actions", () => {
const source = readFileSync(resolve(__dirname, "../GitHubImportModal.css"), "utf8");
const detailPanelRule = source.match(/\.github-import-detail-panel\s*\{[^}]*\}/)?.[0] ?? "";
const actionRowRule = source.match(/\.github-import-detail-actions\s*\{[^}]*\}/)?.[0] ?? "";
expect(detailPanelRule).toContain("padding: var(--space-lg);");
expect(actionRowRule).toContain("flex-wrap: wrap;");
expect(actionRowRule).toContain("gap: var(--space-sm);");
});
it("scopes the import detail FloatingWindow as the shared mobile full-screen sheet", () => {
const source = readFileSync(resolve(__dirname, "../FloatingWindow.css"), "utf8");
expect(source).toMatch(/@media \(max-width: 768px\)[\s\S]*\.floating-window--github-import-detail[\s\S]*width: 100vw !important/);
expect(source).toContain(".floating-window--github-import-detail .floating-window__resize-handle");
const chatSheetRule = source.match(/\.floating-window--chat\s*\{([^}]*)\}/)?.[1] ?? "";
const importSheetRule = source.match(/\.floating-window--github-import-detail\s*\{([^}]*)\}/)?.[1] ?? "";
const taskSheetRule = source.match(/\.floating-window--task-detail\s*\{([^}]*)\}/)?.[1] ?? "";
expect(importSheetRule).toBe(chatSheetRule);
expect(importSheetRule).toBe(taskSheetRule);
expect(importSheetRule).toContain("inset: 0 !important;");
expect(source).toMatch(/@media \(max-width: 768px\)[\s\S]*\.floating-window--github-import-detail \.floating-window__resize-handle\s*\{\s*display: none;/);
expect(source).toContain(".floating-window:not(.floating-window--chat):not(.floating-window--github-import-detail)");
});
describe("Hide imported", () => {