Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,19 @@ export interface ManagementSelection {
projects?: ManagementSelectionProject[];
}
export interface ParticipantRemovalPreview {
confirmationVersion: 2;
previewToken: string;
participantCount: number;
applications: { id: number; projectId: number; name: string; submitted: boolean }[];
assignmentsCount: number;
teamChanges: {
id: number;
projectId: number;
name: string;
submitted: boolean;
members: { id: number; name: string }[];
invitationsCount: number;
}[];
}
export interface ManagementSettingsWrite {
expectedUpdatedAt: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,22 @@ describe("Контракт HTTP панели организатора", () => {
.previewParticipantRemoval(4, [1, 21])
.subscribe(result => expect(result.previewToken).toBe("proof"));
const preview = http.expectOne(r => r.url.endsWith("/remove-preview/"));
preview.flush({ preview_token: "proof", participant_count: 2, applications: [] });
preview.flush({
confirmation_version: 2,
preview_token: "proof",
participant_count: 2,
applications: [],
team_changes: [],
assignments_count: 0,
});
const failed = vi.fn();
adapter.removeParticipants(4, [1, 21], "proof").subscribe({ error: failed });
const removal = http.expectOne(r => r.url.endsWith("/participants/remove/"));
expect(removal.request.body).toEqual({ ids: [1, 21], preview_token: "proof" });
expect(removal.request.body).toEqual({
ids: [1, 21],
preview_token: "proof",
confirmation_version: 2,
});
removal.flush({ detail: "Изменено" }, { status: 409, statusText: "Conflict" });
expect(failed).toHaveBeenCalledOnce();
http.expectNone(r => r.url.endsWith("/participants/remove/"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class ProgramManagementHttpAdapter implements ProgramManagementRepository
return this.api.post<{ removed: number }>(`${this.root(id)}/participants/remove/`, {
ids,
previewToken,
confirmationVersion: 2,
});
}
private participantParams(q: ManagementQuery): HttpParams {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,36 @@ <h3>В программе пока нет материалов</h3>
<section class="management__dialog">
<h2 id="participant-removal-title">Удалить участников из программы?</h2>
<p>Участников: {{ removal.preview.participantCount }}. Аккаунты на платформе сохранятся.</p>
<p>Участники останутся в командах проектов на платформе.</p>
<p>
Участники будут удалены из команд проектов-заявок этой программы. Команды исходных проектов
на платформе сохранятся.
</p>
@if (removal.preview.teamChanges.length) {
<div>
<h3>Изменятся команды заявок</h3>
<ul class="management__removal-projects">
@for (change of removal.preview.teamChanges; track change.id) {
<li>
<strong>{{ change.name }}</strong>
@if (change.members.length) {
<p>
Удаляем из команды:
@for (member of change.members; track member.id; let last = $last) {
{{ member.name }}{{ last ? "" : ", " }}
}
</p>
}
@if (change.invitationsCount) {
<p>Приглашений в заявку к отзыву: {{ change.invitationsCount }}.</p>
}
@if (change.submitted) {
<p>Заявка уже сдана. Сохраненные оценки не изменятся.</p>
}
</li>
}
</ul>
</div>
}
@if (removal.preview.applications.length) {
<div appAlert="warning">
<strong>Среди выбранных есть руководители проектов</strong>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ManagementProject,
ManagementProjectsPage,
ProgramManagement,
ParticipantRemovalPreview,
} from "@domain/program/program-management.model";
import { ProgramManagementComponent } from "./management.component";
import { ProgramProjectAssignmentSelection } from "@api/program/facades/detail/program-project-assignment-selection.service";
Expand Down Expand Up @@ -189,8 +190,15 @@ describe("Списки управления программой в DOM", () =>
context: null as ManagementContext | null,
api: {
selection: vi.fn(() => of({ ids: Array.from({ length: 41 }, (_, i) => i + 1) })),
previewParticipantRemoval: vi.fn(() =>
of({ previewToken: "proof", participantCount: 1, applications: [], assignmentsCount: 0 }),
previewParticipantRemoval: vi.fn<() => Observable<ParticipantRemovalPreview>>(() =>
of({
confirmationVersion: 2,
previewToken: "proof",
participantCount: 1,
applications: [],
assignmentsCount: 0,
teamChanges: [],
}),
),
removeParticipants: vi.fn(() => of({ removed: 1 })),
},
Expand Down Expand Up @@ -624,4 +632,43 @@ describe("Списки управления программой в DOM", () =>
expect(component.selectedRows().size).toBe(0);
expect(state.retry).toHaveBeenCalledOnce();
});
it("подтверждение показывает команду заявки и сохраняемый исходный проект отдельно", async () => {
const { component, state, harness, element } = await setup();
state.api.previewParticipantRemoval.mockReturnValue(
of({
confirmationVersion: 2,
previewToken: "proof",
participantCount: 1,
applications: [],
assignmentsCount: 0,
teamChanges: [
{
id: 11,
projectId: 91,
name: "Заявка команды",
submitted: true,
members: [{ id: 51, name: "Анна" }],
invitationsCount: 1,
},
],
}),
);
component.previewParticipantRemoval([1]);
harness.detectChanges();
await vi.waitFor(() => {
harness.detectChanges();
expect(
document.querySelector('[role="dialog"][aria-labelledby="participant-removal-title"]'),
).toBeTruthy();
});
const dialog = document.querySelector(
'[role="dialog"][aria-labelledby="participant-removal-title"]',
)!;
expect(dialog.textContent).toContain("Команды исходных проектов на платформе сохранятся");
expect(dialog.textContent).toContain("Заявка команды");
expect(dialog.textContent).toContain("Анна");
expect(dialog.textContent).toContain("Сохраненные оценки не изменятся");
expect(state.api.removeParticipants).not.toHaveBeenCalled();
expect(element().querySelector(".management__participants")).toBeTruthy();
});
});