diff --git a/src/app/pages/catalog/catalog.component.css b/src/app/pages/catalog/catalog.component.css index 0f74106a..013af3ed 100755 --- a/src/app/pages/catalog/catalog.component.css +++ b/src/app/pages/catalog/catalog.component.css @@ -28,10 +28,11 @@ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25); } + .checkbox-container { + margin: 1em 12em 0 12em; display: flex; - align-items: center; - margin-left: 0.625em; /* Adiciona algum espaço entre o campo de pesquisa e a checkbox */ + justify-content:space-around; } diff --git a/src/app/pages/catalog/catalog.component.html b/src/app/pages/catalog/catalog.component.html index f3f84980..5d3da92f 100755 --- a/src/app/pages/catalog/catalog.component.html +++ b/src/app/pages/catalog/catalog.component.html @@ -1,13 +1,17 @@
- - +
+ + + +
diff --git a/src/app/pages/catalog/catalog.component.ts b/src/app/pages/catalog/catalog.component.ts index af675074..677e5efa 100755 --- a/src/app/pages/catalog/catalog.component.ts +++ b/src/app/pages/catalog/catalog.component.ts @@ -80,16 +80,16 @@ export class CatalogComponent implements OnInit { if (this.isAuthenticated) { this.videoService.getFavoriteVideos(this.userId).subscribe({ next: (data) => { - + // Verifique se `videoList` existe e é um array if (data && Array.isArray(data.videoList)) { const favorite_videos_ids = data.videoList.map((item: any) => String(item.video_id)); // Converta IDs para string - + this.favoriteVideos = this.unbTvVideos.filter(video => favorite_videos_ids.includes(String(video.id))); // Converta IDs para string } else { console.warn('A estrutura da resposta da API não está conforme o esperado:', data); } - + this.filterVideos(); // Atualize a filtragem após carregar os vídeos de "favoritos" }, error: (error) => { @@ -111,16 +111,16 @@ export class CatalogComponent implements OnInit { if (this.isAuthenticated) { this.videoService.getWatchLaterVideos(this.userId).subscribe({ next: (data) => { - + // Verifique se `videoList` existe e é um array if (data && Array.isArray(data.videoList)) { const watchLaterVideoIds = data.videoList.map((item: any) => String(item.video_id)); // Converta IDs para string - + this.watchLaterVideos = this.unbTvVideos.filter(video => watchLaterVideoIds.includes(String(video.id))); // Converta IDs para string } else { console.warn('A estrutura da resposta da API não está conforme o esperado:', data); } - + this.filterVideos(); // Atualize a filtragem após carregar os vídeos de "assistir mais tarde" }, error: (error) => { @@ -137,7 +137,7 @@ export class CatalogComponent implements OnInit { this.filterVideos(); } } - + filterVideosByChannel(videos: IVideo[]): void { videos.forEach((video) => { @@ -156,7 +156,7 @@ export class CatalogComponent implements OnInit { const matchesDescription = this.filterTitle ? video.description?.toLowerCase().includes(this.filterTitle.toLowerCase()) : true; const matchesKeywords = this.filterTitle ? video.keywords?.toLowerCase().includes(this.filterTitle.toLowerCase()) : true; const matchesCatalog = this.filterTitle ? video.catalog?.toLowerCase().includes(this.filterTitle.toLowerCase()) : true; - + return isWatchLater && isFavorite && (matchesTitle || matchesDescription || matchesKeywords || matchesCatalog); }); } diff --git a/src/app/pages/category-table/category-table.component.html b/src/app/pages/category-table/category-table.component.html index 5cda73a6..5d6549b2 100644 --- a/src/app/pages/category-table/category-table.component.html +++ b/src/app/pages/category-table/category-table.component.html @@ -65,4 +65,4 @@

Dados - Categorias

-
\ No newline at end of file +
diff --git a/src/app/pages/category-table/category-table.component.spec.ts b/src/app/pages/category-table/category-table.component.spec.ts index 4b0455ad..74a09d09 100644 --- a/src/app/pages/category-table/category-table.component.spec.ts +++ b/src/app/pages/category-table/category-table.component.spec.ts @@ -72,13 +72,10 @@ describe('CategoryTableComponent', () => { it('should call findAll on ngOnInit', () => { spyOn(component, 'findAll'); component.ngOnInit(); + expect(component.findAll).toHaveBeenCalled(); component.categories.forEach(category => { - if (category === "Todas"){ - expect(component.selectedCategories[category]).toBeTrue() - }else{ - expect(component.selectedCategories[category]).toBeFalse() - } + expect(component.selectedCategories[category]).toBeTrue(); }); }); diff --git a/src/app/pages/category-table/category-table.component.ts b/src/app/pages/category-table/category-table.component.ts index 55750dea..6f1baa09 100644 --- a/src/app/pages/category-table/category-table.component.ts +++ b/src/app/pages/category-table/category-table.component.ts @@ -32,6 +32,7 @@ export class CategoryTableComponent { "Séries Especiais", "UnBTV", "Variedades" + ]; filteredAggregatedVideos: any[] = []; selectedCategories: { [key: string]: boolean } = {}; @@ -44,13 +45,15 @@ export class CategoryTableComponent { private authService: AuthService, private confirmationService: ConfirmationService ) {}; - + ngOnInit(): void{ this.categories.forEach(category => this.selectedCategories[category] = false); - this.selectedCategories["Todas"] = true; + this.categories.forEach(category => { + this.selectedCategories[category] = true; + }); this.findAll(); } - + findAll(): void { this.videoService.findAll().subscribe({ next: (data) => { @@ -107,7 +110,7 @@ export class CategoryTableComponent { this.aggregatedVideos = Array.from(categoryMap.entries()).map(([category, data]) => ({ category, - videoCount: data.count, + videoCount: data.count, totalViews: data.views, viewsPerVideo: data.count > 0 ? data.views/data.count : 0 })); @@ -141,17 +144,28 @@ export class CategoryTableComponent { this.sortAscending = true; } this.sortAggregatedVideos(); - } + } filterCategories(): void { const selectedCategories = Object.keys(this.selectedCategories).filter(category => this.selectedCategories[category]); if (selectedCategories.includes("Todas")) { - this.filteredAggregatedVideos = this.aggregatedVideos; - }else if(selectedCategories.length === 0){ + this.categories.forEach(category => { + this.selectedCategories[category] = true; + }); + this.filteredAggregatedVideos = this.aggregatedVideos; + } else if ( + !selectedCategories.includes("Todas") && + this.selectedCategories["Todas"] === false && + selectedCategories.length === 8 + ) { + this.categories.forEach(category => { + this.selectedCategories[category] = false; + }); + this.filteredAggregatedVideos = []; + } else if(selectedCategories.length === 0){ this.filteredAggregatedVideos = []; - } - else{ - this.filteredAggregatedVideos = this.aggregatedVideos.filter(video => selectedCategories.includes(video.category)); + } else{ + this.filteredAggregatedVideos = this.aggregatedVideos.filter(video => selectedCategories.includes(video.category)); } this.sortAggregatedVideos(); } @@ -182,7 +196,7 @@ export class CategoryTableComponent { ]; ws['!cols'] = columnWidths; - XLSX.utils.book_append_sheet(wb, ws,'Sheet1'); + XLSX.utils.book_append_sheet(wb, ws,'Sheet1'); XLSX.writeFile(wb, this.fileName); } -} \ No newline at end of file +} diff --git a/src/app/pages/dashboard-category/dashboard-category.component.css b/src/app/pages/dashboard-category/dashboard-category.component.css index e0c0c71f..536a9c7a 100644 --- a/src/app/pages/dashboard-category/dashboard-category.component.css +++ b/src/app/pages/dashboard-category/dashboard-category.component.css @@ -9,6 +9,10 @@ font-family: Helvetic, sans-serif; } +.containerCard, .containerLegenda, .containerGraficos { + font-size: 12px; +} + .containerPrincipal { display: flex; min-height: 100vh; diff --git a/src/app/pages/suggest-agenda/suggest-agenda.component.html b/src/app/pages/suggest-agenda/suggest-agenda.component.html index 37eaed7e..4fbf0550 100755 --- a/src/app/pages/suggest-agenda/suggest-agenda.component.html +++ b/src/app/pages/suggest-agenda/suggest-agenda.component.html @@ -62,7 +62,7 @@

Sugestão de Pautas

class="input first button" name="email-contato" formControlName="emailContato" - placeholder="@example.xxx" + placeholder="seuemail@exemplo.com" /> { form.setValue({ descricao: 'Descrição', responsavel: 'Usuário Teste', - telefoneResponsavel: '(99) 99999-9999', + telefoneResponsavel: 999999999, tema: '', quando: '', local: '', @@ -123,4 +123,22 @@ describe('SuggestAgendaComponent', () => { component.sendSuggestAgenda(); expect(alertSpy).toHaveBeenCalledWith('error', 'Erro', 'Serviços válidos: Youtube, Google Drive, Microsoft Stream, Streamable e Vimeo.'); }); + + it('should handle invalid phone number error', () => { + fixture.detectChanges(); + const alertSpy = spyOn(alertService, 'showMessage'); + const form = component.suggestAgendaForm; + form.setValue({ + descricao: 'Descrição', + responsavel: 'Usuário Teste', + telefoneResponsavel: 99999-9999, + tema: '', + quando: '', + local: '', + emailContato: 'test@example.xxx', + urlVideo: 'https://www.youtube.com/watch?v=bX-8WWmW06Q' + }); + component.sendSuggestAgenda(); + expect(alertSpy).toHaveBeenCalledWith('error', 'Erro', 'Telefone inválido.'); + }); }); \ No newline at end of file diff --git a/src/app/pages/suggest-agenda/suggest-agenda.component.ts b/src/app/pages/suggest-agenda/suggest-agenda.component.ts index 1b52a0ec..2d1250b2 100755 --- a/src/app/pages/suggest-agenda/suggest-agenda.component.ts +++ b/src/app/pages/suggest-agenda/suggest-agenda.component.ts @@ -28,13 +28,24 @@ export class SuggestAgendaComponent implements OnInit { quando: [''], local: [''], responsavel: ['', [Validators.required]], - telefoneResponsavel: ['', [Validators.required]], + telefoneResponsavel: ['', [this.validacaoTelefone()]], emailContato: ['', [Validators.pattern('^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$')]], urlVideo: ['', [this.validacaoUrl()]] }, ); } + validacaoTelefone(): ValidatorFn { + return (control: AbstractControl): { [key: string]: any } | null => { + if (control.value == '') { + return null; + } + const padrao_telefone = /^\d{8,15}$/; + const valido = padrao_telefone.test(control.value); + return valido ? null : { telefone_invalido: { value: control.value } }; + } + } + validacaoUrl(): ValidatorFn{ return (control:AbstractControl):{[key: string]:any}| null => { if(control.value == ''){ @@ -71,7 +82,9 @@ export class SuggestAgendaComponent implements OnInit { this.isSendingEmail = false; }); } else { - if(this.suggestAgendaForm.controls['urlVideo'].errors?.['url_invalida']){ + if(this.suggestAgendaForm.controls['telefoneResponsavel'].errors?.['telefone_invalido']){ + this.alertService.showMessage("error", "Erro", "Telefone inválido."); + } else if(this.suggestAgendaForm.controls['urlVideo'].errors?.['url_invalida']){ this.alertService.showMessage("error", "Erro", "Serviços válidos: Youtube, Google Drive, Microsoft Stream, Streamable e Vimeo."); }else{ this.alertService.showMessage("info", "Alerta", "Preencha todos os campos corretamente!"); diff --git a/src/app/pages/video-viewer/video-viewer.component.ts b/src/app/pages/video-viewer/video-viewer.component.ts index c751fbad..6cd3f479 100755 --- a/src/app/pages/video-viewer/video-viewer.component.ts +++ b/src/app/pages/video-viewer/video-viewer.component.ts @@ -69,7 +69,7 @@ export class VideoViewerComponent implements OnInit { this.checkRecord(); this.findAll(); } - + checkRecord(): Promise { return new Promise((resolve, reject) => { this.videoService.checkRecord(this.userId.toString()).subscribe({ @@ -91,15 +91,6 @@ export class VideoViewerComponent implements OnInit { this.filteredVideos = this.unbTvVideos.filter(video => video.id !== undefined && keys.includes(video.id)); } - filterVideosByChannel(videos: IVideo[]): void { - videos.forEach((video) => { - const channel = video?.channels; - if (channel && channel[0].id === this.unbTvChannelId) { - this.unbTvVideos.push(video); - } - }); - } - findAll(): void { this.videoService.findAll().subscribe({ next: (data) => { @@ -118,9 +109,9 @@ export class VideoViewerComponent implements OnInit { this.program = this.videoService.findProgramName(this.catalog, this.categoryVideo, this.idVideo); this.videosByCategory = this.videoService.filterVideosByCategory(this.unbTvVideos, this.categoryVideo); - //console.log("vídeos da categoria do atual: ", this.videosByCategory) + console.log("vídeos da categoria do atual: ", this.videosByCategory) this.filterVideosByRecord(); - //console.log("videos assistidos: ", this.filteredVideos) + console.log("videos assistidos: ", this.filteredVideos) this.idNextVideo = this.videoService.recommendVideo(this.videosByCategory, this.catalog, this.categoryVideo, this.filteredVideos, this.program); //Se o id for diferente de -1, o usuário ainda não viu todos os vídeos da categoria atual if(this.idNextVideo != -1){ @@ -134,8 +125,8 @@ export class VideoViewerComponent implements OnInit { }else{ this.titleNextVideo = "Não há vídeo para ser recomendado" } - //console.log("id do próximo vídeo: ", this.idNextVideo) - //console.log("título do próximo vídeo: ", this.titleNextVideo) + console.log("id do próximo vídeo: ", this.idNextVideo) + console.log("título do próximo vídeo: ", this.titleNextVideo) }, error: (error) => { console.log(error); @@ -143,6 +134,15 @@ export class VideoViewerComponent implements OnInit { }); } + filterVideosByChannel(videos: IVideo[]): void { + videos.forEach((video) => { + const channel = video?.channels; + if (channel && channel[0].id === this.unbTvChannelId) { + this.unbTvVideos.push(video); + } + }); + } + nextVideo(): void { if(this.idNextVideo != -1){ this.router.navigate([`/video/${this.idNextVideo}`]).then(() => { @@ -301,4 +301,4 @@ export class VideoViewerComponent implements OnInit { console.warn('A API de compartilhamento não é suportada neste navegador.'); } } -} +} \ No newline at end of file diff --git a/src/app/pages/video-views/video-views.component.spec.ts b/src/app/pages/video-views/video-views.component.spec.ts index 8da9c716..52345cd3 100755 --- a/src/app/pages/video-views/video-views.component.spec.ts +++ b/src/app/pages/video-views/video-views.component.spec.ts @@ -71,11 +71,7 @@ describe('VideoViewsComponent', () => { expect(component.findAll).toHaveBeenCalled(); expect(component.filteredVideos).toEqual(component.unbTvVideos); component.categories.forEach(category => { - if (category === "Todas"){ - expect(component.selectedCategories[category]).toBeTrue() - }else{ - expect(component.selectedCategories[category]).toBeFalse() - } + expect(component.selectedCategories[category]).toBeTrue() }); }); diff --git a/src/app/pages/video-views/video-views.component.ts b/src/app/pages/video-views/video-views.component.ts index c0d5333e..a3a0c2bc 100755 --- a/src/app/pages/video-views/video-views.component.ts +++ b/src/app/pages/video-views/video-views.component.ts @@ -34,7 +34,7 @@ export class VideoViewsComponent { "UnBTV", "Variedades" ]; - + sortAscending: boolean = true; isSorted: boolean = false; @@ -50,7 +50,9 @@ export class VideoViewsComponent { this.findAll(); this.filteredVideos = this.unbTvVideos; this.categories.forEach(category => this.selectedCategories[category] = false); - this.selectedCategories["Todas"] = true; + this.categories.forEach(category => { + this.selectedCategories[category] = true; + }); } findAll(): void { @@ -68,21 +70,21 @@ export class VideoViewsComponent { this.filterVideos(); }, }); - } + } cleanDescriptions() { const cleanHtml = (html:string) => { const doc = new DOMParser().parseFromString(html, 'text/html'); return doc.body.textContent ?? ""; }; - + this.unbTvVideos.forEach((video) => { if (video.description) { video.description = cleanHtml(video.description); } }); - } - + } + filterVideosByChannel(videos: IVideo[]): void { videos.forEach((video) => { @@ -95,13 +97,24 @@ export class VideoViewsComponent { filterVideos() { const selectedCategories = Object.keys(this.selectedCategories).filter(category => this.selectedCategories[category]); - + if (selectedCategories.includes("Todas")){ + this.categories.forEach(category => { + this.selectedCategories[category] = true; + }); this.filteredVideos = this.unbTvVideos; + }else if( + !selectedCategories.includes("Todas") && + selectedCategories.length === 8 + ){ + this.categories.forEach(category => { + this.selectedCategories[category] = false; + }); + }else if (selectedCategories.length === 0){ this.filteredVideos = []; }else{ - this.filteredVideos = this.unbTvVideos.filter(video => + this.filteredVideos = this.unbTvVideos.filter(video => (this.filterId ? video.id?.toString().includes(this.filterId) : true) && (this.filterTitle ? video.title?.toLowerCase().includes(this.filterTitle.toLowerCase()) : true) && (this.filterDescription ? video.description?.toLowerCase().includes(this.filterDescription.toLowerCase()) : true) && @@ -130,8 +143,8 @@ export class VideoViewsComponent { this.sortAscending = !this.sortAscending; this.sortVideos(); this.isSorted = true; - } - + } + logoutUser() { this.confirmationService.confirm({ message: 'Tem certeza que deseja sair?', @@ -144,7 +157,7 @@ export class VideoViewsComponent { reject: () => {}, }); } - + exportExcel() { let data = document.getElementById("tabela-videos"); const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(data); @@ -159,7 +172,7 @@ export class VideoViewsComponent { ]; ws['!cols'] = columnWidths; - XLSX.utils.book_append_sheet(wb, ws,'Sheet1'); + XLSX.utils.book_append_sheet(wb, ws,'Sheet1'); XLSX.writeFile(wb, this.fileName); } } diff --git a/test-reports/TESTS.xml b/test-reports/TESTS.xml index e69de29b..2df6de95 100644 --- a/test-reports/TESTS.xml +++ b/test-reports/TESTS.xml @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file