fix(web): preserve pending projects on stale refresh

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
bulai0408 2026-05-24 05:55:49 +08:00
parent 0e658aa2da
commit d19270ec4c
2 changed files with 36 additions and 3 deletions

View file

@ -318,12 +318,9 @@ export function App() {
activeDeletedProjectIds.size > 0
? new Set(visibleList.map((project) => project.id))
: fetchedIds;
const preserveLocalProjects =
request.mutationVersion < projectListMutationVersionRef.current;
setProjects((current) => {
const preserved = current.filter(
(project) =>
preserveLocalProjects &&
pendingLocalProjectIds.has(project.id) &&
!visibleFetchedIds.has(project.id) &&
!activeDeletedProjectIds.has(project.id),

View file

@ -281,6 +281,42 @@ describe('App project creation routing', () => {
expect(window.location.pathname).toBe('/projects/project-new');
});
it('keeps a newly created project open when a post-create refresh resolves stale', async () => {
const bootstrapProjects = deferred<Project[]>();
const staleRefreshProjects = deferred<Project[]>();
mockedListProjects
.mockReturnValueOnce(bootstrapProjects.promise)
.mockReturnValueOnce(staleRefreshProjects.promise)
.mockResolvedValue([]);
render(<App />);
fireEvent.click(await screen.findByRole('button', { name: 'Create project' }));
await waitFor(() => {
expect(screen.getByTestId('project-title').textContent).toBe('Fresh project');
});
expect(window.location.pathname).toBe('/projects/project-new');
fireEvent.click(screen.getByRole('button', { name: 'Refresh projects' }));
await act(async () => {
staleRefreshProjects.resolve([]);
await staleRefreshProjects.promise;
});
expect(screen.getByTestId('project-title').textContent).toBe('Fresh project');
expect(window.location.pathname).toBe('/projects/project-new');
await act(async () => {
bootstrapProjects.resolve([]);
await bootstrapProjects.promise;
});
expect(screen.getByTestId('project-title').textContent).toBe('Fresh project');
expect(window.location.pathname).toBe('/projects/project-new');
});
it('ignores an older stale project list after a newer response confirms the local project', async () => {
const bootstrapProjects = deferred<Project[]>();
const refreshedProjects = deferred<Project[]>();