Skip to content

Commit 52b3fe8

Browse files
committed
change snackbar, skill-group modal, add input type radio, goal service & logic to chosing
1 parent 9b8065e commit 52b3fe8

42 files changed

Lines changed: 958 additions & 168 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Основная модель целей проекта
3+
* Представляет цели со всей необходимой информацией
4+
*
5+
* Goal содержит:
6+
* - Основную информацию (проект, ответственного, название и дату)
7+
* - выполнена или нет цель
8+
* - полную информацию о человеке, который ответсвенен за цель
9+
*
10+
* @format
11+
*/
12+
13+
class responsibleInfo {
14+
id!: number;
15+
firstName!: string;
16+
lastName!: string;
17+
avatar!: string | null;
18+
}
19+
20+
export class Goal {
21+
id!: number;
22+
project!: number;
23+
title!: string;
24+
completionDate!: string;
25+
responsibleId!: number;
26+
responsibleInfo!: responsibleInfo;
27+
isDone!: boolean;
28+
}

projects/social_platform/src/app/office/projects/edit/edit.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ <h3 class="text-bold-body-16">📢 Внимание!</h3>
177177

178178
<app-modal [open]="skillsGroupsModalOpen()" class="modal">
179179
<div class="modal__wrapper">
180-
<h4 class="text-heading-4">Библиотека навыков</h4>
180+
<p class="text-body-14">Библиотека навыков</p>
181181
<div class="modal__content">
182182
<div class="modal__skills-groups">
183183
<ul>
@@ -187,7 +187,10 @@ <h4 class="text-heading-4">Библиотека навыков</h4>
187187
[title]="skillsGroup.name"
188188
[options]="skillsGroup.skills"
189189
[selected]="this.vacancyForm.getRawValue().skills"
190+
[hasOpenGroups]="hasOpenSkillsGroups"
191+
[disabled]="hasOpenSkillsGroups && !openGroupIds.has(skillsGroup.id)"
190192
(optionToggled)="onToggleSkill($event)"
193+
(groupToggled)="onGroupToggled($event, skillsGroup.id)"
191194
></app-skills-group>
192195
</li>
193196
}

projects/social_platform/src/app/office/projects/edit/edit.component.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ import { ProjectTeamService } from "./services/project-team.service";
4949
import { ProjectAdditionalStepComponent } from "./shared/project-additional-step/project-additional-step.component";
5050
import { ProjectAdditionalService } from "./services/project-additional.service";
5151
import { ProjectAchievementsService } from "./services/project-achievements.service";
52+
import { Goal } from "@office/models/goals.model";
53+
import { ProjectGoalService } from "./services/project-goals.service";
54+
import { SnackbarService } from "@ui/services/snackbar.service";
5255

5356
/**
5457
* Компонент редактирования проекта
@@ -116,6 +119,7 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
116119
private readonly projectVacancyService: ProjectVacancyService,
117120
private readonly projectTeamService: ProjectTeamService,
118121
private readonly projectAchievementsService: ProjectAchievementsService,
122+
private readonly snackBarService: SnackbarService,
119123
private readonly skillsService: SkillsService,
120124
private readonly projectAdditionalService: ProjectAdditionalService
121125
) {}
@@ -210,6 +214,10 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
210214
return this.projectStepService.getCurrentStep()();
211215
}
212216

217+
get hasOpenSkillsGroups(): boolean {
218+
return this.openGroupIds.size > 0;
219+
}
220+
213221
// Состояние компонента
214222
isCompleted = false;
215223
isSendDescisionToPartnerProgramProject = false;
@@ -251,6 +259,7 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
251259
projSubmitInitiated = false;
252260
projFormIsSubmittingAsPublished = false;
253261
projFormIsSubmittingAsDraft = false;
262+
openGroupIds = new Set<number>();
254263

255264
/**
256265
* Навигация между шагами редактирования
@@ -260,6 +269,14 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
260269
this.projectStepService.navigateToStep(step);
261270
}
262271

272+
onGroupToggled(isOpen: boolean, groupId: number) {
273+
if (isOpen) {
274+
this.openGroupIds.add(groupId);
275+
} else {
276+
this.openGroupIds.delete(groupId);
277+
}
278+
}
279+
263280
/**
264281
* Привязка проекта к программе выбранной
265282
* Перенаправление её на редактирование "нового" проекта
@@ -382,6 +399,8 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
382399
this.projectVacancyService.submitVacancy(projectId);
383400
}
384401

402+
console.log(payload.goals);
403+
385404
if (
386405
!this.validationService.getFormValidation(this.projectForm) ||
387406
!this.validationService.getFormValidation(this.additionalForm) ||
@@ -391,15 +410,17 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
391410
}
392411

393412
this.setProjFormIsSubmitting(true);
394-
this.projectService.updateProject(projectId, payload).subscribe({
395-
next: () => {
396-
this.setProjFormIsSubmitting(false);
397-
this.router.navigateByUrl(`/office/projects/my`);
398-
},
399-
error: () => {
400-
this.setProjFormIsSubmitting(false);
401-
},
402-
});
413+
// this.projectService.updateProject(projectId, payload).subscribe({
414+
// next: () => {
415+
// this.snackBarService.success("Данные успешно сохранены");
416+
// this.setProjFormIsSubmitting(false);
417+
// this.router.navigateByUrl(`/office/projects/my`);
418+
// },
419+
// error: () => {
420+
// this.setProjFormIsSubmitting(false);
421+
// this.snackBarService.error("Что-то пошло не так!");
422+
// },
423+
// });
403424
}
404425

405426
// Методы для работы с модальными окнами
@@ -565,9 +586,9 @@ export class ProjectEditComponent implements OnInit, AfterViewInit, OnDestroy {
565586
concatMap(() => this.route.data),
566587
map(d => d["data"])
567588
)
568-
.subscribe(([project, invites]: [Project, Invite[]]) => {
589+
.subscribe(([project, goals, invites]: [Project, Goal[], Invite[]]) => {
569590
// Используем сервис для инициализации данных проекта
570-
this.projectFormService.initializeProjectData(project);
591+
this.projectFormService.initializeProjectData(project, goals);
571592
this.projectTeamService.setInvites(invites);
572593
this.projectTeamService.setCollaborators(project.collaborators);
573594

projects/social_platform/src/app/office/projects/edit/edit.resolver.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ProjectService } from "@services/project.service";
77
import { Project } from "@models/project.model";
88
import { InviteService } from "@services/invite.service";
99
import { Invite } from "@models/invite.model";
10+
import { Goal } from "@office/models/goals.model";
1011

1112
/**
1213
* Resolver для загрузки данных редактирования проекта
@@ -30,16 +31,17 @@ import { Invite } from "@models/invite.model";
3031
* Применяет forkJoin для параллельной загрузки данных проекта и приглашений,
3132
* что оптимизирует время загрузки страницы.
3233
*/
33-
export const ProjectEditResolver: ResolveFn<[Project, Invite[]]> = (
34+
export const ProjectEditResolver: ResolveFn<[Project, Goal[], Invite[]]> = (
3435
route: ActivatedRouteSnapshot
3536
) => {
3637
const projectService = inject(ProjectService);
3738
const inviteService = inject(InviteService);
3839

3940
const projectId = Number(route.paramMap.get("projectId"));
4041

41-
return forkJoin<[Project, Invite[]]>([
42+
return forkJoin<[Project, Goal[], Invite[]]>([
4243
projectService.getOne(projectId),
44+
projectService.getGoals(projectId),
4345
inviteService.getByProject(projectId),
4446
]);
4547
};

projects/social_platform/src/app/office/projects/edit/services/project-achievements.service.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,19 @@ export class ProjectAchievementsService {
5555
this.initializeAchievementsItems(achievementsFormArray);
5656

5757
// Считываем вводимые данные
58-
const achievementsName = projectForm.get("achievementsName")?.value;
59-
const achievementsDate = projectForm.get("achievementsDate")?.value;
58+
const title = projectForm.get("title")?.value;
59+
const status = projectForm.get("status")?.value;
6060

6161
// Проверяем, что поля не пустые
62-
if (
63-
!achievementsName ||
64-
!achievementsDate ||
65-
achievementsName.trim().length === 0 ||
66-
achievementsDate.trim().length === 0
67-
) {
62+
if (!title || !status || title.trim().length === 0 || status.trim().length === 0) {
6863
return; // Выходим из функции, если поля пустые
6964
}
7065

7166
// Создаем FormGroup для нового достижения
7267
const achievementItem = this.fb.group({
7368
id: achievementsFormArray.length,
74-
achievementsName: achievementsName.trim(),
75-
achievementsDate: achievementsDate.trim(),
69+
title: title.trim(),
70+
status: status.trim(),
7671
});
7772

7873
// Проверяем, редактируется ли существующее достижение
@@ -94,11 +89,11 @@ export class ProjectAchievementsService {
9489
}
9590

9691
// Очищаем поля ввода формы проекта
97-
projectForm.get("achievementsName")?.reset();
98-
projectForm.get("achievementsName")?.setValue("");
92+
projectForm.get("title")?.reset();
93+
projectForm.get("title")?.setValue("");
9994

100-
projectForm.get("achievementsDate")?.reset();
101-
projectForm.get("achievementsDate")?.setValue("");
95+
projectForm.get("status")?.reset();
96+
projectForm.get("status")?.setValue("");
10297
}
10398

10499
/**

projects/social_platform/src/app/office/projects/edit/services/project-contacts.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @format */
22

33
import { inject, Injectable, signal } from "@angular/core";
4-
import { FormArray, FormBuilder, FormGroup, FormControl } from "@angular/forms";
4+
import { FormArray, FormBuilder, FormGroup, FormControl, Validators } from "@angular/forms";
55
import { ProjectFormService } from "./project-form.service";
66

77
/**
@@ -104,7 +104,7 @@ export class ProjectContactsService {
104104
} else {
105105
// Добавляем новую ссылку в сигнал и FormArray
106106
this.linksItems.update(items => [...items, trimmedLink.value]);
107-
linksFormArray.push(trimmedLink);
107+
linksFormArray.push(this.fb.control(trimmedLink, Validators.required));
108108
}
109109

110110
// Очищаем поле ввода формы проекта

projects/social_platform/src/app/office/projects/edit/services/project-form.service.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ValidatorFn,
1111
} from "@angular/forms";
1212
import { ActivatedRoute } from "@angular/router";
13+
import { Goal } from "@office/models/goals.model";
1314
import { PartnerProgramFields } from "@office/models/partner-program-fields.model";
1415
import { Project } from "@office/models/project.model";
1516
import { ProjectService } from "@office/services/project.service";
@@ -56,8 +57,14 @@ export class ProjectFormService {
5657
problem: ["", [Validators.required, Validators.maxLength(1000)]],
5758
partnerProgramId: [null],
5859
achievements: this.fb.array([]),
59-
achievementsName: [""],
60-
achievementsDate: [""],
60+
title: [""],
61+
status: [""],
62+
63+
goals: this.fb.array([]),
64+
goalName: [""],
65+
goalDate: [""],
66+
goalLeader: [null],
67+
6168
draft: [null],
6269
});
6370

@@ -92,7 +99,7 @@ export class ProjectFormService {
9299
* Заполняет основную форму данными существующего проекта.
93100
* @param project экземпляр Project с текущими данными
94101
*/
95-
public initializeProjectData(project: Project): void {
102+
public initializeProjectData(project: Project, goals: Goal[]): void {
96103
// Заполняем простые поля
97104
this.projectForm.patchValue({
98105
imageAddress: project.imageAddress,
@@ -117,6 +124,8 @@ export class ProjectFormService {
117124
this.populateLinksFormArray(project.links || []);
118125

119126
this.populateAchievementsFormArray(project.achievements || []);
127+
128+
this.populateGoalsFormArray(goals || []);
120129
}
121130

122131
/**
@@ -131,7 +140,7 @@ export class ProjectFormService {
131140
}
132141

133142
links.forEach(link => {
134-
linksFormArray.push(this.fb.control(link));
143+
linksFormArray.push(this.fb.control(link, [Validators.required]));
135144
});
136145
}
137146

@@ -149,13 +158,35 @@ export class ProjectFormService {
149158
achievements.forEach((achievement, index) => {
150159
const achievementGroup = this.fb.group({
151160
id: achievement.id ?? index,
152-
achievementsName: [achievement.achievementsName || "", Validators.required],
153-
achievementsDate: [achievement.achievementsDate || "", Validators.required],
161+
title: [achievement.title || "", Validators.required],
162+
status: [achievement.status || "", Validators.required],
154163
});
155164
achievementsFormArray.push(achievementGroup);
156165
});
157166
}
158167

168+
/**
169+
* Заполняет FormArray цели данными из проекта
170+
* @param goals массив целей из проекта
171+
*/
172+
private populateGoalsFormArray(goals: any[]): void {
173+
const goalsFormArray = this.projectForm.get("goals") as FormArray;
174+
175+
while (goalsFormArray.length !== 0) {
176+
goalsFormArray.removeAt(0);
177+
}
178+
179+
goals.forEach(goal => {
180+
const goalsGroup = this.fb.group({
181+
goalName: [goal.goalName || "", Validators.required],
182+
goalDate: [goal.goalDate || "", Validators.required],
183+
goalLeader: [goal.goalLeader || "", Validators.required],
184+
isDone: false,
185+
});
186+
goalsFormArray.push(goalsGroup);
187+
});
188+
}
189+
159190
/**
160191
* Возвращает основную форму проекта.
161192
* @returns FormGroup экземпляр формы проекта

0 commit comments

Comments
 (0)