Skip to content

[codex] Fix v1 import modal layout#4822

Merged
Kitenite merged 2 commits into
mainfrom
florentine-geometry
May 21, 2026
Merged

[codex] Fix v1 import modal layout#4822
Kitenite merged 2 commits into
mainfrom
florentine-geometry

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented May 21, 2026

Summary

  • Fix the v1 import modal row layout so rows keep their height, align actions predictably, and allow the list to scroll.
  • Move modal close affordance into the footer, remove the old header padding reserved for the top-right close icon, and keep Back next to the primary Next/Done action.
  • Add project Import all support with conservative skips for already-linked, ambiguous, and cloud-error rows.
  • Add a footer-border step progress indicator with focused test coverage.

Why

The importer list was visually compressed and did not scroll correctly because rows could shrink inside the flex scroll container. The close button placement also left unused header padding after moving the action into the footer.

Validation

  • bun test ./src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.test.tsx
  • bun run --cwd apps/desktop typecheck
  • bun run lint

Notes

  • bun.lock has an unrelated local modification and was intentionally excluded from this PR.

Open in Stage

Summary by cubic

Fixes the v1 import modal layout and adds “Import all” with a step progress indicator for a smoother import experience. Rows keep a stable height, actions align predictably, and the list scrolls correctly.

  • New Features

    • Added “Import all” for projects with conservative skips (already linked, ambiguous matches, cloud errors) and inline progress (spinner + x/y).
    • Added an accessible footer step progress bar with focused tests.
    • Moved controls to the footer: Cancel, Back beside Next/Done.
  • Bug Fixes

    • Prevented row shrinkage and action jitter; ImportRow uses a grid layout to keep heights consistent.
    • Removed unused header padding from the old top-right close icon; content area now uses the full width.
    • Fixed scrolling inside the modal so long lists are usable.

Written for commit b81bf3f. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added "Import all" action to import multiple V1 projects in a single workflow with progress tracking
    • Added progress indicator showing current step during imports
    • Already-imported projects are automatically skipped
  • Improvements

    • Added Cancel button for better control during the import workflow
    • Refined navigation flow and modal layout for improved usability

Review Change Stack

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 21, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 869e6c43-d0a5-41ce-8082-72aeca1e6f50

📥 Commits

Reviewing files that changed from the base of the PR and between 0165b94 and b81bf3f.

📒 Files selected for processing (7)
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportProjectsPage/ImportProjectsPage.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/V1ImportModal.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/ImportPageShell/ImportPageShell.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/ImportRow/ImportRow.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.test.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.tsx
  • apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/index.ts

📝 Walkthrough

Walkthrough

This PR enhances the V1 project import workflow by introducing a new progress-tracking component and refactoring the import page to support batch importing all projects sequentially. The modal UI is updated to display step progress, add explicit cancellation, and adjust layouts for the new action flow.

Changes

V1 Project Import All with Progress Tracking

Layer / File(s) Summary
StepProgress component and tests
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/*
New StepProgress component renders a horizontal progress bar with ARIA accessibility attributes. getStepProgress helper clamps step bounds, calculates current step and percent, and formats labels. Tests verify helper calculations and rendered progress bar attributes.
ImportProjectsPage import all workflow and shared helpers
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportProjectsPage/ImportProjectsPage.tsx
Refactored to support sequential "import all" workflow with progress tracking. Centralizes V1 import logic into reusable helpers: query key builder, React Query fetch wrapper, local-import detection, unified import/setup handler with relocate logic, and cache invalidation. Implements importAll that iterates through projects, updates progress state, and skips already-imported or ambiguous projects. Adds headerAction button with spinner. Updates ProjectRow and runImport to use shared helpers.
V1ImportModal integration with StepProgress and layout updates
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/V1ImportModal.tsx, apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/ImportPageShell/ImportPageShell.tsx, apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/ImportRow/ImportRow.tsx
V1ImportModal integrates StepProgress display in bottom bar, adds "Cancel" button, and disables default close button. Bottom navigation shows "Back" conditionally and routes "Next"/"Done" based on page flow. ImportPageShell removes right padding from header. ImportRow switches to CSS grid layout with updated spacing and typography for better alignment with the new UI structure.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A progress bar hops through the steps with grace,
Import-all brings projects to their rightful place,
No close button blocks the exit way,
The modal dances brighter every day!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] Fix v1 import modal layout' is clear and directly relates to the main change: fixing the layout issues in the v1 import modal component.
Description check ✅ Passed The description covers most required sections: Summary, Why, Validation, and Notes are well-documented; however, Related Issues and Type of Change sections from the template are missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch florentine-geometry

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@stage-review
Copy link
Copy Markdown

stage-review Bot commented May 21, 2026

Ready to review this PR? Stage has broken it down into 5 individual chapters for you:

Title
1 Fix import row layout and scrolling
2 Implement step progress indicator component
3 Refactor project import logic for reuse
4 Add bulk project import functionality
5 Update modal layout and footer actions
Open in Stage

Chapters generated by Stage for commit b81bf3f on May 21, 2026 10:18pm UTC.

@Kitenite Kitenite merged commit 4c62ba1 into main May 21, 2026
9 of 10 checks passed
@Kitenite Kitenite deleted the florentine-geometry branch May 21, 2026 22:22
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 21, 2026

Greptile Summary

This PR fixes the v1 import modal's row layout (flex → CSS grid to prevent row shrinkage), relocates the close affordance to the footer as a "Cancel" button, and adds a footer-border step-progress indicator. It also introduces an "Import all" batch operation that sequentially imports eligible projects, skipping already-linked, ambiguous, or cloud-error rows.

  • Layout / UX: ImportRow switches to a responsive two/three-column grid; header padding reserved for the old close icon is removed; StepProgress renders a 1 px animated progress line above the footer border with correct WAI-ARIA attributes.
  • Import all: importAll iterates the project list, fetches per-project status via the React Query cache, and calls the shared importProject helper (extracted from ProjectRow.runImport) with conservative skips; there is currently no cancellation mechanism, so closing the modal mid-run does not halt the background loop.
  • Refactoring: importProject, fetchProjectFindByPath, isProjectAlreadyImported, and invalidateProjectImportQueries are lifted into module-level helpers shared by both importAll and the per-row runImport.

Confidence Score: 3/5

The layout and UI restructuring are safe, but the new Import all flow continues making project-creation/linking mutations in the background even after the user dismisses the modal.

The wizard can silently create or link projects after the user has explicitly dismissed it, with no way to stop it. The importAll async loop runs to completion regardless of modal close.

ImportProjectsPage.tsx — specifically the importAll function and its interaction with the Cancel button in the modal footer.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportProjectsPage/ImportProjectsPage.tsx Adds Import all batch operation and refactors importProject into a standalone async function; the importAll loop has no cancellation guard, so closing the modal mid-run continues making API mutations in the background.
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/V1ImportModal.tsx Restructures footer: replaces the top-right close icon with an always-visible Cancel button, adds StepProgress bar, and groups Back/Next/Done together. Changes are self-contained and look correct.
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/ImportRow/ImportRow.tsx Converts row layout from flex to a two/three-column CSS grid with a responsive sm: breakpoint, fixing row shrinkage and action alignment. Styling-only change with no logic impact.
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.tsx New accessible step-progress bar component; clamps index/step values defensively and uses correct WAI-ARIA progressbar attributes.
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.test.tsx Covers getStepProgress logic and ARIA attributes correctly, but two assertions check for specific Tailwind class strings, coupling tests to implementation details.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant Modal as V1ImportModal
    participant Page as ImportProjectsPage
    participant QC as QueryClient
    participant API as Host Service API

    U->>Modal: Click Import all
    Modal->>Page: importAll()
    Page->>Page: "setImportAllProgress({current:0, total:N})"

    loop for each project i
        Page->>QC: fetchQuery(findByPath)
        QC->>API: project.findByPath.query(...)
        API-->>QC: candidates / cloudErrors
        QC-->>Page: findByPathResult

        alt already imported / ambiguous / cloud-error
            Page->>Page: continue (skip)
        else importable
            Page->>API: project.setup.mutate OR project.create.mutate
            API-->>Page: result
            Page->>Page: finalizeSetup(activeHostUrl)
            Page->>QC: invalidateProjectImportQueries
        end

        Page->>Page: "setImportAllProgress({current:i, total:N})"
    end

    Page->>Page: setImportAllProgress(null) [finally]

    Note over U,Page: If user clicks Cancel mid-loop, modal unmounts but loop continues running
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportProjectsPage/ImportProjectsPage.tsx:66-114
**`importAll` loop is not cancellable after modal close**

Clicking "Cancel" while an import is in progress calls `close()`, which unmounts the modal, but the `importAll` async loop keeps running. Every subsequent iteration will still call `client.project.setup.mutate` / `client.project.create.mutate` and then `finalizeSetup`, creating or linking projects after the user has explicitly dismissed the wizard. The `setImportAllProgress(null)` call in `finally` also attempts to update state on an unmounted component.

A common fix is a cancellation ref: set it to `true` in a cleanup effect (or on the Cancel click), and check it at the top of each loop iteration before issuing any mutations.

### Issue 2 of 2
apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.test.tsx:25-27
**Test couples to Tailwind utility class names**

The assertions `expect(markup).toContain("-top-px")` and `expect(markup).toContain("h-px")` check for specific Tailwind class strings in the rendered HTML. Any future restyling of the progress bar (e.g. changing `h-px` to `h-[1px]` for consistency) would fail this test without any actual regression in behaviour. Consider asserting on the `role`, ARIA attributes, and inline `style` (which already drive correctness), rather than on CSS class tokens.

Reviews (1): Last reviewed commit: "Add v1 import step progress" | Re-trigger Greptile

Comment on lines +66 to +114
const importAll = async () => {
if (isImportingAll) return;
const queue = projects;
setImportAllProgress({ current: 0, total: queue.length });
try {
for (let i = 0; i < queue.length; i++) {
const project = queue[i];
if (!project) continue;
setImportAllProgress({ current: i, total: queue.length });
try {
const findByPathResult = await fetchProjectFindByPath(
queryClient,
project,
activeHostUrl,
);
if (isProjectAlreadyImported(findByPathResult)) {
continue;
}
if (findByPathResult.candidates.length > 1) {
continue;
}
if (
findByPathResult.candidates.length === 0 &&
findByPathResult.cloudErrors.length > 0
) {
continue;
}
const result = await importProject({
project,
activeHostUrl,
findByPathResult,
finalizeSetup,
});
if (result.kind === "imported") {
await invalidateProjectImportQueries(queryClient, project);
}
} catch (err) {
console.error("[v1-import] project import all failed", {
v1ProjectId: project.id,
mainRepoPath: project.mainRepoPath,
organizationId,
err,
});
}
}
} finally {
setImportAllProgress(null);
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 importAll loop is not cancellable after modal close

Clicking "Cancel" while an import is in progress calls close(), which unmounts the modal, but the importAll async loop keeps running. Every subsequent iteration will still call client.project.setup.mutate / client.project.create.mutate and then finalizeSetup, creating or linking projects after the user has explicitly dismissed the wizard. The setImportAllProgress(null) call in finally also attempts to update state on an unmounted component.

A common fix is a cancellation ref: set it to true in a cleanup effect (or on the Cancel click), and check it at the top of each loop iteration before issuing any mutations.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportProjectsPage/ImportProjectsPage.tsx
Line: 66-114

Comment:
**`importAll` loop is not cancellable after modal close**

Clicking "Cancel" while an import is in progress calls `close()`, which unmounts the modal, but the `importAll` async loop keeps running. Every subsequent iteration will still call `client.project.setup.mutate` / `client.project.create.mutate` and then `finalizeSetup`, creating or linking projects after the user has explicitly dismissed the wizard. The `setImportAllProgress(null)` call in `finally` also attempts to update state on an unmounted component.

A common fix is a cancellation ref: set it to `true` in a cleanup effect (or on the Cancel click), and check it at the top of each loop iteration before issuing any mutations.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +25 to +27
expect(markup).toContain("-top-px");
expect(markup).toContain("h-px");
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test couples to Tailwind utility class names

The assertions expect(markup).toContain("-top-px") and expect(markup).toContain("h-px") check for specific Tailwind class strings in the rendered HTML. Any future restyling of the progress bar (e.g. changing h-px to h-[1px] for consistency) would fail this test without any actual regression in behaviour. Consider asserting on the role, ARIA attributes, and inline style (which already drive correctness), rather than on CSS class tokens.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/components/StepProgress/StepProgress.test.tsx
Line: 25-27

Comment:
**Test couples to Tailwind utility class names**

The assertions `expect(markup).toContain("-top-px")` and `expect(markup).toContain("h-px")` check for specific Tailwind class strings in the rendered HTML. Any future restyling of the progress bar (e.g. changing `h-px` to `h-[1px]` for consistency) would fail this test without any actual regression in behaviour. Consider asserting on the `role`, ARIA attributes, and inline `style` (which already drive correctness), rather than on CSS class tokens.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

MocA-Love added a commit to MocA-Love/superset that referenced this pull request May 29, 2026
Non-applicable to current fork structure: superset-sh#3960 and superset-sh#4068 require linux-arm64/full CLI dist targets that this fork does not ship; superset-sh#4678 targets a relay deploy script intentionally absent from the fork; superset-sh#4694 requires DuckDB native packaging but the fork has no DuckDB runtime dependency; superset-sh#4822 targets removed v1 import modal paths; superset-sh#4826 assumes upstream release-cli.yml while this fork uses build-cli.yml with draft release semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant