@@ -10,7 +10,17 @@ import {
1010} from "@angular/core" ;
1111import { ProgramService } from "@office/program/services/program.service" ;
1212import { ActivatedRoute , Router , RouterLink } from "@angular/router" ;
13- import { concatMap , fromEvent , map , noop , of , Subscription , tap , throttleTime } from "rxjs" ;
13+ import {
14+ concatMap ,
15+ fromEvent ,
16+ map ,
17+ noop ,
18+ Observable ,
19+ of ,
20+ Subscription ,
21+ tap ,
22+ throttleTime ,
23+ } from "rxjs" ;
1424import { Program } from "@office/program/models/program.model" ;
1525import { ProgramNewsService } from "@office/program/services/program-news.service" ;
1626import { FeedNews } from "@office/projects/models/project-news.model" ;
@@ -25,51 +35,10 @@ import { TagComponent } from "@ui/components/tag/tag.component";
2535import { NewsFormComponent } from "@office/shared/news-form/news-form.component" ;
2636import { ModalComponent } from "@ui/components/modal/modal.component" ;
2737import { ProjectService } from "@office/services/project.service" ;
38+ import { MatProgressBarModule } from "@angular/material/progress-bar" ;
39+ import { AsyncPipe } from "@angular/common" ;
40+ import { LoadingService } from "@office/services/loading.service" ;
2841
29- /**
30- * Главный компонент детальной страницы программы
31- *
32- * Отображает основную информацию о программе и новостную ленту:
33- * - Детальное описание программы с возможностью развернуть/свернуть
34- * - Информацию о датах и регистрации
35- * - Новостную ленту для участников программы
36- * - Форму добавления новостей
37- * - Взаимодействие с новостями (лайки, просмотры)
38- *
39- * Принимает:
40- * @param {ProgramService } programService - Сервис программ
41- * @param {ProgramNewsService } programNewsService - Сервис новостей программы
42- * @param {ActivatedRoute } route - Для получения данных программы
43- * @param {ChangeDetectorRef } cdRef - Для ручного обновления представления
44- *
45- * Состояние (signals):
46- * @property {Signal<FeedNews[]> } news - Массив новостей программы
47- * @property {Signal<number> } totalNewsCount - Общее количество новостей
48- * @property {Signal<number> } fetchLimit - Лимит загрузки новостей (10)
49- * @property {Signal<number> } fetchPage - Текущая страница новостей
50- * @property {Signal<Subscription[]> } subscriptions$ - Подписки для очистки
51- *
52- * Данные программы:
53- * @property {Program } program - Объект программы
54- * @property {boolean } registerDateExpired - Истек ли срок регистрации
55- * @property {boolean } descriptionExpandable - Можно ли развернуть описание
56- * @property {boolean } readFullDescription - Развернуто ли описание
57- *
58- * ViewChild:
59- * @ViewChild NewsFormComponent - Ссылка на компонент формы новостей
60- * @ViewChild descEl - Ссылка на элемент описания
61- *
62- * Методы:
63- * @method fetchNews(offset, limit) - Загружает новости с пагинацией
64- * @method onScroll() - Обработчик прокрутки для подгрузки новостей
65- * @method onNewsInVew(entries) - Отмечает новости как просмотренные
66- * @method onAddNews(news) - Добавляет новую новость
67- * @method onLike(newsId) - Переключает лайк новости
68- * @method onExpandDescription() - Разворачивает/сворачивает описание
69- *
70- * Возвращает:
71- * HTML шаблон с информацией о программе и новостной лентой
72- */
7342@Component ( {
7443 selector : "app-main" ,
7544 templateUrl : "./main.component.html" ,
@@ -83,10 +52,12 @@ import { ProjectService } from "@office/services/project.service";
8352 ProgramNewsCardComponent ,
8453 TagComponent ,
8554 UserLinksPipe ,
55+ AsyncPipe ,
8656 ParseBreaksPipe ,
8757 ParseLinksPipe ,
8858 NewsFormComponent ,
8959 ModalComponent ,
60+ MatProgressBarModule ,
9061 ] ,
9162} )
9263export class ProgramDetailMainComponent implements OnInit , OnDestroy {
@@ -96,7 +67,8 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
9667 private readonly projectService : ProjectService ,
9768 private readonly router : Router ,
9869 private readonly route : ActivatedRoute ,
99- private readonly cdRef : ChangeDetectorRef
70+ private readonly cdRef : ChangeDetectorRef ,
71+ private readonly loadingService : LoadingService
10072 ) { }
10173
10274 news = signal < FeedNews [ ] > ( [ ] ) ;
@@ -110,6 +82,7 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
11082 programId ?: number ;
11183
11284 subscriptions$ = signal < Subscription [ ] > ( [ ] ) ;
85+
11386 ngOnInit ( ) : void {
11487 const programIdSubscription$ = this . route . params
11588 . pipe (
@@ -123,6 +96,8 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
12396
12497 const routeModalSub$ = this . route . queryParams . subscribe ( param => {
12598 if ( param [ "access" ] === "accessDenied" ) {
99+ this . loadingService . hide ( ) ;
100+
126101 this . showProgramModal . set ( true ) ;
127102 this . showProgramModalErrorMessage . set ( "У вас не доступа к этой вкладке!" ) ;
128103
@@ -150,13 +125,25 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
150125 }
151126 } )
152127 )
153- . subscribe ( news => {
154- if ( news . results ?. length ) {
155- this . news . set ( news . results ) ;
156- this . totalNewsCount . set ( news . count ) ;
157- }
128+ . subscribe ( {
129+ next : news => {
130+ if ( news . results ?. length ) {
131+ this . news . set ( news . results ) ;
132+ this . totalNewsCount . set ( news . count ) ;
133+ }
134+
135+ this . loadingService . hide ( ) ;
136+ } ,
137+ error : ( ) => {
138+ this . loadingService . hide ( ) ;
139+
140+ this . showProgramModal . set ( true ) ;
141+ this . showProgramModalErrorMessage . set ( "Произошла ошибка при загрузке программы" ) ;
142+ } ,
158143 } ) ;
159144
145+ this . loadEvent = fromEvent ( window , "load" ) ;
146+
160147 this . subscriptions$ ( ) . push ( program$ ) ;
161148 this . subscriptions$ ( ) . push ( programIdSubscription$ ) ;
162149 this . subscriptions$ ( ) . push ( routeModalSub$ ) ;
@@ -216,6 +203,7 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
216203
217204 @ViewChild ( NewsFormComponent ) newsFormComponent ?: NewsFormComponent ;
218205 @ViewChild ( "descEl" ) descEl ?: ElementRef ;
206+
219207 onNewsInVew ( entries : IntersectionObserverEntry [ ] ) : void {
220208 const ids = entries . map ( e => {
221209 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -263,20 +251,33 @@ export class ProgramDetailMainComponent implements OnInit, OnDestroy {
263251
264252 closeModal ( ) : void {
265253 this . showProgramModal . set ( false ) ;
254+ this . loadingService . hide ( ) ;
266255 }
267256
268257 addProject ( ) : void {
269- this . projectService . create ( ) . subscribe ( project => {
270- this . projectService . projectsCount . next ( {
271- ...this . projectService . projectsCount . getValue ( ) ,
272- my : this . projectService . projectsCount . getValue ( ) . my + 1 ,
273- } ) ;
274- this . router
275- . navigateByUrl ( `/office/projects/${ project . id } /edit?editingStep=main` )
276- . then ( ( ) => console . debug ( "Route change from ProjectsComponent" ) ) ;
258+ this . loadingService . show ( ) ;
259+
260+ this . projectService . create ( ) . subscribe ( {
261+ next : project => {
262+ this . projectService . projectsCount . next ( {
263+ ...this . projectService . projectsCount . getValue ( ) ,
264+ my : this . projectService . projectsCount . getValue ( ) . my + 1 ,
265+ } ) ;
266+ this . router
267+ . navigateByUrl ( `/office/projects/${ project . id } /edit?editingStep=main` )
268+ . then ( ( ) => {
269+ console . debug ( "Route change from ProjectsComponent" ) ;
270+ } ) ;
271+ } ,
272+ error : error => {
273+ this . loadingService . hide ( ) ;
274+ console . error ( "Project creation error:" , error ) ;
275+ } ,
277276 } ) ;
278277 }
279278
279+ private loadEvent ?: Observable < Event > ;
280+
280281 program ?: Program ;
281282 registerDateExpired ! : boolean ;
282283 descriptionExpandable ! : boolean ;
0 commit comments