Skip to content

Commit 31db91d

Browse files
committed
add link block to main stage
1 parent 4460649 commit 31db91d

8 files changed

Lines changed: 248 additions & 104 deletions

File tree

Lines changed: 108 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,169 @@
11
/** @format */
22

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

7+
/**
8+
* Сервис для управления контактами проекта.
9+
* Предоставляет методы для добавления, редактирования, удаления ссылок,
10+
* а также очистки ошибок валидации.
11+
*/
712
@Injectable({
813
providedIn: "root",
914
})
1015
export class ProjectContactsService {
16+
/** FormBuilder для создания FormGroup элементов */
1117
private readonly fb = inject(FormBuilder);
18+
/** Сервис для управления индексом редактируемой ссылки */
1219
private readonly projectFormService = inject(ProjectFormService);
20+
/** Сигнал для хранения списка ссылок (массив объектов) */
1321
public readonly linksItems = signal<any[]>([]);
22+
private initialized = false;
1423

15-
constructor() {
16-
effect(() => {
17-
const formArray = this.links;
18-
if (formArray && formArray.length > 0) {
19-
const currentSignalValue = this.linksItems();
20-
const formArrayValue = formArray.value;
24+
/**
25+
* Инициализирует сигнал linksItems из данных FormArray
26+
* Вызывается при первом обращении к данным
27+
*/
28+
private initializeLinksItems(linksFormArray: FormArray): void {
29+
if (this.initialized) return;
2130

22-
if (JSON.stringify(currentSignalValue) !== JSON.stringify(formArrayValue)) {
23-
this.linksItems.set(formArrayValue);
24-
}
25-
}
26-
});
31+
if (linksFormArray && linksFormArray.length > 0) {
32+
// Синхронизируем сигнал с данными из FormArray
33+
this.linksItems.set(linksFormArray.value);
34+
}
35+
this.initialized = true;
2736
}
2837

38+
/**
39+
* Принудительно синхронизирует сигнал с FormArray
40+
* Полезно вызывать после загрузки данных с сервера
41+
*/
42+
public syncLinksItems(linksFormArray: FormArray): void {
43+
if (linksFormArray) {
44+
this.linksItems.set(linksFormArray.value);
45+
}
46+
}
47+
48+
/**
49+
* Получает основную форму проекта
50+
*/
2951
private get projectForm(): FormGroup {
3052
return this.projectFormService.getForm();
3153
}
3254

55+
/**
56+
* Получает FormArray ссылок
57+
*/
3358
public get links(): FormArray {
3459
return this.projectForm.get("links") as FormArray;
3560
}
3661

62+
/**
63+
* Получает FormControl для поля ввода ссылки
64+
*/
3765
public get link(): FormControl {
3866
return this.projectForm.get("link") as FormControl;
3967
}
4068

4169
/**
42-
* Принудительная синхронизация сигнала с FormArray
43-
* Вызывается после загрузки данных проекта
70+
* Добавляет новую ссылку или сохраняет изменения существующей.
71+
* @param linksFormArray FormArray, содержащий формы ссылок
72+
* @param projectForm основная форма проекта (FormGroup)
4473
*/
45-
public syncLinksItems(): void {
46-
const linksFormArray = this.links;
47-
if (linksFormArray && linksFormArray.length > 0) {
48-
this.linksItems.set(linksFormArray.value);
49-
} else {
50-
this.linksItems.set([]);
51-
}
52-
}
74+
public addLink(linksFormArray: FormArray, projectForm: FormGroup): void {
75+
// Инициализируем сигнал при первом вызове
76+
this.initializeLinksItems(linksFormArray);
5377

54-
public addLink(): void {
55-
const linkValue = this.link?.value;
78+
// Считываем вводимые данные
79+
const linkValue = projectForm.get("link")?.value;
5680

81+
// Проверяем, что поле не пустое и содержит валидный URL
5782
if (
5883
!linkValue ||
5984
!linkValue.trim() ||
60-
!linkValue.includes("https://") ||
61-
!linkValue.includes("http://")
85+
(!linkValue.includes("https://") && !linkValue.includes("http://"))
6286
) {
63-
return;
87+
return; // Выходим из функции, если поле пустое или невалидное
6488
}
6589

6690
const trimmedLink = linkValue.trim();
67-
const editIdx = this.projectFormService.editIndex();
6891

92+
// Проверяем, редактируется ли существующая ссылка
93+
const editIdx = this.projectFormService.editIndex();
6994
if (editIdx !== null) {
70-
// Режим редактирования
71-
this.links.at(editIdx).setValue(trimmedLink);
95+
// Обновляем массив сигналов и соответствующий контрол в FormArray
7296
this.linksItems.update(items => {
7397
const updated = [...items];
74-
updated[editIdx] = trimmedLink;
98+
updated[editIdx] = trimmedLink.value;
7599
return updated;
76100
});
101+
linksFormArray.at(editIdx).patchValue(trimmedLink.value);
102+
// Сбрасываем индекс редактирования
77103
this.projectFormService.editIndex.set(null);
78104
} else {
79-
// Добавление нового элемента
80-
this.links.push(this.fb.control(trimmedLink));
81-
this.linksItems.update(items => [...items, trimmedLink]);
105+
// Добавляем новую ссылку в сигнал и FormArray
106+
this.linksItems.update(items => [...items, trimmedLink.value]);
107+
linksFormArray.push(trimmedLink);
82108
}
83109

84-
// Очищаем поле ввода
85-
this.link?.reset();
86-
this.link?.setValue("");
110+
// Очищаем поле ввода формы проекта
111+
projectForm.get("link")?.reset();
112+
projectForm.get("link")?.setValue("");
87113
}
88114

89-
public editLink(index: number): void {
90-
const value = this.links.value[index];
91-
this.projectForm.patchValue({ link: value });
115+
/**
116+
* Инициализирует редактирование существующей ссылки.
117+
* @param index индекс ссылки в списке
118+
* @param linksFormArray FormArray ссылок
119+
* @param projectForm основная форма проекта
120+
*/
121+
public editLink(index: number, linksFormArray: FormArray, projectForm: FormGroup): void {
122+
// Инициализируем сигнал при необходимости
123+
this.initializeLinksItems(linksFormArray);
124+
125+
// Используем данные из FormArray как источник истины
126+
const source = linksFormArray.value[index];
127+
128+
// Заполняем поле формы проекта для редактирования
129+
projectForm.patchValue({
130+
link: source?.link || "",
131+
});
132+
// Устанавливаем текущий индекс редактирования в сервисе
92133
this.projectFormService.editIndex.set(index);
93134
}
94135

95-
public removeLink(index: number): void {
96-
this.links.removeAt(index);
136+
/**
137+
* Удаляет ссылку по указанному индексу.
138+
* @param index индекс удаляемой ссылки
139+
* @param linksFormArray FormArray ссылок
140+
*/
141+
public removeLink(index: number, linksFormArray: FormArray): void {
142+
// Удаляем из сигнала и из FormArray
97143
this.linksItems.update(items => items.filter((_, i) => i !== index));
144+
linksFormArray.removeAt(index);
145+
}
146+
147+
/**
148+
* Сбрасывает все ошибки валидации во всех контролах FormArray ссылок.
149+
* @param links FormArray ссылок
150+
*/
151+
public clearAllLinksErrors(links: FormArray): void {
152+
links.controls.forEach(control => {
153+
if (control instanceof FormGroup) {
154+
Object.keys(control.controls).forEach(key => {
155+
control.get(key)?.setErrors(null);
156+
});
157+
}
158+
});
98159
}
99160

161+
/**
162+
* Сбрасывает состояние сервиса
163+
* Полезно при смене проекта или очистке формы
164+
*/
100165
public reset(): void {
101166
this.linksItems.set([]);
167+
this.initialized = false;
102168
}
103169
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,10 @@ export class ProjectFormService {
126126
private populateLinksFormArray(links: string[]): void {
127127
const linksFormArray = this.projectForm.get("links") as FormArray;
128128

129-
// Очищаем существующие контролы
130129
while (linksFormArray.length !== 0) {
131130
linksFormArray.removeAt(0);
132131
}
133132

134-
// Добавляем новые контролы
135133
links.forEach(link => {
136134
linksFormArray.push(this.fb.control(link));
137135
});

projects/social_platform/src/app/office/projects/edit/shared/project-contacts-step/project-contacts-step.component.html

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
11
<!-- @format -->
22

33
<div [formGroup]="projectForm" class="project__inner">
4-
<!-- @if(link; as link){
5-
<fieldset class="project__left">
6-
<label class="field-label">Ссылка на контакты</label>
7-
<app-input
8-
class="edit-link__input"
9-
formControlName="link"
10-
placeholder="https://example.com"
11-
></app-input>
12-
@if (link | controlError: "pattern") {
13-
<div class="text-body-10 error">
14-
{{ errorMessage.VALIDATION_PATTERN }}
15-
</div>
16-
}
17-
</fieldset>
18-
} -->
19-
204
<div class="project__left">
215
<!-- <ul class="invite__list">
226
@if(linksItems().length || links.length){ @for (linkItem of links.value; track $index) {
@@ -35,7 +19,6 @@
3519
size="big"
3620
appearance="outline"
3721
customTypographyClass="text-body-12"
38-
(click)="addLink()"
3922
class="vacancy__submit"
4023
>
4124
<span>Добавить партнера</span>
@@ -61,15 +44,14 @@
6144
size="big"
6245
appearance="outline"
6346
customTypographyClass="text-body-12"
64-
(click)="addLink()"
6547
class="vacancy__submit"
6648
>
6749
<span>Добавить ресурс</span>
6850
<i appIcon icon="plus" appSquare="12"></i>
6951
</app-button>
7052
</div>
7153

72-
@if (!links.length) {
54+
<!-- @if (!resources.length) {
7355
<i appIcon icon="sad-smile" appSquare="20" class="project__no-items"></i>
74-
}
56+
} -->
7557
</div>

projects/social_platform/src/app/office/projects/edit/shared/project-contacts-step/project-contacts-step.component.ts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,4 @@ export class ProjectContactsStepComponent {
3535
get projectForm(): FormGroup {
3636
return this.projectFormService.getForm();
3737
}
38-
39-
// Получаем поля из формы из сервиса
40-
get linksItems() {
41-
return this.projectContactsService.linksItems;
42-
}
43-
44-
get link() {
45-
return this.projectContactsService.link;
46-
}
47-
48-
get links(): FormArray {
49-
return this.projectContactsService.links;
50-
}
51-
52-
/**
53-
* Добавление ссылки
54-
*/
55-
addLink(): void {
56-
this.projectContactsService.addLink();
57-
}
58-
59-
/**
60-
* Редактирование ссылки
61-
* @param index - индекс ссылки
62-
*/
63-
editLink(index: number): void {
64-
this.projectContactsService.editLink(index);
65-
}
66-
67-
/**
68-
* Удаление ссылки
69-
* @param index - индекс ссылки
70-
*/
71-
removeLink(index: number): void {
72-
this.projectContactsService.removeLink(index);
73-
}
7438
}

projects/social_platform/src/app/office/projects/edit/shared/project-main-step/project-main-step.component.html

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,49 @@
282282
<i appIcon icon="plus" appSquare="12"></i>
283283
</app-button>
284284

285-
<app-button size="big" appearance="outline" customTypographyClass="text-body-12">
285+
<div>
286+
@if (hasLinks) {
287+
<ul formArrayName="links" class="project__links--wrapper">
288+
@for (control of links.controls; track i; let i = $index) {
289+
<li class="project__links">
290+
<form [formGroupName]="i" class="project__links">
291+
@if (links.at(i)?.get("link"); as link) {
292+
<fieldset style="flex-grow: 1">
293+
<label class="text-body-12 field-label">Ссылка на контакты и сообщества</label>
294+
<app-input
295+
size="big"
296+
[error]="link | controlError"
297+
placeholder="@eeeasycarrer"
298+
formControlName="link"
299+
></app-input>
300+
@if (link | controlError: "required") {
301+
<div class="text-body-10 error">
302+
{{ errorMessage.VALIDATION_REQUIRED }}
303+
</div>
304+
}
305+
</fieldset>
306+
}
307+
</form>
308+
<app-button
309+
class="project__links--remove"
310+
color="red"
311+
(click)="removeLink(i)"
312+
type="button"
313+
>
314+
<i appIcon icon="basket" appSquare="20"></i>
315+
</app-button>
316+
</li>
317+
}
318+
</ul>
319+
}
320+
</div>
321+
322+
<app-button
323+
(click)="addLink()"
324+
size="big"
325+
appearance="outline"
326+
customTypographyClass="text-body-12"
327+
>
286328
<span>Добавить ссылку на контакты и сообщества</span>
287329
<i appIcon icon="plus" appSquare="12"></i>
288330
</app-button>

0 commit comments

Comments
 (0)