diff --git a/projects/social_platform/src/app/ui/pages/program/management/management.component.spec.ts b/projects/social_platform/src/app/ui/pages/program/management/management.component.spec.ts index a894755d7..5b007eadc 100644 --- a/projects/social_platform/src/app/ui/pages/program/management/management.component.spec.ts +++ b/projects/social_platform/src/app/ui/pages/program/management/management.component.spec.ts @@ -285,6 +285,47 @@ describe("Списки управления программой в DOM", () => expect(state.retry).toHaveBeenCalledOnce(); expect(component.tableMessage()).toBe("Проект откреплен от программы."); }); + it.each([ + "?case_scope=selected&case_name=" + encodeURIComponent("Кейс №1") + "&offset=40", + "?case_scope=without_case&offset=40", + ])("после смены кейса последней строки возвращается на предыдущую страницу: %s", async query => { + const { component, state } = await setup("projects", query); + state.projects.update(page => page && { ...page, count: 41 }); + component.projectActionCompleted({ + programId: 1, + action: "change_case", + changedCount: 1, + alreadySubmittedCount: 0, + }); + await vi.waitFor(() => expect(state.context?.query.offset).toBe(20)); + expect(state.context?.query.caseScope).toBe( + query.includes("without_case") ? "without_case" : "selected", + ); + }); + it("после массовой сдачи исключает новые решения из фильтра несданных и исправляет страницу", async () => { + const { component, state } = await setup("projects", "?submission=not_submitted&offset=40"); + state.projects.update(page => page && { ...page, count: 41 }); + component.projectActionCompleted({ + programId: 1, + action: "submit", + changedCount: 21, + alreadySubmittedCount: 0, + }); + await vi.waitFor(() => expect(state.context?.query.offset).toBe(0)); + expect(state.context?.query.submission).toBe("not_submitted"); + }); + it("без фильтра кейса смена кейса сохраняет текущую страницу", async () => { + const { component, state } = await setup("projects", "?offset=40"); + state.projects.update(page => page && { ...page, count: 41 }); + component.projectActionCompleted({ + programId: 1, + action: "change_case", + changedCount: 1, + alreadySubmittedCount: 0, + }); + expect(state.context?.query.offset).toBe(40); + expect(state.retry).toHaveBeenCalledOnce(); + }); it("при401 показывает рабочую ссылку Войти с возвратом в текущую программу", async () => { const { state, harness, element } = await setup( "participants", diff --git a/projects/social_platform/src/app/ui/pages/program/management/management.component.ts b/projects/social_platform/src/app/ui/pages/program/management/management.component.ts index e9185fd68..336402434 100644 --- a/projects/social_platform/src/app/ui/pages/program/management/management.component.ts +++ b/projects/social_platform/src/app/ui/pages/program/management/management.component.ts @@ -985,7 +985,8 @@ export class ProgramManagementComponent implements OnInit { }); } projectActionCompleted(result: ProjectActionDone): void { - if (this.state.context?.programId !== result.programId || this.section() !== "projects") return; + const context = this.state.context; + if (!context || context.programId !== result.programId || this.section() !== "projects") return; this.projectActionRequest.set(null); this.clearRows(); this.tableMessage.set( @@ -995,13 +996,12 @@ export class ProgramManagementComponent implements OnInit { ? "Проект откреплен от программы." : `Сдано решений: ${result.changedCount}.`, ); - const lastOffset = - Math.max( - 0, - Math.ceil( - (this.count() - (result.action === "detach" ? result.changedCount : 0)) / this.pageSize, - ) - 1, - ) * this.pageSize; + const leavesSelection = + result.action === "detach" || + (result.action === "change_case" && context.query.caseScope !== "all") || + (result.action === "submit" && context.query.submission === "not_submitted"); + const remaining = this.count() - (leavesSelection ? result.changedCount : 0); + const lastOffset = Math.max(0, Math.ceil(remaining / this.pageSize) - 1) * this.pageSize; if (this.offset() > lastOffset) void this.changeQuery({ offset: lastOffset }); else this.state.retry(); }