feat(FN-3631): replicate task creation across mesh nodes and fix modal scrolling
- Add mesh task replication plumbing in core store/types with node-aware task creation metadata - Expose dashboard and mesh API route coverage for replicated task creation and sync behavior - Restore independent scrolling in Git Manager changes list and prevent Scripts modal scroll regressions - Expand tests across core, dashboard routes, API, and CLI extension insights for the new behavior Fusion-Task-Id: FN-3631
This commit is contained in:
@@ -1117,7 +1117,7 @@ function ChangesPanel({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="gm-file-list">
|
||||
<div className="gm-file-list gm-file-list-unstaged" data-testid="gm-file-list-unstaged">
|
||||
{unstagedFiles.length === 0 ? (
|
||||
<div className="gm-empty">No unstaged changes</div>
|
||||
) : (
|
||||
@@ -1189,7 +1189,7 @@ function ChangesPanel({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="gm-file-list">
|
||||
<div className="gm-file-list gm-file-list-staged" data-testid="gm-file-list-staged">
|
||||
{stagedFiles.length === 0 ? (
|
||||
<div className="gm-empty">No staged changes</div>
|
||||
) : (
|
||||
|
||||
@@ -2058,6 +2058,7 @@
|
||||
position: sticky;
|
||||
top: 0;
|
||||
align-self: start;
|
||||
min-height: 0;
|
||||
/* Cap the sticky column so its internal lists never push past the viewport
|
||||
* — without this, two long lists at max-height 200px each + headers can
|
||||
* exceed the available scroll-port height and the column visually clips. */
|
||||
@@ -2118,6 +2119,9 @@
|
||||
/* ── File Section ── */
|
||||
|
||||
.gm-file-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
@@ -2149,8 +2153,11 @@
|
||||
/* ── File List ── */
|
||||
|
||||
.gm-file-list {
|
||||
max-height: 200px;
|
||||
min-height: 0;
|
||||
max-height: calc(var(--space-2xl) * 6 + var(--space-md));
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.gm-file-item {
|
||||
|
||||
@@ -420,6 +420,35 @@ describe("GitManagerModal", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps separate scroll containers for unstaged and staged file lists", async () => {
|
||||
(fetchFileChanges as any).mockResolvedValue([
|
||||
...Array.from({ length: 30 }, (_, index) => ({
|
||||
file: `src/unstaged-${index}.ts`,
|
||||
status: "modified",
|
||||
staged: false,
|
||||
})),
|
||||
{ file: "src/staged.ts", status: "added", staged: true },
|
||||
]);
|
||||
|
||||
render(
|
||||
<GitManagerModal isOpen={true} onClose={vi.fn()} tasks={mockTasks} addToast={mockAddToast} />
|
||||
);
|
||||
fireEvent.click(screen.getByRole("tab", { name: /changes/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Unstaged Changes (30)")).toBeInTheDocument();
|
||||
expect(screen.getByText("Staged Changes (1)")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const unstagedList = screen.getByTestId("gm-file-list-unstaged");
|
||||
const stagedList = screen.getByTestId("gm-file-list-staged");
|
||||
|
||||
expect(unstagedList).toHaveClass("gm-file-list", "gm-file-list-unstaged");
|
||||
expect(stagedList).toHaveClass("gm-file-list", "gm-file-list-staged");
|
||||
expect(within(unstagedList).getAllByRole("button").length).toBeGreaterThan(10);
|
||||
expect(within(stagedList).getAllByRole("button").length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("stages all files when Stage All is clicked", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
|
||||
@@ -193,6 +193,22 @@ describe("core modals mobile css coverage", () => {
|
||||
expect(fileSectionRule![0]).toContain("max-width: 100%");
|
||||
});
|
||||
|
||||
it("GitManagerModal: file sections and file lists keep independent scrolling constraints", () => {
|
||||
const css = loadAllAppCss();
|
||||
|
||||
const fileSectionRule = css.match(/\.gm-file-section\s*\{[^}]+\}/s);
|
||||
expect(fileSectionRule).not.toBeNull();
|
||||
expect(fileSectionRule![0]).toContain("display: flex");
|
||||
expect(fileSectionRule![0]).toContain("flex-direction: column");
|
||||
expect(fileSectionRule![0]).toContain("min-height: 0");
|
||||
|
||||
const fileListRule = css.match(/\.gm-file-list\s*\{[^}]+\}/s);
|
||||
expect(fileListRule).not.toBeNull();
|
||||
expect(fileListRule![0]).toContain("overflow-y: auto");
|
||||
expect(fileListRule![0]).toContain("overscroll-behavior: contain");
|
||||
expect(fileListRule![0]).toContain("-webkit-overflow-scrolling: touch");
|
||||
});
|
||||
|
||||
it("GitManagerModal: modal uses full-screen viewport sizing on mobile (641-768px range)", () => {
|
||||
const css = loadAllAppCss();
|
||||
const mobileBlock = getMainMobileBlock(css);
|
||||
|
||||
Reference in New Issue
Block a user