From 51e5c0df827038c459f7082fda8c24009e78bc01 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 19 Oct 2021 13:42:58 +1300 Subject: [PATCH 01/39] Squashed commit of the following: commit 2f22e091c547c9e647e9f535b3bb81543b685e3f Author: Luke Date: Thu Oct 14 15:31:14 2021 +1300 fixed single quotes commit 2dc309e3fc24270c6f30a4d21c0fb47ca0c20a4e Author: Luke Date: Thu Oct 14 15:12:24 2021 +1300 removed subhub list from subhub component commit 53b98473b68f6634cc785e8f13c16dfe04d9c78d Author: Luke Date: Thu Oct 14 15:11:23 2021 +1300 removed software list from software component commit fcb5263b6353cb77b3348aad52cbf92c1bb41eff Author: Luke Date: Thu Oct 14 15:09:07 2021 +1300 removed service list from service component commit 9207298e825167c05c2e18e4819d3aff8e4cabfd Author: Luke Date: Thu Oct 14 15:07:22 2021 +1300 removed funding list from funding component commit f5091c09e759d97916cacc18c8387eca08170834 Author: Luke Date: Thu Oct 14 15:04:12 2021 +1300 removed event list from event component commit bd603898e50660672c3365e2c18c58ac8887a723 Author: Luke Date: Thu Oct 14 15:00:24 2021 +1300 removed all equipment query commit feb33a4bf4e42662f5ee52c905e5d8070aaf6b77 Author: Luke Date: Thu Oct 14 14:53:26 2021 +1300 removed equipment list from equipment component commit 9c811a8f114b8cc6111ad45c10e37f4060b863f7 Author: Luke Date: Thu Oct 14 14:49:28 2021 +1300 removed case study list from case study component commit 22c4b6d4c44b55509a510d3ea6c6536816629ebf Author: Luke Date: Thu Oct 14 14:43:57 2021 +1300 removed articles list from article component commit 8c3e32fdc9c229b492b3dcafcc8aac6a17375aca Author: Luke Date: Thu Oct 14 14:19:33 2021 +1300 broke out subhub list commit b0bbef7dd45ba8342c55bea76cb46d6bb094b18b Author: Luke Date: Thu Oct 14 13:46:42 2021 +1300 broke out software list commit 0ce590baae043a2a43ec5f473f7e957bc130250a Author: Luke Date: Thu Oct 14 13:33:38 2021 +1300 broke out service list commit ac7f5cdbba687728c5426ff809c75d9006a8996b Author: Luke Date: Thu Oct 14 13:04:01 2021 +1300 changed import for funding route commit 7b0289b2c31a85da36067c0a3798bec1e61e8708 Author: Luke Date: Thu Oct 14 12:35:12 2021 +1300 broke out funding list commit 877c6744a9d42e9bcd684665d2af656dc910dae7 Author: Luke Date: Thu Oct 14 11:48:14 2021 +1300 broke out event list commit 8f14525e7f4425e6dd410a41b7290ecee1c4bc21 Author: Luke Date: Thu Oct 14 11:28:38 2021 +1300 broke out equipment list commit 4b76f8b423d6c3087e8177c2c1d0eccfc1aaf599 Author: Luke Date: Thu Oct 14 11:17:19 2021 +1300 broke out case study list commit 51d557cea4cdb520608d5839c8a715aa6a5fb9f1 Author: Luke Date: Thu Oct 14 11:06:45 2021 +1300 unsubscribe on destroy commit 85446160d976d5b1f95a81ca1c99ca0a97f96fed Merge: c48690f7 486d2893 Author: Luke Date: Thu Oct 14 10:32:34 2021 +1300 Merge branch 'master' into build-new-content-types-list-page commit c48690f7c630d3a505ca0a2de031489fa60026f9 Author: Luke Date: Thu Oct 14 10:32:12 2021 +1300 broke out article list --- .../article-list/article-list.component.html | 1 + .../article-list/article-list.component.scss | 0 .../article-list.component.spec.ts | 25 ++++ .../article-list/article-list.component.ts | 30 +++++ .../article.component.html} | 8 -- .../article.component.scss} | 0 .../article.component.spec.ts} | 9 +- .../article.component.ts} | 89 ++++++------- .../articles/articles-routing.module.ts | 6 +- .../components/articles/articles.module.ts | 6 +- .../case-study-list.component.html | 1 + .../case-study-list.component.scss | 0 .../case-study-list.component.spec.ts | 25 ++++ .../case-study-list.component.ts | 30 +++++ .../casestudys/case-study-routing.module.ts | 6 +- .../case-study.component.html | 8 -- .../case-study.component.scss | 0 .../case-study.component.spec.ts | 0 .../{ => case-study}/case-study.component.ts | 73 ++++------- .../casestudys/casestudys.module.ts | 6 +- .../equipment-list.component.html | 1 + .../equipment-list.component.scss | 0 .../equipment-list.component.spec.ts | 25 ++++ .../equipment-list.component.ts | 30 +++++ .../equipments/equipment-routing.module.ts | 6 +- .../{ => equipment}/equipment.component.html | 8 -- .../{ => equipment}/equipment.component.scss | 0 .../equipment.component.spec.ts | 0 .../{ => equipment}/equipment.component.ts | 77 +++++------- .../equipments/equipments.module.ts | 5 +- .../event-list/event-list.component.html | 1 + .../event-list/event-list.component.scss | 0 .../event-list/event-list.component.spec.ts | 25 ++++ .../events/event-list/event-list.component.ts | 29 +++++ ...g.module.ts.ts => event-routing.module.ts} | 6 +- .../event.component.html} | 8 -- .../event.component.scss} | 0 .../event.component.spec.ts} | 12 +- .../event.component.ts} | 29 +---- .../app/components/events/events.module.ts | 7 +- .../funding-list/funding-list.component.html | 1 + .../funding-list/funding-list.component.scss | 0 .../funding-list.component.spec.ts | 25 ++++ .../funding-list/funding-list.component.ts | 30 +++++ .../fundings/funding-routing.module.ts | 6 +- .../funding.component.html} | 8 -- .../funding.component.scss} | 0 .../funding.component.spec.ts} | 12 +- .../funding.component.ts} | 29 +---- .../components/fundings/fundings.module.ts | 10 +- .../service-list/service-list.component.html | 1 + .../service-list/service-list.component.scss | 0 .../service-list.component.spec.ts | 25 ++++ .../service-list/service-list.component.ts | 30 +++++ .../service.component.html} | 8 -- .../service.component.scss} | 0 .../service.component.spec.ts} | 12 +- .../service.component.ts} | 29 +---- .../services/services-routing.module.ts | 6 +- .../components/services/services.module.ts | 5 +- .../collection-list.component.html | 117 ++++++++++++------ .../software-list.component.html | 1 + .../software-list.component.scss | 0 .../software-list.component.spec.ts | 25 ++++ .../software-list/software-list.component.ts | 30 +++++ .../softwares/software-routing.module.ts | 6 +- .../software.component.html} | 8 -- .../software.component.scss} | 0 .../software.component.spec.ts} | 12 +- .../software.component.ts} | 87 +++++-------- .../components/softwares/softwares.module.ts | 5 +- .../subhub-list/subhub-list.component.html | 1 + .../subhub-list/subhub-list.component.scss | 0 .../subhub-list/subhub-list.component.spec.ts | 25 ++++ .../subhub-list/subhub-list.component.ts | 29 +++++ .../subhub.component.html} | 10 +- .../subhub.component.scss} | 0 .../subhub.component.spec.ts} | 20 ++- .../subhub.component.ts} | 29 +---- .../subhubs/subhubs-routing.module.ts | 6 +- .../app/components/subhubs/subhubs.module.ts | 7 +- research-hub-web/src/app/routing/routing.ts | 60 +++------ 82 files changed, 773 insertions(+), 534 deletions(-) create mode 100644 research-hub-web/src/app/components/articles/article-list/article-list.component.html create mode 100644 research-hub-web/src/app/components/articles/article-list/article-list.component.scss create mode 100644 research-hub-web/src/app/components/articles/article-list/article-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/articles/article-list/article-list.component.ts rename research-hub-web/src/app/components/articles/{articles.component.html => article/article.component.html} (94%) rename research-hub-web/src/app/components/articles/{articles.component.scss => article/article.component.scss} (100%) rename research-hub-web/src/app/components/articles/{articles.component.spec.ts => article/article.component.spec.ts} (96%) rename research-hub-web/src/app/components/articles/{articles.component.ts => article/article.component.ts} (63%) create mode 100644 research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.html create mode 100644 research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.scss create mode 100644 research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.ts rename research-hub-web/src/app/components/casestudys/{ => case-study}/case-study.component.html (93%) rename research-hub-web/src/app/components/casestudys/{ => case-study}/case-study.component.scss (100%) rename research-hub-web/src/app/components/casestudys/{ => case-study}/case-study.component.spec.ts (100%) rename research-hub-web/src/app/components/casestudys/{ => case-study}/case-study.component.ts (68%) create mode 100644 research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.html create mode 100644 research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.scss create mode 100644 research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.ts rename research-hub-web/src/app/components/equipments/{ => equipment}/equipment.component.html (96%) rename research-hub-web/src/app/components/equipments/{ => equipment}/equipment.component.scss (100%) rename research-hub-web/src/app/components/equipments/{ => equipment}/equipment.component.spec.ts (100%) rename research-hub-web/src/app/components/equipments/{ => equipment}/equipment.component.ts (64%) create mode 100644 research-hub-web/src/app/components/events/event-list/event-list.component.html create mode 100644 research-hub-web/src/app/components/events/event-list/event-list.component.scss create mode 100644 research-hub-web/src/app/components/events/event-list/event-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/events/event-list/event-list.component.ts rename research-hub-web/src/app/components/events/{event-routing.module.ts.ts => event-routing.module.ts} (52%) rename research-hub-web/src/app/components/events/{events.component.html => event/event.component.html} (95%) rename research-hub-web/src/app/components/events/{events.component.scss => event/event.component.scss} (100%) rename research-hub-web/src/app/components/events/{events.component.spec.ts => event/event.component.spec.ts} (91%) rename research-hub-web/src/app/components/events/{events.component.ts => event/event.component.ts} (84%) create mode 100644 research-hub-web/src/app/components/fundings/funding-list/funding-list.component.html create mode 100644 research-hub-web/src/app/components/fundings/funding-list/funding-list.component.scss create mode 100644 research-hub-web/src/app/components/fundings/funding-list/funding-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/fundings/funding-list/funding-list.component.ts rename research-hub-web/src/app/components/fundings/{fundings.component.html => funding/funding.component.html} (96%) rename research-hub-web/src/app/components/fundings/{fundings.component.scss => funding/funding.component.scss} (100%) rename research-hub-web/src/app/components/fundings/{fundings.component.spec.ts => funding/funding.component.spec.ts} (91%) rename research-hub-web/src/app/components/fundings/{fundings.component.ts => funding/funding.component.ts} (84%) create mode 100644 research-hub-web/src/app/components/services/service-list/service-list.component.html create mode 100644 research-hub-web/src/app/components/services/service-list/service-list.component.scss create mode 100644 research-hub-web/src/app/components/services/service-list/service-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/services/service-list/service-list.component.ts rename research-hub-web/src/app/components/services/{services.component.html => service/service.component.html} (94%) rename research-hub-web/src/app/components/services/{services.component.scss => service/service.component.scss} (100%) rename research-hub-web/src/app/components/services/{services.component.spec.ts => service/service.component.spec.ts} (91%) rename research-hub-web/src/app/components/services/{services.component.ts => service/service.component.ts} (84%) create mode 100644 research-hub-web/src/app/components/softwares/software-list/software-list.component.html create mode 100644 research-hub-web/src/app/components/softwares/software-list/software-list.component.scss create mode 100644 research-hub-web/src/app/components/softwares/software-list/software-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/softwares/software-list/software-list.component.ts rename research-hub-web/src/app/components/softwares/{softwares.component.html => software/software.component.html} (95%) rename research-hub-web/src/app/components/softwares/{softwares.component.scss => software/software.component.scss} (100%) rename research-hub-web/src/app/components/softwares/{softwares.component.spec.ts => software/software.component.spec.ts} (91%) rename research-hub-web/src/app/components/softwares/{softwares.component.ts => software/software.component.ts} (59%) create mode 100644 research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.html create mode 100644 research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.scss create mode 100644 research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.spec.ts create mode 100644 research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.ts rename research-hub-web/src/app/components/subhubs/{subhubs.component.html => subhub/subhub.component.html} (93%) rename research-hub-web/src/app/components/subhubs/{subhubs.component.scss => subhub/subhub.component.scss} (100%) rename research-hub-web/src/app/components/subhubs/{subhubs.component.spec.ts => subhub/subhub.component.spec.ts} (96%) rename research-hub-web/src/app/components/subhubs/{subhubs.component.ts => subhub/subhub.component.ts} (81%) diff --git a/research-hub-web/src/app/components/articles/article-list/article-list.component.html b/research-hub-web/src/app/components/articles/article-list/article-list.component.html new file mode 100644 index 000000000..a1470c85a --- /dev/null +++ b/research-hub-web/src/app/components/articles/article-list/article-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/articles/article-list/article-list.component.scss b/research-hub-web/src/app/components/articles/article-list/article-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/articles/article-list/article-list.component.spec.ts b/research-hub-web/src/app/components/articles/article-list/article-list.component.spec.ts new file mode 100644 index 000000000..921ecab9d --- /dev/null +++ b/research-hub-web/src/app/components/articles/article-list/article-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ArticleListComponent } from './article-list.component'; + +describe('ArticleListComponent', () => { + let component: ArticleListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ArticleListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ArticleListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/articles/article-list/article-list.component.ts b/research-hub-web/src/app/components/articles/article-list/article-list.component.ts new file mode 100644 index 000000000..3da5152b7 --- /dev/null +++ b/research-hub-web/src/app/components/articles/article-list/article-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllArticlesGQL, ArticleCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-article-list', + templateUrl: './article-list.component.html', + styleUrls: ['./article-list.component.scss'] +}) +export class ArticleListComponent implements OnInit, OnDestroy { + public articles: ArticleCollection + + private subscription = new Subscription(); + + constructor( + private allArticlesGQL: AllArticlesGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allArticlesGQL.fetch().pipe( + map((result) => result.data.articleCollection as ArticleCollection) + ).subscribe(collection => this.articles = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/articles/articles.component.html b/research-hub-web/src/app/components/articles/article/article.component.html similarity index 94% rename from research-hub-web/src/app/components/articles/articles.component.html rename to research-hub-web/src/app/components/articles/article/article.component.html index 3343b3d08..4df2769ed 100644 --- a/research-hub-web/src/app/components/articles/articles.component.html +++ b/research-hub-web/src/app/components/articles/article/article.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/articles/articles.component.scss b/research-hub-web/src/app/components/articles/article/article.component.scss similarity index 100% rename from research-hub-web/src/app/components/articles/articles.component.scss rename to research-hub-web/src/app/components/articles/article/article.component.scss diff --git a/research-hub-web/src/app/components/articles/articles.component.spec.ts b/research-hub-web/src/app/components/articles/article/article.component.spec.ts similarity index 96% rename from research-hub-web/src/app/components/articles/articles.component.spec.ts rename to research-hub-web/src/app/components/articles/article/article.component.spec.ts index 19888a91a..2a0ce76fa 100644 --- a/research-hub-web/src/app/components/articles/articles.component.spec.ts +++ b/research-hub-web/src/app/components/articles/article/article.component.spec.ts @@ -1,11 +1,10 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; -import { PageTitleService } from '../../services/page-title.service'; -import { ArticlesComponent } from './articles.component'; +import { PageTitleService } from '@services/page-title.service'; +import { ArticlesComponent } from './article.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; -import { RouterModule, ActivatedRoute, convertToParamMap, Router } from '@angular/router'; -import { By } from '@angular/platform-browser'; +import { ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; -import { ArticleCollection, AllArticlesGQL, Article } from '@graphql/schema'; +import { ArticleCollection, Article } from '@graphql/schema'; import { CommonModule } from '@angular/common'; import { MaterialModule } from '@app/app.material.module'; import { SharedModule } from '@components/shared/app.shared.module'; diff --git a/research-hub-web/src/app/components/articles/articles.component.ts b/research-hub-web/src/app/components/articles/article/article.component.ts similarity index 63% rename from research-hub-web/src/app/components/articles/articles.component.ts rename to research-hub-web/src/app/components/articles/article/article.component.ts index 34a094912..749099ac7 100644 --- a/research-hub-web/src/app/components/articles/articles.component.ts +++ b/research-hub-web/src/app/components/articles/article/article.component.ts @@ -20,8 +20,8 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-articles', - templateUrl: './articles.component.html', - styleUrls: ['./articles.component.scss'] + templateUrl: './article.component.html', + styleUrls: ['./article.component.scss'] }) export class ArticlesComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { @@ -94,59 +94,40 @@ export class ArticlesComponent implements OnInit, OnDestroy { * If this.slug is defined, we're loading an individual article, * therefore run the corresponding query. If not, return all articles. */ - if (!!this.slug) { - // Check if the article slug is valid otherwise redirect to 404 - this.getAllArticlesSlugs().subscribe(data => { - let slugs = []; - data.items.forEach(data => { - slugs.push(data.slug) - }) - if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } - }); - this.article = this.getArticleBySlug(this.slug); - this.article$ = this.getArticleBySlug(this.slug).subscribe(data => { - - // Strip nulls from related collection data. - data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); - data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); - data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); - data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); - - // If Call To Action is an email address - if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { - data['callToAction'] = 'mailto:' + data['callToAction']; - } - - // Set banner image URL for webp format if webp is supported - if (data.banner?.url) { - this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; - } else { - this.bannerImageUrl = undefined; - } - - this.bodyMediaService.setBodyMedia(data.bodyText?.links); - this.pageTitleService.title = data.title; - }); - this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Articles'; - this.allArticles$ = this.getAllArticles(); - try { this.article$.unsubscribe(); } catch { } - } - } - /** - * Function that returns all articles from the ArticleCollection as an observable - * of type ArticleCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting article/slug-name. - */ - public getAllArticles(): Observable { - try { - return this.allArticlesGQL.fetch() - .pipe(pluck('data', 'articleCollection')) as Observable - } catch (e) { console.error('Error loading all articles:', e) }; + this.getAllArticlesSlugs().subscribe(data => { + let slugs = []; + data.items.forEach(data => { + slugs.push(data.slug) + }) + if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } + }); + this.article = this.getArticleBySlug(this.slug); + this.article$ = this.getArticleBySlug(this.slug).subscribe(data => { + + // Strip nulls from related collection data. + data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); + data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); + data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); + data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); + + // If Call To Action is an email address + if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { + data['callToAction'] = 'mailto:' + data['callToAction']; + } + + // Set banner image URL for webp format if webp is supported + if (data.banner?.url) { + this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; + } else { + this.bannerImageUrl = undefined; + } + + this.bodyMediaService.setBodyMedia(data.bodyText?.links); + this.pageTitleService.title = data.title; + }); + this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); + } /** diff --git a/research-hub-web/src/app/components/articles/articles-routing.module.ts b/research-hub-web/src/app/components/articles/articles-routing.module.ts index b789e424f..e882beb51 100644 --- a/research-hub-web/src/app/components/articles/articles-routing.module.ts +++ b/research-hub-web/src/app/components/articles/articles-routing.module.ts @@ -1,9 +1,11 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { ArticlesComponent } from './articles.component'; +import { ArticleListComponent } from './article-list/article-list.component'; +import { ArticlesComponent } from './article/article.component'; const routes: Routes = [ - { path: '', component: ArticlesComponent } + { path: '', component: ArticleListComponent }, + { path: ':slug', component: ArticlesComponent } ]; @NgModule({ diff --git a/research-hub-web/src/app/components/articles/articles.module.ts b/research-hub-web/src/app/components/articles/articles.module.ts index 07b8d5d10..c69b8c7c8 100644 --- a/research-hub-web/src/app/components/articles/articles.module.ts +++ b/research-hub-web/src/app/components/articles/articles.module.ts @@ -1,14 +1,16 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ArticlesRoutingModule } from './articles-routing.module'; -import { ArticlesComponent } from './articles.component'; +import { ArticlesComponent } from './article/article.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { ArticleListComponent } from './article-list/article-list.component'; @NgModule({ declarations: [ - ArticlesComponent + ArticlesComponent, + ArticleListComponent ], imports: [ CommonModule, diff --git a/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.html b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.html new file mode 100644 index 000000000..be079019d --- /dev/null +++ b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.scss b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.spec.ts b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.spec.ts new file mode 100644 index 000000000..accdd56e1 --- /dev/null +++ b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CaseStudyListComponent } from './case-study-list.component'; + +describe('CaseStudyListComponent', () => { + let component: CaseStudyListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CaseStudyListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CaseStudyListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.ts b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.ts new file mode 100644 index 000000000..ab7ccdd9f --- /dev/null +++ b/research-hub-web/src/app/components/casestudys/case-study-list/case-study-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllCaseStudiesGQL, CaseStudyCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-case-study-list', + templateUrl: './case-study-list.component.html', + styleUrls: ['./case-study-list.component.scss'] +}) +export class CaseStudyListComponent implements OnInit, OnDestroy { + public caseStudies: CaseStudyCollection + + private subscription = new Subscription(); + + constructor( + private allCaseStudiesGQL: AllCaseStudiesGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allCaseStudiesGQL.fetch().pipe( + map((result) => result.data.caseStudyCollection as CaseStudyCollection) + ).subscribe((collection) => this.caseStudies = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/casestudys/case-study-routing.module.ts b/research-hub-web/src/app/components/casestudys/case-study-routing.module.ts index a73013382..f6af59d49 100644 --- a/research-hub-web/src/app/components/casestudys/case-study-routing.module.ts +++ b/research-hub-web/src/app/components/casestudys/case-study-routing.module.ts @@ -1,9 +1,11 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { CaseStudyComponent } from './case-study.component'; +import { CaseStudyListComponent } from './case-study-list/case-study-list.component'; +import { CaseStudyComponent } from './case-study/case-study.component'; const routes: Routes = [ - { path: '', component: CaseStudyComponent } + { path: '', component: CaseStudyListComponent }, + { path: ':slug', component: CaseStudyComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/casestudys/case-study.component.html b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html similarity index 93% rename from research-hub-web/src/app/components/casestudys/case-study.component.html rename to research-hub-web/src/app/components/casestudys/case-study/case-study.component.html index 186162681..94d4d4b77 100644 --- a/research-hub-web/src/app/components/casestudys/case-study.component.html +++ b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/casestudys/case-study.component.scss b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.scss similarity index 100% rename from research-hub-web/src/app/components/casestudys/case-study.component.scss rename to research-hub-web/src/app/components/casestudys/case-study/case-study.component.scss diff --git a/research-hub-web/src/app/components/casestudys/case-study.component.spec.ts b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.spec.ts similarity index 100% rename from research-hub-web/src/app/components/casestudys/case-study.component.spec.ts rename to research-hub-web/src/app/components/casestudys/case-study/case-study.component.spec.ts diff --git a/research-hub-web/src/app/components/casestudys/case-study.component.ts b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.ts similarity index 68% rename from research-hub-web/src/app/components/casestudys/case-study.component.ts rename to research-hub-web/src/app/components/casestudys/case-study/case-study.component.ts index a58417788..a2f0300c5 100644 --- a/research-hub-web/src/app/components/casestudys/case-study.component.ts +++ b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.ts @@ -94,56 +94,37 @@ export class CaseStudyComponent implements OnInit, OnDestroy { * If this.slug is defined, we're loading an individual CaseStudy, * therefore run the corresponding query. If not, return all CaseStudy. */ - if (!!this.slug) { - this.getAllCaseStudySlugs().subscribe(data => { - let slugs = []; - data.items.forEach(data => { - slugs.push(data.slug) - }) - if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } - }); - this.caseStudy = this.getCaseStudyBySlug(this.slug); + this.getAllCaseStudySlugs().subscribe(data => { + let slugs = []; + data.items.forEach(data => { + slugs.push(data.slug) + }) + if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } + }); + this.caseStudy = this.getCaseStudyBySlug(this.slug); - /** - * If the page is SSO Protected then check if the user is authenticated - */ - this.caseStudy$ = this.getCaseStudyBySlug(this.slug).subscribe(data => { - // Strip nulls from related collection data. - data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); - data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); - data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); - data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); + /** + * If the page is SSO Protected then check if the user is authenticated + */ + this.caseStudy$ = this.getCaseStudyBySlug(this.slug).subscribe(data => { + // Strip nulls from related collection data. + data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); + data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); + data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); + data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); - // Set banner image URL for webp format if webp is supported - if (data.banner?.url) { - this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; - } else { - this.bannerImageUrl = undefined; - } + // Set banner image URL for webp format if webp is supported + if (data.banner?.url) { + this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; + } else { + this.bannerImageUrl = undefined; + } - this.bodyMediaService.setBodyMedia(data.bodyText.links); - this.pageTitleService.title = data.title; - }); - this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Case Studies'; - this.allCaseStudies$ = this.getAllCaseStudy(); - try { this.caseStudy$.unsubscribe(); } catch { } - } - } + this.bodyMediaService.setBodyMedia(data.bodyText.links); + this.pageTitleService.title = data.title; + }); + this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - /** - * Function that returns all CaseStudy from the CaseStudyCollection as an observable - * of type CaseStudyCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting CaseStudy/slug-name. - */ - public getAllCaseStudy(): Observable { - try { - return this.allCaseStudyGQL.fetch() - .pipe(pluck('data', 'caseStudyCollection')) as Observable - } catch (e) { console.error('Error loading all CaseStudy:', e) }; } /** diff --git a/research-hub-web/src/app/components/casestudys/casestudys.module.ts b/research-hub-web/src/app/components/casestudys/casestudys.module.ts index c8ce8aac6..7495170d7 100644 --- a/research-hub-web/src/app/components/casestudys/casestudys.module.ts +++ b/research-hub-web/src/app/components/casestudys/casestudys.module.ts @@ -1,16 +1,18 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { CaseStudyRoutingModule } from './case-study-routing.module'; -import { CaseStudyComponent } from './case-study.component'; +import { CaseStudyComponent } from './case-study/case-study.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; import { CaseStudyReferencesComponent } from './case-study-references/case-study-references.component'; +import { CaseStudyListComponent } from './case-study-list/case-study-list.component'; @NgModule({ declarations: [ CaseStudyComponent, - CaseStudyReferencesComponent + CaseStudyReferencesComponent, + CaseStudyListComponent ], imports: [ CommonModule, diff --git a/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.html b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.html new file mode 100644 index 000000000..48fdf777c --- /dev/null +++ b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.scss b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.spec.ts b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.spec.ts new file mode 100644 index 000000000..9381cce60 --- /dev/null +++ b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EquipmentListComponent } from './equipment-list.component'; + +describe('EquipmentListComponent', () => { + let component: EquipmentListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EquipmentListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EquipmentListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.ts b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.ts new file mode 100644 index 000000000..52b3d6c84 --- /dev/null +++ b/research-hub-web/src/app/components/equipments/equipment-list/equipment-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllEquipmentGQL, EquipmentCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-equipment-list', + templateUrl: './equipment-list.component.html', + styleUrls: ['./equipment-list.component.scss'] +}) +export class EquipmentListComponent implements OnInit, OnDestroy { + public equipment: EquipmentCollection; + + private subscription = new Subscription(); + + constructor( + private allEquipmentGQL: AllEquipmentGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allEquipmentGQL.fetch().pipe( + map((result) => result.data.equipmentCollection as EquipmentCollection) + ).subscribe((collection) => this.equipment = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/equipments/equipment-routing.module.ts b/research-hub-web/src/app/components/equipments/equipment-routing.module.ts index b1ed95f86..5c1452610 100644 --- a/research-hub-web/src/app/components/equipments/equipment-routing.module.ts +++ b/research-hub-web/src/app/components/equipments/equipment-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { EquipmentComponent } from './equipment.component'; +import { EquipmentListComponent } from './equipment-list/equipment-list.component'; +import { EquipmentComponent } from './equipment/equipment.component'; const routes: Routes = [ - { path: '', component: EquipmentComponent } + { path: '', component: EquipmentListComponent }, + { path: ':slug', component: EquipmentComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/equipments/equipment.component.html b/research-hub-web/src/app/components/equipments/equipment/equipment.component.html similarity index 96% rename from research-hub-web/src/app/components/equipments/equipment.component.html rename to research-hub-web/src/app/components/equipments/equipment/equipment.component.html index 2230b1df8..9247b8074 100644 --- a/research-hub-web/src/app/components/equipments/equipment.component.html +++ b/research-hub-web/src/app/components/equipments/equipment/equipment.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/equipments/equipment.component.scss b/research-hub-web/src/app/components/equipments/equipment/equipment.component.scss similarity index 100% rename from research-hub-web/src/app/components/equipments/equipment.component.scss rename to research-hub-web/src/app/components/equipments/equipment/equipment.component.scss diff --git a/research-hub-web/src/app/components/equipments/equipment.component.spec.ts b/research-hub-web/src/app/components/equipments/equipment/equipment.component.spec.ts similarity index 100% rename from research-hub-web/src/app/components/equipments/equipment.component.spec.ts rename to research-hub-web/src/app/components/equipments/equipment/equipment.component.spec.ts diff --git a/research-hub-web/src/app/components/equipments/equipment.component.ts b/research-hub-web/src/app/components/equipments/equipment/equipment.component.ts similarity index 64% rename from research-hub-web/src/app/components/equipments/equipment.component.ts rename to research-hub-web/src/app/components/equipments/equipment/equipment.component.ts index cdb9cd775..004ab85d9 100644 --- a/research-hub-web/src/app/components/equipments/equipment.component.ts +++ b/research-hub-web/src/app/components/equipments/equipment/equipment.component.ts @@ -91,58 +91,39 @@ export class EquipmentComponent implements OnInit, OnDestroy { * If this.slug is defined, we're loading an individual Equipment, * therefore run the corresponding query. If not, return all Equipment. */ - if (!!this.slug) { - // Check if the equipment slug is valid otherwise redirect to 404 - this.getAllEquipmentSlugs().subscribe(data => { - let slugs = []; - data.items.forEach(data => { - slugs.push(data.slug) - }) - if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } - }); - this.equipment = this.getEquipmentBySlug(this.slug); - this.equipment$ = this.getEquipmentBySlug(this.slug).subscribe(data => { - // Strip nulls from related collection data. - data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); - data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); - data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); - data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); + // Check if the equipment slug is valid otherwise redirect to 404 + this.getAllEquipmentSlugs().subscribe(data => { + let slugs = []; + data.items.forEach(data => { + slugs.push(data.slug) + }) + if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } + }); + this.equipment = this.getEquipmentBySlug(this.slug); + this.equipment$ = this.getEquipmentBySlug(this.slug).subscribe(data => { + // Strip nulls from related collection data. + data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); + data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); + data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); + data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); - // If Call To Action is an email address - if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { - data['callToAction'] = 'mailto:' + data['callToAction']; - } + // If Call To Action is an email address + if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { + data['callToAction'] = 'mailto:' + data['callToAction']; + } - // Set banner image URL for webp format if webp is supported - if (data.banner?.url) { - this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; - } else { - this.bannerImageUrl = undefined; - } + // Set banner image URL for webp format if webp is supported + if (data.banner?.url) { + this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; + } else { + this.bannerImageUrl = undefined; + } - this.bodyMediaService.setBodyMedia(data.bodyText?.links); - this.pageTitleService.title = data.title; - }); - this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Equipment'; - this.allEquipment$ = this.getAllEquipment(); - try { this.equipment$.unsubscribe(); } catch { } - } - } + this.bodyMediaService.setBodyMedia(data.bodyText?.links); + this.pageTitleService.title = data.title; + }); + this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - /** - * Function that returns all Equipment from the EquipmentCollection as an observable - * of type EquipmentCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting Equipment/slug-name. - */ - public getAllEquipment(): Observable { - try { - return this.allEquipmentGQL.fetch() - .pipe(pluck('data', 'equipmentCollection')) as Observable - } catch (e) { console.error('Error loading all Equipment:', e) }; } /** diff --git a/research-hub-web/src/app/components/equipments/equipments.module.ts b/research-hub-web/src/app/components/equipments/equipments.module.ts index 213b58fcb..a8cef376c 100644 --- a/research-hub-web/src/app/components/equipments/equipments.module.ts +++ b/research-hub-web/src/app/components/equipments/equipments.module.ts @@ -2,12 +2,13 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { EquipmentRoutingModule } from './equipment-routing.module'; -import { EquipmentComponent } from './equipment.component'; +import { EquipmentComponent } from './equipment/equipment.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { EquipmentListComponent } from './equipment-list/equipment-list.component'; @NgModule({ - declarations: [EquipmentComponent], + declarations: [EquipmentComponent, EquipmentListComponent], imports: [ CommonModule, EquipmentRoutingModule, diff --git a/research-hub-web/src/app/components/events/event-list/event-list.component.html b/research-hub-web/src/app/components/events/event-list/event-list.component.html new file mode 100644 index 000000000..7e18b9006 --- /dev/null +++ b/research-hub-web/src/app/components/events/event-list/event-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/events/event-list/event-list.component.scss b/research-hub-web/src/app/components/events/event-list/event-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/events/event-list/event-list.component.spec.ts b/research-hub-web/src/app/components/events/event-list/event-list.component.spec.ts new file mode 100644 index 000000000..d0e8eb551 --- /dev/null +++ b/research-hub-web/src/app/components/events/event-list/event-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventListComponent } from './event-list.component'; + +describe('EventListComponent', () => { + let component: EventListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EventListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EventListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/events/event-list/event-list.component.ts b/research-hub-web/src/app/components/events/event-list/event-list.component.ts new file mode 100644 index 000000000..0e7273b92 --- /dev/null +++ b/research-hub-web/src/app/components/events/event-list/event-list.component.ts @@ -0,0 +1,29 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllEventsGQL, EventCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-event-list', + templateUrl: './event-list.component.html', + styleUrls: ['./event-list.component.scss'] +}) +export class EventListComponent implements OnInit, OnDestroy { + public events: EventCollection; + + private subscription = new Subscription(); + + constructor( + private allEventsGQL: AllEventsGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allEventsGQL.fetch().pipe( + map((result) => result.data.eventCollection as EventCollection) + ).subscribe((collection) => this.events = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } +} diff --git a/research-hub-web/src/app/components/events/event-routing.module.ts.ts b/research-hub-web/src/app/components/events/event-routing.module.ts similarity index 52% rename from research-hub-web/src/app/components/events/event-routing.module.ts.ts rename to research-hub-web/src/app/components/events/event-routing.module.ts index 5c28e9e77..2af2dd766 100644 --- a/research-hub-web/src/app/components/events/event-routing.module.ts.ts +++ b/research-hub-web/src/app/components/events/event-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { EventsComponent } from './events.component'; +import { EventListComponent } from './event-list/event-list.component'; +import { EventComponent } from './event/event.component'; const routes: Routes = [ - { path: '', component: EventsComponent } + { path: '', component: EventListComponent }, + { path: ':slug', component: EventComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/events/events.component.html b/research-hub-web/src/app/components/events/event/event.component.html similarity index 95% rename from research-hub-web/src/app/components/events/events.component.html rename to research-hub-web/src/app/components/events/event/event.component.html index 0de0dfc02..6a8e57c06 100644 --- a/research-hub-web/src/app/components/events/events.component.html +++ b/research-hub-web/src/app/components/events/event/event.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/events/events.component.scss b/research-hub-web/src/app/components/events/event/event.component.scss similarity index 100% rename from research-hub-web/src/app/components/events/events.component.scss rename to research-hub-web/src/app/components/events/event/event.component.scss diff --git a/research-hub-web/src/app/components/events/events.component.spec.ts b/research-hub-web/src/app/components/events/event/event.component.spec.ts similarity index 91% rename from research-hub-web/src/app/components/events/events.component.spec.ts rename to research-hub-web/src/app/components/events/event/event.component.spec.ts index f1d338bc8..2e467a1d3 100644 --- a/research-hub-web/src/app/components/events/events.component.spec.ts +++ b/research-hub-web/src/app/components/events/event/event.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { PageTitleService } from '@services/page-title.service'; -import { EventsComponent } from './events.component'; +import { EventComponent } from './event.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; import { ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -13,8 +13,8 @@ import { RouterTestingModule } from '@angular/router/testing'; import { MockModule, MockProvider } from 'ng-mocks'; describe('EventsComponent', () => { - let component: EventsComponent; - let fixture: ComponentFixture; + let component: EventComponent; + let fixture: ComponentFixture; let controller: ApolloTestingController; const mockAllEvent$: Observable = of({ @@ -47,7 +47,7 @@ describe('EventsComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - EventsComponent + EventComponent ], imports: [ RouterTestingModule, @@ -65,7 +65,7 @@ describe('EventsComponent', () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(EventsComponent); + fixture = TestBed.createComponent(EventComponent); component = fixture.componentInstance; fixture.detectChanges(); }); @@ -88,7 +88,7 @@ describe('EventsComponent', () => { describe('When a url slug is present', async () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(EventsComponent); + fixture = TestBed.createComponent(EventComponent); component = fixture.componentInstance; TestBed.inject(ActivatedRoute).params = of({ slug: 'death-star' diff --git a/research-hub-web/src/app/components/events/events.component.ts b/research-hub-web/src/app/components/events/event/event.component.ts similarity index 84% rename from research-hub-web/src/app/components/events/events.component.ts rename to research-hub-web/src/app/components/events/event/event.component.ts index f0112ced7..eda632a64 100644 --- a/research-hub-web/src/app/components/events/events.component.ts +++ b/research-hub-web/src/app/components/events/event/event.component.ts @@ -20,10 +20,10 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-events', - templateUrl: './events.component.html', - styleUrls: ['./events.component.scss'] + templateUrl: './event.component.html', + styleUrls: ['./event.component.scss'] }) -export class EventsComponent implements OnInit, OnDestroy { +export class EventComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -85,11 +85,6 @@ export class EventsComponent implements OnInit, OnDestroy { * Function that loads the Event/collection depending on if a slug is present. */ private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual Event, - * therefore run the corresponding query. If not, return all Events. - */ - if (!!this.slug) { // Check if the article slug is valid otherwise redirect to 404 this.getAllEventSlugs().subscribe(data => { let slugs = []; @@ -123,25 +118,7 @@ export class EventsComponent implements OnInit, OnDestroy { this.pageTitleService.title = data.title; }); this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Events'; - this.allEvents$ = this.getAllEvents(); - try { this.event$.unsubscribe(); } catch { } - } - } - /** - * Function that returns all Events from the EventCollection as an observable - * of type EventCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting Event/slug-name. - */ - public getAllEvents(): Observable { - try { - return this.allEventsGQL.fetch() - .pipe(pluck('data', 'eventCollection')) as Observable - } catch (e) { console.error('Error loading all Events:', e) }; } /** diff --git a/research-hub-web/src/app/components/events/events.module.ts b/research-hub-web/src/app/components/events/events.module.ts index 59b1d3c4a..17a365b33 100644 --- a/research-hub-web/src/app/components/events/events.module.ts +++ b/research-hub-web/src/app/components/events/events.module.ts @@ -1,13 +1,14 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { EventRoutingModule } from './event-routing.module.ts'; -import { EventsComponent } from './events.component'; +import { EventRoutingModule } from './event-routing.module'; +import { EventComponent } from './event/event.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { EventListComponent } from './event-list/event-list.component'; @NgModule({ - declarations: [EventsComponent], + declarations: [EventComponent, EventListComponent], imports: [ CommonModule, EventRoutingModule, diff --git a/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.html b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.html new file mode 100644 index 000000000..94de422be --- /dev/null +++ b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.scss b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.spec.ts b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.spec.ts new file mode 100644 index 000000000..51be079eb --- /dev/null +++ b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FundingListComponent } from './funding-list.component'; + +describe('FundingListComponent', () => { + let component: FundingListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FundingListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FundingListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.ts b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.ts new file mode 100644 index 000000000..e9c82e223 --- /dev/null +++ b/research-hub-web/src/app/components/fundings/funding-list/funding-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllFundingGQL, FundingCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-funding-list', + templateUrl: './funding-list.component.html', + styleUrls: ['./funding-list.component.scss'] +}) +export class FundingListComponent implements OnInit, OnDestroy { + public fundings: FundingCollection; + + private subscription = new Subscription(); + + constructor( + private allFundingGQL: AllFundingGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allFundingGQL.fetch().pipe( + map((result) => result.data.fundingCollection as FundingCollection) + ).subscribe((collection) => this.fundings = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/fundings/funding-routing.module.ts b/research-hub-web/src/app/components/fundings/funding-routing.module.ts index 0b837b10a..c5a567ff1 100644 --- a/research-hub-web/src/app/components/fundings/funding-routing.module.ts +++ b/research-hub-web/src/app/components/fundings/funding-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { FundingsComponent } from './fundings.component'; +import { FundingListComponent } from './funding-list/funding-list.component'; +import { FundingComponent } from './funding/funding.component'; const routes: Routes = [ - { path: '', component: FundingsComponent } + { path: '', component: FundingListComponent }, + { path: ':slug', component: FundingComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/fundings/fundings.component.html b/research-hub-web/src/app/components/fundings/funding/funding.component.html similarity index 96% rename from research-hub-web/src/app/components/fundings/fundings.component.html rename to research-hub-web/src/app/components/fundings/funding/funding.component.html index f6ace15fa..ac9827ade 100644 --- a/research-hub-web/src/app/components/fundings/fundings.component.html +++ b/research-hub-web/src/app/components/fundings/funding/funding.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/fundings/fundings.component.scss b/research-hub-web/src/app/components/fundings/funding/funding.component.scss similarity index 100% rename from research-hub-web/src/app/components/fundings/fundings.component.scss rename to research-hub-web/src/app/components/fundings/funding/funding.component.scss diff --git a/research-hub-web/src/app/components/fundings/fundings.component.spec.ts b/research-hub-web/src/app/components/fundings/funding/funding.component.spec.ts similarity index 91% rename from research-hub-web/src/app/components/fundings/fundings.component.spec.ts rename to research-hub-web/src/app/components/fundings/funding/funding.component.spec.ts index a4af3203d..f3d030dfb 100644 --- a/research-hub-web/src/app/components/fundings/fundings.component.spec.ts +++ b/research-hub-web/src/app/components/fundings/funding/funding.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { PageTitleService } from '@services/page-title.service'; -import { FundingsComponent } from './fundings.component'; +import { FundingComponent } from './funding.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; import { ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -13,8 +13,8 @@ import { RouterTestingModule } from '@angular/router/testing'; import { MockModule, MockProvider } from 'ng-mocks'; describe('FundingsComponent', () => { - let component: FundingsComponent; - let fixture: ComponentFixture; + let component: FundingComponent; + let fixture: ComponentFixture; let controller: ApolloTestingController; const mockAllFunding$: Observable = of({ @@ -47,7 +47,7 @@ describe('FundingsComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - FundingsComponent + FundingComponent ], imports: [ RouterTestingModule, @@ -65,7 +65,7 @@ describe('FundingsComponent', () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(FundingsComponent); + fixture = TestBed.createComponent(FundingComponent); component = fixture.componentInstance; fixture.detectChanges(); }); @@ -88,7 +88,7 @@ describe('FundingsComponent', () => { describe('When a url slug is present', async () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(FundingsComponent); + fixture = TestBed.createComponent(FundingComponent); component = fixture.componentInstance; TestBed.inject(ActivatedRoute).params = of({ slug: 'death-star' diff --git a/research-hub-web/src/app/components/fundings/fundings.component.ts b/research-hub-web/src/app/components/fundings/funding/funding.component.ts similarity index 84% rename from research-hub-web/src/app/components/fundings/fundings.component.ts rename to research-hub-web/src/app/components/fundings/funding/funding.component.ts index 484da56d8..2c49d1447 100644 --- a/research-hub-web/src/app/components/fundings/fundings.component.ts +++ b/research-hub-web/src/app/components/fundings/funding/funding.component.ts @@ -20,10 +20,10 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-fundings', - templateUrl: './fundings.component.html', - styleUrls: ['./fundings.component.scss'] + templateUrl: './funding.component.html', + styleUrls: ['./funding.component.scss'] }) -export class FundingsComponent implements OnInit, OnDestroy { +export class FundingComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -84,11 +84,6 @@ export class FundingsComponent implements OnInit, OnDestroy { * Function that loads the Funding/collection depending on if a slug is present. */ private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual Funding, - * therefore run the corresponding query. If not, return all Fundings. - */ - if (!!this.slug) { // Check if the article slug is valid otherwise redirect to 404 this.getAllFundingSlugs().subscribe(data => { let slugs = []; @@ -123,25 +118,7 @@ export class FundingsComponent implements OnInit, OnDestroy { this.pageTitleService.title = data.title; }); this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Fundings'; - this.allFundings$ = this.getAllFundings(); - try { this.funding$.unsubscribe(); } catch { } - } - } - /** - * Function that returns all Fundings from the FundingCollection as an observable - * of type FundingCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting Funding/slug-name. - */ - public getAllFundings(): Observable { - try { - return this.allFundingGQL.fetch() - .pipe(pluck('data', 'fundingCollection')) as Observable - } catch (e) { console.error('Error loading all Fundings:', e) }; } /** diff --git a/research-hub-web/src/app/components/fundings/fundings.module.ts b/research-hub-web/src/app/components/fundings/fundings.module.ts index 7bc8715eb..7ae02791b 100644 --- a/research-hub-web/src/app/components/fundings/fundings.module.ts +++ b/research-hub-web/src/app/components/fundings/fundings.module.ts @@ -1,17 +1,19 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FundingsComponent } from './fundings.component'; +import { FundingComponent } from './funding/funding.component'; import { FundingRoutingModule } from './funding-routing.module'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; import { FundingPurposeComponent } from './funding-purpose/funding-purpose.component'; import { FundingDeadlinesComponent } from './funding-deadlines/funding-deadlines.component'; +import { FundingListComponent } from './funding-list/funding-list.component'; @NgModule({ declarations: [ - FundingsComponent, + FundingComponent, FundingPurposeComponent, - FundingDeadlinesComponent + FundingDeadlinesComponent, + FundingListComponent ], imports: [ CommonModule, @@ -20,4 +22,4 @@ import { FundingDeadlinesComponent } from './funding-deadlines/funding-deadlines NgxContentfulRichTextModule ] }) -export class FundingsModule { } \ No newline at end of file +export class FundingsModule { } diff --git a/research-hub-web/src/app/components/services/service-list/service-list.component.html b/research-hub-web/src/app/components/services/service-list/service-list.component.html new file mode 100644 index 000000000..50e57dc7f --- /dev/null +++ b/research-hub-web/src/app/components/services/service-list/service-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/services/service-list/service-list.component.scss b/research-hub-web/src/app/components/services/service-list/service-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/services/service-list/service-list.component.spec.ts b/research-hub-web/src/app/components/services/service-list/service-list.component.spec.ts new file mode 100644 index 000000000..97c794920 --- /dev/null +++ b/research-hub-web/src/app/components/services/service-list/service-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ServiceListComponent } from './service-list.component'; + +describe('ServiceListComponent', () => { + let component: ServiceListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ServiceListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ServiceListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/services/service-list/service-list.component.ts b/research-hub-web/src/app/components/services/service-list/service-list.component.ts new file mode 100644 index 000000000..5e232e31d --- /dev/null +++ b/research-hub-web/src/app/components/services/service-list/service-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllServicesGQL, ServiceCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-service-list', + templateUrl: './service-list.component.html', + styleUrls: ['./service-list.component.scss'] +}) +export class ServiceListComponent implements OnInit, OnDestroy { + public services: ServiceCollection; + + private subscription = new Subscription(); + + constructor( + private allServicesGQL: AllServicesGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allServicesGQL.fetch().pipe( + map((result) => result.data.serviceCollection as ServiceCollection) + ).subscribe((collection) => this.services = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/services/services.component.html b/research-hub-web/src/app/components/services/service/service.component.html similarity index 94% rename from research-hub-web/src/app/components/services/services.component.html rename to research-hub-web/src/app/components/services/service/service.component.html index ad1935f20..0e6980179 100644 --- a/research-hub-web/src/app/components/services/services.component.html +++ b/research-hub-web/src/app/components/services/service/service.component.html @@ -1,11 +1,3 @@ - -
-
- -
diff --git a/research-hub-web/src/app/components/services/services.component.scss b/research-hub-web/src/app/components/services/service/service.component.scss similarity index 100% rename from research-hub-web/src/app/components/services/services.component.scss rename to research-hub-web/src/app/components/services/service/service.component.scss diff --git a/research-hub-web/src/app/components/services/services.component.spec.ts b/research-hub-web/src/app/components/services/service/service.component.spec.ts similarity index 91% rename from research-hub-web/src/app/components/services/services.component.spec.ts rename to research-hub-web/src/app/components/services/service/service.component.spec.ts index 2247a8b84..20c5f75e9 100644 --- a/research-hub-web/src/app/components/services/services.component.spec.ts +++ b/research-hub-web/src/app/components/services/service/service.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { PageTitleService } from '@services/page-title.service'; -import { ServicesComponent } from './services.component'; +import { ServiceComponent } from './service.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; import { RouterModule, ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -13,8 +13,8 @@ import { RouterTestingModule } from '@angular/router/testing'; import { MockModule, MockProvider } from 'ng-mocks'; describe('ServicesComponent', () => { - let component: ServicesComponent; - let fixture: ComponentFixture; + let component: ServiceComponent; + let fixture: ComponentFixture; let controller: ApolloTestingController; const mockAllServices$: Observable = of({ @@ -47,7 +47,7 @@ describe('ServicesComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - ServicesComponent + ServiceComponent ], imports: [ RouterTestingModule, @@ -65,7 +65,7 @@ describe('ServicesComponent', () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(ServicesComponent); + fixture = TestBed.createComponent(ServiceComponent); component = fixture.componentInstance; fixture.detectChanges(); }); @@ -88,7 +88,7 @@ describe('ServicesComponent', () => { describe('When a url slug is present', async () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(ServicesComponent); + fixture = TestBed.createComponent(ServiceComponent); component = fixture.componentInstance; TestBed.inject(ActivatedRoute).params = of({ slug: 'death-star' diff --git a/research-hub-web/src/app/components/services/services.component.ts b/research-hub-web/src/app/components/services/service/service.component.ts similarity index 84% rename from research-hub-web/src/app/components/services/services.component.ts rename to research-hub-web/src/app/components/services/service/service.component.ts index ead3b48d5..52d898828 100644 --- a/research-hub-web/src/app/components/services/services.component.ts +++ b/research-hub-web/src/app/components/services/service/service.component.ts @@ -20,10 +20,10 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-services', - templateUrl: './services.component.html', - styleUrls: ['./services.component.scss'] + templateUrl: './service.component.html', + styleUrls: ['./service.component.scss'] }) -export class ServicesComponent implements OnInit, OnDestroy { +export class ServiceComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -84,11 +84,6 @@ export class ServicesComponent implements OnInit, OnDestroy { * Function that loads the Service/collection depending on if a slug is present. */ private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual Service, - * therefore run the corresponding query. If not, return all Services. - */ - if (!!this.slug) { // Check if the article slug is valid otherwise redirect to 404 this.getAllServicesSlugs().subscribe(data => { let slugs = []; @@ -122,25 +117,7 @@ export class ServicesComponent implements OnInit, OnDestroy { this.pageTitleService.title = data.title; }); this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Services'; - this.allServices$ = this.getAllServices(); - try { this.service$.unsubscribe(); } catch { } - } - } - /** - * Function that returns all Services from the ServiceCollection as an observable - * of type ServiceCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting Service/slug-name. - */ - public getAllServices(): Observable { - try { - return this.allServicesGQL.fetch() - .pipe(pluck('data', 'serviceCollection')) as Observable - } catch (e) { console.error('Error loading all Services:', e) }; } /** diff --git a/research-hub-web/src/app/components/services/services-routing.module.ts b/research-hub-web/src/app/components/services/services-routing.module.ts index b1272d693..5d1bd050a 100644 --- a/research-hub-web/src/app/components/services/services-routing.module.ts +++ b/research-hub-web/src/app/components/services/services-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { ServicesComponent } from './services.component'; +import { ServiceListComponent } from './service-list/service-list.component'; +import { ServiceComponent } from './service/service.component'; const routes: Routes = [ - { path: '', component: ServicesComponent } + { path: '', component: ServiceListComponent }, + { path: ':slug', component: ServiceComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/services/services.module.ts b/research-hub-web/src/app/components/services/services.module.ts index 51d986807..a0f2cd1e4 100644 --- a/research-hub-web/src/app/components/services/services.module.ts +++ b/research-hub-web/src/app/components/services/services.module.ts @@ -2,12 +2,13 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ServiceRoutingModule } from './services-routing.module'; -import { ServicesComponent } from './services.component'; +import { ServiceComponent } from './service/service.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { ServiceListComponent } from './service-list/service-list.component'; @NgModule({ - declarations: [ServicesComponent], + declarations: [ServiceComponent, ServiceListComponent], imports: [ CommonModule, ServiceRoutingModule, diff --git a/research-hub-web/src/app/components/shared/collection-list/collection-list.component.html b/research-hub-web/src/app/components/shared/collection-list/collection-list.component.html index 83a0ee77b..c1fe7ebfa 100644 --- a/research-hub-web/src/app/components/shared/collection-list/collection-list.component.html +++ b/research-hub-web/src/app/components/shared/collection-list/collection-list.component.html @@ -1,52 +1,91 @@ - +
+

- {{ collection.__typename | humanCase }} -

Found + {{ collection.__typename | humanCase }} + + Found - {{ collection.items.length }} - results in + {{ collection.items.length }} results in - {{ collection.__typename | humanCase }} + {{ collection.__typename | humanCase }} - - - -
-
- {{content?.icon?.description}} -
- - - - -
- -

{{ content.title }}  - lock -

-
- - {{ content.summary }} - -
-
-
+ + + +
+
+ {{ content?.icon?.description }} +
+ + + + +
+ +

+ {{ content.title }}  + lock +

+
+ + {{ content.summary }} + +
+
+
-
\ No newline at end of file + +
diff --git a/research-hub-web/src/app/components/softwares/software-list/software-list.component.html b/research-hub-web/src/app/components/softwares/software-list/software-list.component.html new file mode 100644 index 000000000..9e661be18 --- /dev/null +++ b/research-hub-web/src/app/components/softwares/software-list/software-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/softwares/software-list/software-list.component.scss b/research-hub-web/src/app/components/softwares/software-list/software-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/softwares/software-list/software-list.component.spec.ts b/research-hub-web/src/app/components/softwares/software-list/software-list.component.spec.ts new file mode 100644 index 000000000..861394c64 --- /dev/null +++ b/research-hub-web/src/app/components/softwares/software-list/software-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SoftwareListComponent } from './software-list.component'; + +describe('SoftwareListComponent', () => { + let component: SoftwareListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SoftwareListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SoftwareListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/softwares/software-list/software-list.component.ts b/research-hub-web/src/app/components/softwares/software-list/software-list.component.ts new file mode 100644 index 000000000..f69a04725 --- /dev/null +++ b/research-hub-web/src/app/components/softwares/software-list/software-list.component.ts @@ -0,0 +1,30 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllSoftwareGQL, SoftwareCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-software-list', + templateUrl: './software-list.component.html', + styleUrls: ['./software-list.component.scss'] +}) +export class SoftwareListComponent implements OnInit, OnDestroy { + public software: SoftwareCollection; + + private subscription = new Subscription(); + + constructor( + private allSoftwareGQL: AllSoftwareGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allSoftwareGQL.fetch().pipe( + map((result) => result.data.softwareCollection as SoftwareCollection) + ).subscribe((collection) => this.software = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + +} diff --git a/research-hub-web/src/app/components/softwares/software-routing.module.ts b/research-hub-web/src/app/components/softwares/software-routing.module.ts index 47b740ff3..7de37c224 100644 --- a/research-hub-web/src/app/components/softwares/software-routing.module.ts +++ b/research-hub-web/src/app/components/softwares/software-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { SoftwaresComponent } from './softwares.component'; +import { SoftwareListComponent } from './software-list/software-list.component'; +import { SoftwareComponent } from './software/software.component'; const routes: Routes = [ - { path: '', component: SoftwaresComponent } + { path: '', component: SoftwareListComponent }, + { path: ':slug', component: SoftwareComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/softwares/softwares.component.html b/research-hub-web/src/app/components/softwares/software/software.component.html similarity index 95% rename from research-hub-web/src/app/components/softwares/softwares.component.html rename to research-hub-web/src/app/components/softwares/software/software.component.html index 87c18c31d..e4321b1bd 100644 --- a/research-hub-web/src/app/components/softwares/softwares.component.html +++ b/research-hub-web/src/app/components/softwares/software/software.component.html @@ -1,11 +1,3 @@ - -
- -
-
diff --git a/research-hub-web/src/app/components/softwares/softwares.component.scss b/research-hub-web/src/app/components/softwares/software/software.component.scss similarity index 100% rename from research-hub-web/src/app/components/softwares/softwares.component.scss rename to research-hub-web/src/app/components/softwares/software/software.component.scss diff --git a/research-hub-web/src/app/components/softwares/softwares.component.spec.ts b/research-hub-web/src/app/components/softwares/software/software.component.spec.ts similarity index 91% rename from research-hub-web/src/app/components/softwares/softwares.component.spec.ts rename to research-hub-web/src/app/components/softwares/software/software.component.spec.ts index d3309c625..ad75ff264 100644 --- a/research-hub-web/src/app/components/softwares/softwares.component.spec.ts +++ b/research-hub-web/src/app/components/softwares/software/software.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { PageTitleService } from '@services/page-title.service'; -import { SoftwaresComponent } from './softwares.component'; +import { SoftwareComponent } from './software.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; import { RouterModule, ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -13,8 +13,8 @@ import { RouterTestingModule } from '@angular/router/testing'; import { MockModule, MockProvider } from 'ng-mocks'; describe('SoftwaresComponent', () => { - let component: SoftwaresComponent; - let fixture: ComponentFixture; + let component: SoftwareComponent; + let fixture: ComponentFixture; let controller: ApolloTestingController; const mockAllSoftware$: Observable = of({ @@ -47,7 +47,7 @@ describe('SoftwaresComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - SoftwaresComponent + SoftwareComponent ], imports: [ RouterTestingModule, @@ -65,7 +65,7 @@ describe('SoftwaresComponent', () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(SoftwaresComponent); + fixture = TestBed.createComponent(SoftwareComponent); component = fixture.componentInstance; fixture.detectChanges(); }); @@ -88,7 +88,7 @@ describe('SoftwaresComponent', () => { describe('When a url slug is present', async () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(SoftwaresComponent); + fixture = TestBed.createComponent(SoftwareComponent); component = fixture.componentInstance; TestBed.inject(ActivatedRoute).params = of({ slug: 'death-star' diff --git a/research-hub-web/src/app/components/softwares/softwares.component.ts b/research-hub-web/src/app/components/softwares/software/software.component.ts similarity index 59% rename from research-hub-web/src/app/components/softwares/softwares.component.ts rename to research-hub-web/src/app/components/softwares/software/software.component.ts index 221a20c70..8c952d372 100644 --- a/research-hub-web/src/app/components/softwares/softwares.component.ts +++ b/research-hub-web/src/app/components/softwares/software/software.component.ts @@ -20,10 +20,10 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-software', - templateUrl: './softwares.component.html', - styleUrls: ['./softwares.component.scss'] + templateUrl: './software.component.html', + styleUrls: ['./software.component.scss'] }) -export class SoftwaresComponent implements OnInit, OnDestroy { +export class SoftwareComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -84,62 +84,39 @@ export class SoftwaresComponent implements OnInit, OnDestroy { * Function that loads the Software/collection depending on if a slug is present. */ private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual Software, - * therefore run the corresponding query. If not, return all Software. - */ - if (!!this.slug) { - // Check if the article slug is valid otherwise redirect to 404 - this.getAllSoftwareSlugs().subscribe(data => { - let slugs = []; - data.items.forEach(data => { - slugs.push(data.slug) - }) - if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } - }); - this.software = this.getSoftwareBySlug(this.slug); - this.software$ = this.getSoftwareBySlug(this.slug).subscribe(data => { - // Strip nulls from related collection data. - data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); - data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); - data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); - data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); + // Check if the article slug is valid otherwise redirect to 404 + this.getAllSoftwareSlugs().subscribe(data => { + let slugs = []; + data.items.forEach(data => { + slugs.push(data.slug) + }) + if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } + }); + this.software = this.getSoftwareBySlug(this.slug); + this.software$ = this.getSoftwareBySlug(this.slug).subscribe(data => { + // Strip nulls from related collection data. + data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); + data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); + data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); + data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); - // Set banner image URL for webp format if webp is supported - if (data.banner?.url) { - this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; - } else { - this.bannerImageUrl = undefined; - } + // Set banner image URL for webp format if webp is supported + if (data.banner?.url) { + this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; + } else { + this.bannerImageUrl = undefined; + } - // If Call To Action is an email address - if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { - data['callToAction'] = 'mailto:' + data['callToAction']; - } + // If Call To Action is an email address + if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { + data['callToAction'] = 'mailto:' + data['callToAction']; + } - this.bodyMediaService.setBodyMedia(data.bodyText?.links); - this.pageTitleService.title = data.title; - }); - this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'Software'; - this.allSoftware$ = this.getAllSoftware(); - try { this.software$.unsubscribe(); } catch { } - } - } + this.bodyMediaService.setBodyMedia(data.bodyText?.links); + this.pageTitleService.title = data.title; + }); + this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - /** - * Function that returns all Software from the SoftwareCollection as an observable - * of type SoftwareCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting Software/slug-name. - */ - public getAllSoftware(): Observable { - try { - return this.allSoftwareGQL.fetch() - .pipe(pluck('data', 'softwareCollection')) as Observable - } catch (e) { console.error('Error loading all Software:', e) }; } /** diff --git a/research-hub-web/src/app/components/softwares/softwares.module.ts b/research-hub-web/src/app/components/softwares/softwares.module.ts index 3bf909b06..e0159aed2 100644 --- a/research-hub-web/src/app/components/softwares/softwares.module.ts +++ b/research-hub-web/src/app/components/softwares/softwares.module.ts @@ -2,12 +2,13 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SoftwareRoutingModule } from './software-routing.module'; -import { SoftwaresComponent } from './softwares.component'; +import { SoftwareComponent } from './software/software.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { SoftwareListComponent } from './software-list/software-list.component'; @NgModule({ - declarations: [SoftwaresComponent], + declarations: [SoftwareComponent, SoftwareListComponent], imports: [ CommonModule, SoftwareRoutingModule, diff --git a/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.html b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.html new file mode 100644 index 000000000..afaf62624 --- /dev/null +++ b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.html @@ -0,0 +1 @@ + diff --git a/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.scss b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.spec.ts b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.spec.ts new file mode 100644 index 000000000..d8539a0ad --- /dev/null +++ b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubhubListComponent } from './subhub-list.component'; + +describe('SubhubListComponent', () => { + let component: SubhubListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SubhubListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubhubListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.ts b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.ts new file mode 100644 index 000000000..6588ea34d --- /dev/null +++ b/research-hub-web/src/app/components/subhubs/subhub-list/subhub-list.component.ts @@ -0,0 +1,29 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { AllSubHubGQL, SubHubCollection } from '@app/graphql/schema'; +import { Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-subhub-list', + templateUrl: './subhub-list.component.html', + styleUrls: ['./subhub-list.component.scss'] +}) +export class SubhubListComponent implements OnInit, OnDestroy { + public subhubs: SubHubCollection; + + private subscription = new Subscription(); + + constructor( + private allSubhubGQL: AllSubHubGQL + ) { } + + ngOnInit(): void { + this.subscription.add(this.allSubhubGQL.fetch().pipe( + map((result) => result.data.subHubCollection as SubHubCollection) + ).subscribe((collection) => this.subhubs = collection)); + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } +} diff --git a/research-hub-web/src/app/components/subhubs/subhubs.component.html b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html similarity index 93% rename from research-hub-web/src/app/components/subhubs/subhubs.component.html rename to research-hub-web/src/app/components/subhubs/subhub/subhub.component.html index 615ee920f..4b11c0727 100644 --- a/research-hub-web/src/app/components/subhubs/subhubs.component.html +++ b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html @@ -1,14 +1,6 @@ - -
- -
-
-
+
diff --git a/research-hub-web/src/app/components/subhubs/subhubs.component.scss b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.scss similarity index 100% rename from research-hub-web/src/app/components/subhubs/subhubs.component.scss rename to research-hub-web/src/app/components/subhubs/subhub/subhub.component.scss diff --git a/research-hub-web/src/app/components/subhubs/subhubs.component.spec.ts b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.spec.ts similarity index 96% rename from research-hub-web/src/app/components/subhubs/subhubs.component.spec.ts rename to research-hub-web/src/app/components/subhubs/subhub/subhub.component.spec.ts index 4a9392841..6d46aeab2 100644 --- a/research-hub-web/src/app/components/subhubs/subhubs.component.spec.ts +++ b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.spec.ts @@ -1,31 +1,27 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { SubhubsComponent } from './subhubs.component'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; import { SharedModule } from '@components/shared/app.shared.module'; -import { SubhubsRoutingModule } from './subhubs-routing.module'; -import { RouterModule, ActivatedRoute } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; -import { By } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { MaterialModule } from '@app/app.material.module'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { Observable, of, from } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { SubHub, SubHubCollection, - AllSubHubGQL, AllContentItemParentSubHubsGQL, - SubHubOrder, } from "@graphql/schema"; import { PageTitleService } from '@services/page-title.service'; import { MockModule, MockProvider } from 'ng-mocks'; import { RouterTestingModule } from '@angular/router/testing'; +import { SubhubComponent } from './subhub.component'; describe('SubhubsComponent', () => { - let component: SubhubsComponent; - let fixture: ComponentFixture; + let component: SubhubComponent; + let fixture: ComponentFixture; let backend: ApolloTestingController; let controller: ApolloTestingController; let subHubSpy: any; // returns mock query data @@ -504,7 +500,7 @@ describe('SubhubsComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [SubhubsComponent], + declarations: [SubhubComponent], imports: [ ApolloTestingModule, MockModule(CommonModule), @@ -522,7 +518,7 @@ describe('SubhubsComponent', () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(SubhubsComponent); + fixture = TestBed.createComponent(SubhubComponent); component = fixture.componentInstance; fixture.detectChanges(); }); @@ -545,7 +541,7 @@ describe('SubhubsComponent', () => { describe('When a url slug is present', async () => { beforeEach(() => { controller = TestBed.inject(ApolloTestingController); - fixture = TestBed.createComponent(SubhubsComponent); + fixture = TestBed.createComponent(SubhubComponent); component = fixture.componentInstance; TestBed.inject(ActivatedRoute).params = of({ slug: 'first-subhub' diff --git a/research-hub-web/src/app/components/subhubs/subhubs.component.ts b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts similarity index 81% rename from research-hub-web/src/app/components/subhubs/subhubs.component.ts rename to research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts index 7106e6c90..5d719196b 100644 --- a/research-hub-web/src/app/components/subhubs/subhubs.component.ts +++ b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts @@ -19,10 +19,10 @@ import supportsWebP from 'supports-webp'; @Component({ selector: 'app-subhubs', - templateUrl: './subhubs.component.html', - styleUrls: ['./subhubs.component.scss'] + templateUrl: './subhub.component.html', + styleUrls: ['./subhub.component.scss'] }) -export class SubhubsComponent implements OnInit, OnDestroy { +export class SubhubComponent implements OnInit, OnDestroy { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -89,11 +89,6 @@ export class SubhubsComponent implements OnInit, OnDestroy { * Function that loads the SubHub/collection depending on if a slug is present. */ private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual SubHub, - * therefore run the corresponding query. If not, return all SubHub. - */ - if (!!this.slug) { this.subHub = this.getSubHubBySlug(this.slug); this.subHub$ = this.getSubHubBySlug(this.slug).subscribe(data => { // Remove nulls from server in case of error. @@ -110,25 +105,7 @@ export class SubhubsComponent implements OnInit, OnDestroy { } }); this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - } else { - this.pageTitleService.title = 'SubHub'; - this.allSubHubs$ = this.getAllSubHubs(); - try { this.subHub$.unsubscribe(); } catch { } - } - } - /** - * Function that returns all SubHub from the SubHubCollection as an observable - * of type SubHubCollection. This is then unwrapped with the async pipe. - * - * This function is only called if no slug parameter is present in the URL, i.e. the - * user is visiting SubHub/slug-name. - */ - public getAllSubHubs(): Observable { - try { - return this.allSubHubGQL.fetch() - .pipe(pluck('data', 'subHubCollection')) as Observable - } catch (e) { console.error('Error loading all SubHub:', e) }; } /** diff --git a/research-hub-web/src/app/components/subhubs/subhubs-routing.module.ts b/research-hub-web/src/app/components/subhubs/subhubs-routing.module.ts index bd9084b3b..1a0a69082 100644 --- a/research-hub-web/src/app/components/subhubs/subhubs-routing.module.ts +++ b/research-hub-web/src/app/components/subhubs/subhubs-routing.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { SubhubsComponent } from './subhubs.component'; +import { SubhubListComponent } from './subhub-list/subhub-list.component'; +import { SubhubComponent } from './subhub/subhub.component'; const routes: Routes = [ - {path: '', component: SubhubsComponent} + { path: '', component: SubhubListComponent }, + { path: ':slug', component: SubhubComponent} ]; @NgModule({ diff --git a/research-hub-web/src/app/components/subhubs/subhubs.module.ts b/research-hub-web/src/app/components/subhubs/subhubs.module.ts index 24d0401cb..54c147d4f 100644 --- a/research-hub-web/src/app/components/subhubs/subhubs.module.ts +++ b/research-hub-web/src/app/components/subhubs/subhubs.module.ts @@ -2,12 +2,13 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SubhubsRoutingModule } from './subhubs-routing.module'; -import { SubhubsComponent } from './subhubs.component'; +import { SubhubComponent } from './subhub/subhub.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; +import { SubhubListComponent } from './subhub-list/subhub-list.component'; @NgModule({ - declarations: [SubhubsComponent], + declarations: [SubhubComponent, SubhubListComponent], imports: [ CommonModule, SubhubsRoutingModule, @@ -15,4 +16,4 @@ import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; NgxContentfulRichTextModule ] }) -export class SubhubsModule { } \ No newline at end of file +export class SubhubsModule { } diff --git a/research-hub-web/src/app/routing/routing.ts b/research-hub-web/src/app/routing/routing.ts index a2eea331a..2c54f7871 100644 --- a/research-hub-web/src/app/routing/routing.ts +++ b/research-hub-web/src/app/routing/routing.ts @@ -36,79 +36,47 @@ export const appRoutes: Routes = [ }, { path: 'search', - loadChildren: () => import('@app/components/search-page/search-page.module').then((m) => m.SearchPageModule), + loadChildren: () => import('@components/search-page/search-page.module').then((m) => m.SearchPageModule), }, { path: 'categories', - loadChildren: () => import('@app/components/categories-page/categories-page.module').then((m) => m.CategoriesPageModule), + loadChildren: () => import('@components/categories-page/categories-page.module').then((m) => m.CategoriesPageModule), }, { path: 'activities', - loadChildren: () => import('@app/components/activities-page/activities-page.module').then((m) => m.ActivitiesPageModule), + loadChildren: () => import('@components/activities-page/activities-page.module').then((m) => m.ActivitiesPageModule), }, { path: 'equipment', - loadChildren: () => import('@app/components/equipments/equipments.module').then(m => m.EquipmentsModule) + loadChildren: () => import('@components/equipments/equipments.module').then(m => m.EquipmentsModule) }, { - path: 'equipment/:slug', - loadChildren: () => import('@app/components/equipments/equipments.module').then(m => m.EquipmentsModule) - }, - { - path: 'casestudies', - loadChildren: () => import('@components/casestudys/casestudys.module').then(m => m.CasestudysModule) - }, - { - path: 'casestudy/:slug', + path: 'casestudy', loadChildren: () => import('@components/casestudys/casestudys.module').then(m => m.CasestudysModule) }, { - path: 'articles', + path: 'article', loadChildren: () => import('@components/articles/articles.module').then(m => m.ArticlesModule) }, { - path: 'article/:slug', - loadChildren: () => import('@components/articles/articles.module').then(m => m.ArticlesModule) - }, - { - path: 'event/:slug', - loadChildren: () => import('@app/components/events/events.module').then(m => m.EventsModule) - }, - { - path: 'events', - loadChildren: () => import('@app/components/events/events.module').then(m => m.EventsModule) - }, - { - path: 'funding/:slug', - loadChildren: () => import('@app/components/fundings/fundings.module').then(m => m.FundingsModule) + path: 'event', + loadChildren: () => import('@components/events/events.module').then(m => m.EventsModule) }, { path: 'funding', - loadChildren: () => import('@app/components/fundings/fundings.module').then(m => m.FundingsModule) - }, - { - path: 'subhub/:slug', - loadChildren: () => import('@components/subhubs/subhubs.module').then(m => m.SubhubsModule) + loadChildren: () => import('@components/fundings/fundings.module').then(m => m.FundingsModule) }, { - path: 'subhubs', + path: 'subhub', loadChildren: () => import('@components/subhubs/subhubs.module').then(m => m.SubhubsModule) }, { - path: 'services', - loadChildren: () => import('@app/components/services/services.module').then(m => m.ServicesModule) - }, - { - path: 'service/:slug', - loadChildren: () => import('@app/components/services/services.module').then(m => m.ServicesModule) - }, - { - path: 'software/:slug', - loadChildren: () => import('@app/components/softwares/softwares.module').then(m => m.SoftwaresModule) + path: 'service', + loadChildren: () => import('@components/services/services.module').then(m => m.ServicesModule) }, { path: 'software', - loadChildren: () => import('@app/components/softwares/softwares.module').then(m => m.SoftwaresModule) + loadChildren: () => import('@components/softwares/softwares.module').then(m => m.SoftwaresModule) }, ] }, @@ -118,6 +86,6 @@ export const appRoutes: Routes = [ */ { path: '**', - loadChildren: () => import("@app/components/subhub-routes-loader/subhub-routes-loader.module").then(m => m.SubHubRoutesLoaderModule) + loadChildren: () => import("@components/subhub-routes-loader/subhub-routes-loader.module").then(m => m.SubHubRoutesLoaderModule) } ]; From 3b70c8c59e827691166167f9f2a008269e1c7062 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 20 Oct 2021 14:25:50 +1300 Subject: [PATCH 02/39] initial refactor of article component --- .../articles/article/article.component.html | 2 +- .../articles/article/article.component.ts | 138 +++++++----------- .../shared/cards/cards.component.html | 6 +- .../shared/cards/cards.component.ts | 32 ++-- 4 files changed, 70 insertions(+), 108 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.html b/research-hub-web/src/app/components/articles/article/article.component.html index 4df2769ed..096900d25 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.html +++ b/research-hub-web/src/app/components/articles/article/article.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/research-hub-web/src/app/components/articles/article/article.component.ts b/research-hub-web/src/app/components/articles/article/article.component.ts index 749099ac7..f33617cce 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.ts +++ b/research-hub-web/src/app/components/articles/article/article.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, Type } from '@angular/core'; +import { Component, OnInit, Type } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { BodyMediaComponent } from '@components/shared/body-media/body-media.component'; import { BLOCKS, INLINES } from '@contentful/rich-text-types'; @@ -14,8 +14,8 @@ import { CerGraphqlService } from '@services/cer-graphql.service'; import { PageTitleService } from '@services/page-title.service'; import { NodeRenderer } from 'ngx-contentful-rich-text'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { Observable, Subscription } from 'rxjs'; -import { flatMap, pluck } from 'rxjs/operators'; +import { Observable, of, throwError } from 'rxjs'; +import { map, mergeMap, switchMap } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ @@ -23,7 +23,7 @@ import supportsWebP from 'supports-webp'; templateUrl: './article.component.html', styleUrls: ['./article.component.scss'] }) -export class ArticlesComponent implements OnInit, OnDestroy { +export class ArticlesComponent implements OnInit { nodeRenderers: Record> = { [BLOCKS.QUOTE]: BodyMediaComponent, [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, @@ -34,13 +34,8 @@ export class ArticlesComponent implements OnInit, OnDestroy { }; public isMobile: Boolean; - public bannerTextStyling; - public slug: string; - public article; - public article$: Subscription; - public route$: Subscription; - public bodyLinks$: Subscription; - public allArticles$: Observable; + public bannerTextStyling = 'color: white; text-shadow: 0px 0px 8px #333333;'; + public article$: Observable
; public parentSubHubs; public supportsWebp: Boolean; public bannerImageUrl: string; @@ -70,101 +65,66 @@ export class ArticlesComponent implements OnInit, OnDestroy { }); } - async ngOnInit() { - /** - * Check if there is a slug URL parameter present. If so, this is - * passed to the getArticleBySlug() method. - */ - this.route$ = this.route.params.subscribe(params => { - this.slug = params.slug || this.route.snapshot.data.slug; - this._loadContent(); - }); + ngOnInit() { + this.article$ = this.route.params.pipe( + map((params) => { + return (params.slug || this.route.snapshot.data.slug) as string; + }), + switchMap((slug) => this.loadArticle(slug)) + ); - /** - * Set styling for text if banner is present - */ - this.bannerTextStyling = 'color: white; text-shadow: 0px 0px 8px #333333;'; } /** * Function that loads the article/collection depending on if a slug is present. */ - private async _loadContent() { - /** - * If this.slug is defined, we're loading an individual article, - * therefore run the corresponding query. If not, return all articles. - */ - - this.getAllArticlesSlugs().subscribe(data => { - let slugs = []; - data.items.forEach(data => { - slugs.push(data.slug) + private loadArticle(slug: string): Observable
{ + return this.getArticleBySlug(slug).pipe( + map(data => { + + // Strip nulls from related collection data. + data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); + data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); + data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); + data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); + + // If Call To Action is an email address + if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { + data['callToAction'] = 'mailto:' + data['callToAction']; + } + + // Set banner image URL for webp format if webp is supported + if (data.banner?.url) { + this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; + } else { + this.bannerImageUrl = undefined; + } + + this.bodyMediaService.setBodyMedia(data.bodyText?.links); + this.pageTitleService.title = data.title; + + return data; }) - if (!slugs.includes(this.slug)) { this.router.navigate(['error/404']) } - }); - this.article = this.getArticleBySlug(this.slug); - this.article$ = this.getArticleBySlug(this.slug).subscribe(data => { - - // Strip nulls from related collection data. - data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item); - data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item); - data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item); - data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item); - - // If Call To Action is an email address - if (data.callToAction?.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) { - data['callToAction'] = 'mailto:' + data['callToAction']; - } - - // Set banner image URL for webp format if webp is supported - if (data.banner?.url) { - this.bannerImageUrl = this.supportsWebp ? data.banner?.url + '?w=1900&fm=webp' : data.banner?.url + '?w=1900'; - } else { - this.bannerImageUrl = undefined; - } - - this.bodyMediaService.setBodyMedia(data.bodyText?.links); - this.pageTitleService.title = data.title; - }); - this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); + ); - } + // NOTE: this should be moved to the breadcrumb component + // this.parentSubHubs = await this.cerGraphQLService.getParentSubHubs(this.slug); - /** - * Function that returns all articles slugs from the ArticleCollection as an observable - * of type ArticleCollection. This is then unwrapped with the async pipe. - * - * This function called to determine if a valid slug has been searched otherwise redirect - * - */ - public getAllArticlesSlugs(): Observable { - try { - return this.allArticlesSlugsGQL.fetch() - .pipe(pluck('data', 'articleCollection')) as Observable - } catch (e) { console.error('Error loading all articles:', e) }; } /** * Function that returns an individual article from the ArticleCollection by it's slug * as an observable of type Article. This is then unwrapped with the async pipe. * - * This function is only called if no slug parameter is present in the URL, i.e. - * the user is visiting /articles. - * * @param slug The article's slug. Retrieved from the route parameter of the same name. */ public getArticleBySlug(slug: string): Observable
{ - try { - return this.getArticleBySlugGQL.fetch({ slug: this.slug }) - .pipe(flatMap(x => x.data.articleCollection.items)) as Observable
; - } catch (e) { console.error(`Error loading article ${slug}:`, e); } - } - - ngOnDestroy() { - try { - this.article$.unsubscribe(); - this.route$.unsubscribe(); - this.bodyLinks$.unsubscribe(); - } catch { } + return this.getArticleBySlugGQL.fetch({ slug }).pipe( + mergeMap(x => + x.data.articleCollection.items.length === 0 + ? throwError(`Could not load article with slug "${slug}"`) + : of(x.data.articleCollection.items[0]) + ) + ) as Observable
; } } diff --git a/research-hub-web/src/app/components/shared/cards/cards.component.html b/research-hub-web/src/app/components/shared/cards/cards.component.html index 5063ceb23..293858395 100644 --- a/research-hub-web/src/app/components/shared/cards/cards.component.html +++ b/research-hub-web/src/app/components/shared/cards/cards.component.html @@ -1,4 +1,4 @@ -
+

{{ title }} @@ -11,7 +11,7 @@

role="navigation" fxFlex="19%" aria-label="Collection list" - *ngFor="let content of _contentItem.items" + *ngFor="let content of contentItem.items" class="collection" > @@ -42,7 +42,7 @@

- + {{ content.__typename | contentTypeDisplayName diff --git a/research-hub-web/src/app/components/shared/cards/cards.component.ts b/research-hub-web/src/app/components/shared/cards/cards.component.ts index 86ff4fec7..fb8ec9783 100644 --- a/research-hub-web/src/app/components/shared/cards/cards.component.ts +++ b/research-hub-web/src/app/components/shared/cards/cards.component.ts @@ -1,28 +1,30 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-cards', templateUrl: './cards.component.html', styleUrls: ['./cards.component.scss'] }) -export class CardsComponent implements OnInit { - @Input() title; - public _contentItem; - @Input() contentItem; - @Input() hideImage?: boolean; - @Input() flex; - - constructor() { } +export class CardsComponent { + private _contentItem; - async ngOnInit() { + @Input() + set contentItem(value: any) { // Make a copy of the contentItem, so we can make changes to it without causing ChangedAfterCheckErrors. // Then, remove null items. - this._contentItem = Object.assign({}, this.contentItem); + this._contentItem = Object.assign({}, value); // Don't display content without a title or name. this._contentItem.items = this._contentItem.items?.filter(item => item && (item.title || item.name || item.maoriName)); - // If you want to hide image when displayed - if (this.hideImage) { this._contentItem.items.forEach(element => { - try { delete element['banner'].url } catch {} }); - }; + }; + + get contentItem(): any { + return this._contentItem; } + + @Input() title: string; + @Input() hideImage?: boolean; + @Input() flex: string; + + constructor() { } + } From c23c6a969533f674a0cc986b71d4fb9bfa0f1c36 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 9 Nov 2021 15:00:14 +1300 Subject: [PATCH 03/39] merge changes to article.component --- .../articles/article/article.component.ts | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.ts b/research-hub-web/src/app/components/articles/article/article.component.ts index f33617cce..ffb745135 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.ts +++ b/research-hub-web/src/app/components/articles/article/article.component.ts @@ -1,18 +1,15 @@ import { Component, OnInit, Type } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { BodyMediaComponent } from '@components/shared/body-media/body-media.component'; -import { BLOCKS, INLINES } from '@contentful/rich-text-types'; import { AllArticlesGQL, AllArticlesSlugsGQL, Article, - ArticleCollection, GetArticleBySlugGQL } from '@graphql/schema'; import { BodyMediaService } from '@services/body-media.service'; import { CerGraphqlService } from '@services/cer-graphql.service'; import { PageTitleService } from '@services/page-title.service'; -import { NodeRenderer } from 'ngx-contentful-rich-text'; +import { MarkRenderer, NodeRenderer } from 'ngx-contentful-rich-text'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Observable, of, throwError } from 'rxjs'; import { map, mergeMap, switchMap } from 'rxjs/operators'; @@ -24,14 +21,8 @@ import supportsWebP from 'supports-webp'; styleUrls: ['./article.component.scss'] }) export class ArticlesComponent implements OnInit { - nodeRenderers: Record> = { - [BLOCKS.QUOTE]: BodyMediaComponent, - [BLOCKS.EMBEDDED_ASSET]: BodyMediaComponent, - [BLOCKS.EMBEDDED_ENTRY]: BodyMediaComponent, - [INLINES.ASSET_HYPERLINK]: BodyMediaComponent, - [INLINES.EMBEDDED_ENTRY]: BodyMediaComponent, - [INLINES.ENTRY_HYPERLINK]: BodyMediaComponent, - }; + public nodeRenderers: Record>; + public markRenderers: Record>; public isMobile: Boolean; public bannerTextStyling = 'color: white; text-shadow: 0px 0px 8px #333333;'; @@ -53,6 +44,9 @@ export class ArticlesComponent implements OnInit { ) { this.detectDevice(); this.detectWebP(); + + this.nodeRenderers = this.bodyMediaService.nodeRenderers; + this.markRenderers = this.bodyMediaService.markRenderers; } detectDevice() { @@ -100,7 +94,9 @@ export class ArticlesComponent implements OnInit { this.bannerImageUrl = undefined; } - this.bodyMediaService.setBodyMedia(data.bodyText?.links); + // For each rich text field add the links to the link maps in the body media service to enable rich text rendering + this.bodyMediaService.buildLinkMaps(data.bodyText?.links); + this.pageTitleService.title = data.title; return data; From 76ae8f41230d931409a6e919d9a6371cf6282d4c Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 10 Nov 2021 14:45:50 +1300 Subject: [PATCH 04/39] more changes --- .../src/app/components/articles/article/article.component.ts | 4 ++-- .../src/app/components/articles/articles-routing.module.ts | 4 ++-- .../src/app/components/articles/articles.module.ts | 4 ++-- .../src/app/components/events/event/event.component.ts | 4 ++-- .../src/app/components/fundings/funding/funding.component.ts | 4 ++-- .../src/app/components/fundings/fundings.module.ts | 4 ++-- .../src/app/components/services/service/service.component.ts | 4 ++-- .../app/components/softwares/software/software.component.ts | 2 +- .../src/app/components/subhubs/subhub/subhub.component.ts | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.ts b/research-hub-web/src/app/components/articles/article/article.component.ts index ffb745135..c8f4f717f 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.ts +++ b/research-hub-web/src/app/components/articles/article/article.component.ts @@ -16,11 +16,11 @@ import { map, mergeMap, switchMap } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ - selector: 'app-articles', + selector: 'app-article', templateUrl: './article.component.html', styleUrls: ['./article.component.scss'] }) -export class ArticlesComponent implements OnInit { +export class ArticleComponent implements OnInit { public nodeRenderers: Record>; public markRenderers: Record>; diff --git a/research-hub-web/src/app/components/articles/articles-routing.module.ts b/research-hub-web/src/app/components/articles/articles-routing.module.ts index e882beb51..5bc4df1f1 100644 --- a/research-hub-web/src/app/components/articles/articles-routing.module.ts +++ b/research-hub-web/src/app/components/articles/articles-routing.module.ts @@ -1,11 +1,11 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ArticleListComponent } from './article-list/article-list.component'; -import { ArticlesComponent } from './article/article.component'; +import { ArticleComponent } from './article/article.component'; const routes: Routes = [ { path: '', component: ArticleListComponent }, - { path: ':slug', component: ArticlesComponent } + { path: ':slug', component: ArticleComponent } ]; @NgModule({ diff --git a/research-hub-web/src/app/components/articles/articles.module.ts b/research-hub-web/src/app/components/articles/articles.module.ts index 61120992f..0a912a703 100644 --- a/research-hub-web/src/app/components/articles/articles.module.ts +++ b/research-hub-web/src/app/components/articles/articles.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ArticlesRoutingModule } from './articles-routing.module'; -import { ArticlesComponent } from './article/article.component'; +import { ArticleComponent } from './article/article.component'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; import { ArticleListComponent } from './article-list/article-list.component'; @@ -10,7 +10,7 @@ import { CardsModule } from '../cards/cards.module'; @NgModule({ declarations: [ - ArticlesComponent, + ArticleComponent, ArticleListComponent ], imports: [ diff --git a/research-hub-web/src/app/components/events/event/event.component.ts b/research-hub-web/src/app/components/events/event/event.component.ts index 6076a4417..8236a5723 100644 --- a/research-hub-web/src/app/components/events/event/event.component.ts +++ b/research-hub-web/src/app/components/events/event/event.component.ts @@ -17,11 +17,11 @@ import { flatMap, pluck } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ - selector: 'app-events', + selector: 'app-event', templateUrl: './event.component.html', styleUrls: ['./event.component.scss'] }) -export class EventsComponent implements OnInit, OnDestroy { +export class EventComponent implements OnInit, OnDestroy { public nodeRenderers: Record>; public markRenderers: Record>; public slug: string; diff --git a/research-hub-web/src/app/components/fundings/funding/funding.component.ts b/research-hub-web/src/app/components/fundings/funding/funding.component.ts index 42502b30f..ecd323784 100644 --- a/research-hub-web/src/app/components/fundings/funding/funding.component.ts +++ b/research-hub-web/src/app/components/fundings/funding/funding.component.ts @@ -17,11 +17,11 @@ import { flatMap, pluck } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ - selector: 'app-fundings', + selector: 'app-funding', templateUrl: './funding.component.html', styleUrls: ['./funding.component.scss'] }) -export class FundingsComponent implements OnInit, OnDestroy { +export class FundingComponent implements OnInit, OnDestroy { public nodeRenderers: Record>; public markRenderers: Record>; public slug: string; diff --git a/research-hub-web/src/app/components/fundings/fundings.module.ts b/research-hub-web/src/app/components/fundings/fundings.module.ts index 5baf864e1..f3a1e5c81 100644 --- a/research-hub-web/src/app/components/fundings/fundings.module.ts +++ b/research-hub-web/src/app/components/fundings/fundings.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FundingsComponent } from './funding/funding.component'; +import { FundingComponent } from './funding/funding.component'; import { FundingRoutingModule } from './funding-routing.module'; import { SharedModule } from '@components/shared/app.shared.module'; import { NgxContentfulRichTextModule } from 'ngx-contentful-rich-text'; @@ -9,7 +9,7 @@ import { CardsModule } from '../cards/cards.module'; @NgModule({ declarations: [ - FundingsComponent, + FundingComponent, FundingListComponent ], imports: [ diff --git a/research-hub-web/src/app/components/services/service/service.component.ts b/research-hub-web/src/app/components/services/service/service.component.ts index e0e368bf8..707e80f1e 100644 --- a/research-hub-web/src/app/components/services/service/service.component.ts +++ b/research-hub-web/src/app/components/services/service/service.component.ts @@ -17,11 +17,11 @@ import { flatMap, pluck } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ - selector: 'app-services', + selector: 'app-service', templateUrl: './service.component.html', styleUrls: ['./service.component.scss'] }) -export class ServicesComponent implements OnInit, OnDestroy { +export class ServiceComponent implements OnInit, OnDestroy { public nodeRenderers: Record>; public markRenderers: Record>; public slug: string; diff --git a/research-hub-web/src/app/components/softwares/software/software.component.ts b/research-hub-web/src/app/components/softwares/software/software.component.ts index 1c5f34042..1dcd6d6ee 100644 --- a/research-hub-web/src/app/components/softwares/software/software.component.ts +++ b/research-hub-web/src/app/components/softwares/software/software.component.ts @@ -21,7 +21,7 @@ import supportsWebP from 'supports-webp'; templateUrl: './software.component.html', styleUrls: ['./software.component.scss'] }) -export class SoftwaresComponent implements OnInit, OnDestroy { +export class SoftwareComponent implements OnInit, OnDestroy { public nodeRenderers: Record>; public markRenderers: Record>; public slug: string; diff --git a/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts index 6f7cae8fa..176b1bf8a 100644 --- a/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts +++ b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.ts @@ -16,11 +16,11 @@ import { flatMap, pluck } from 'rxjs/operators'; import supportsWebP from 'supports-webp'; @Component({ - selector: 'app-subhubs', + selector: 'app-subhub', templateUrl: './subhub.component.html', styleUrls: ['./subhub.component.scss'] }) -export class SubhubsComponent implements OnInit, OnDestroy { +export class SubhubComponent implements OnInit, OnDestroy { public nodeRenderers: Record>; public markRenderers: Record>; public slug: string; From 6e7ce10a095035edcad7c8ababfb3fb2fcd32bad Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 11 Nov 2021 10:05:02 +1300 Subject: [PATCH 05/39] fixes and 404 redirect --- .../articles/article/article.component.html | 14 ++++--- .../articles/article/article.component.ts | 37 +++++++++---------- .../case-study/case-study.component.html | 16 ++++---- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.html b/research-hub-web/src/app/components/articles/article/article.component.html index ff175ea59..5a292e171 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.html +++ b/research-hub-web/src/app/components/articles/article/article.component.html @@ -1,4 +1,4 @@ -
+


>; public markRenderers: Record>; + private subscriptions = new Subscription(); + public isMobile: Boolean; public bannerTextStyling = 'color: white; text-shadow: 0px 0px 8px #333333;'; - public article$: Observable
; + public article: Article; public parentSubHubs; public supportsWebp: Boolean; public bannerImageUrl: string; constructor( public route: ActivatedRoute, - public allArticlesGQL: AllArticlesGQL, - public allArticlesSlugsGQL: AllArticlesSlugsGQL, public getArticleBySlugGQL: GetArticleBySlugGQL, - public cerGraphQLService: CerGraphqlService, public pageTitleService: PageTitleService, public bodyMediaService: BodyMediaService, public router: Router, @@ -60,18 +53,24 @@ export class ArticleComponent implements OnInit { } ngOnInit() { - this.article$ = this.route.params.pipe( + this.subscriptions.add(this.route.params.pipe( map((params) => { return (params.slug || this.route.snapshot.data.slug) as string; }), switchMap((slug) => this.loadArticle(slug)) - ); + ).subscribe({ + next: (article: Article) => this.article = article, + error: (error) => { + console.error(error); + this.router.navigateByUrl('/error/404'); + } + })); + } + ngOnDestroy() { + this.subscriptions.unsubscribe(); } - /** - * Function that loads the article/collection depending on if a slug is present. - */ private loadArticle(slug: string): Observable
{ return this.getArticleBySlug(slug).pipe( map(data => { diff --git a/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html index e8f21d25d..e21c8a524 100644 --- a/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html +++ b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html @@ -104,8 +104,8 @@




Date: Thu, 11 Nov 2021 11:21:25 +1300 Subject: [PATCH 06/39] breadcrumb refactor --- .../articles/article/article.component.html | 1 - .../case-study/case-study.component.html | 1 - .../equipment/equipment.component.html | 1 - .../events/event/event.component.html | 1 - .../fundings/funding/funding.component.html | 1 - .../search-page/search-page.component.html | 2 +- .../services/service/service.component.html | 1 - .../breadcrumbs/breadcrumbs.component.html | 6 ++--- .../breadcrumbs/breadcrumbs.component.ts | 22 +++++++++++++++---- .../software/software.component.html | 1 - .../subhubs/subhub/subhub.component.html | 1 - 11 files changed, 22 insertions(+), 16 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.html b/research-hub-web/src/app/components/articles/article/article.component.html index 5a292e171..285f1dd7c 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.html +++ b/research-hub-web/src/app/components/articles/article/article.component.html @@ -79,7 +79,6 @@
diff --git a/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html index e21c8a524..5e98011d9 100644 --- a/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html +++ b/research-hub-web/src/app/components/casestudys/case-study/case-study.component.html @@ -50,7 +50,6 @@
diff --git a/research-hub-web/src/app/components/equipments/equipment/equipment.component.html b/research-hub-web/src/app/components/equipments/equipment/equipment.component.html index 78af9999f..aebd12edf 100644 --- a/research-hub-web/src/app/components/equipments/equipment/equipment.component.html +++ b/research-hub-web/src/app/components/equipments/equipment/equipment.component.html @@ -6,7 +6,6 @@ ngClass.lt-md="site-padding-mobile top-padding" > diff --git a/research-hub-web/src/app/components/events/event/event.component.html b/research-hub-web/src/app/components/events/event/event.component.html index f346848b2..0418d6d30 100644 --- a/research-hub-web/src/app/components/events/event/event.component.html +++ b/research-hub-web/src/app/components/events/event/event.component.html @@ -7,7 +7,6 @@ ngClass.lt-md="site-padding-mobile top-padding" > diff --git a/research-hub-web/src/app/components/fundings/funding/funding.component.html b/research-hub-web/src/app/components/fundings/funding/funding.component.html index 039270a37..e2cdd76da 100644 --- a/research-hub-web/src/app/components/fundings/funding/funding.component.html +++ b/research-hub-web/src/app/components/fundings/funding/funding.component.html @@ -7,7 +7,6 @@ ngClass.lt-md="site-padding-mobile top-padding" > diff --git a/research-hub-web/src/app/components/search-page/search-page.component.html b/research-hub-web/src/app/components/search-page/search-page.component.html index af57c6f74..bbdc3788e 100644 --- a/research-hub-web/src/app/components/search-page/search-page.component.html +++ b/research-hub-web/src/app/components/search-page/search-page.component.html @@ -18,7 +18,7 @@
- +
diff --git a/research-hub-web/src/app/components/services/service/service.component.html b/research-hub-web/src/app/components/services/service/service.component.html index 4f73b7311..e811f8d1d 100644 --- a/research-hub-web/src/app/components/services/service/service.component.html +++ b/research-hub-web/src/app/components/services/service/service.component.html @@ -7,7 +7,6 @@ ngClass.lt-md="site-padding-mobile top-padding" > diff --git a/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.html b/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.html index a223d6309..3db62b82b 100644 --- a/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.html +++ b/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.html @@ -2,8 +2,8 @@ Home - - {{ subHub.title }} + + {{ subHub.title }} {{ title }} -
\ No newline at end of file +
diff --git a/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.ts b/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.ts index 8fc1b252d..9ba8e1369 100644 --- a/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.ts +++ b/research-hub-web/src/app/components/shared/breadcrumbs/breadcrumbs.component.ts @@ -1,13 +1,27 @@ import { Component, OnInit, Input } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { CerGraphqlService, SubHubTitleAndSlug } from '@services/cer-graphql.service'; +import { from } from 'rxjs'; +import { map, mergeMap } from 'rxjs/operators'; @Component({ selector: 'app-breadcrumbs', templateUrl: './breadcrumbs.component.html', styleUrls: ['./breadcrumbs.component.scss'] }) -export class BreadcrumbsComponent { - @Input() contentItem; - @Input() title; +export class BreadcrumbsComponent implements OnInit { + @Input() title: string; + public parentSubHubs: SubHubTitleAndSlug[] = []; - constructor() { } + constructor( + private route: ActivatedRoute, + private cerGraphQLService: CerGraphqlService + ) { } + + ngOnInit(): void { + this.route.paramMap.pipe( + map((paramMap) => paramMap.get('slug')), + mergeMap((slug: string) => from(this.cerGraphQLService.getParentSubHubs(slug))) + ).subscribe((result) => this.parentSubHubs = result); + } } diff --git a/research-hub-web/src/app/components/softwares/software/software.component.html b/research-hub-web/src/app/components/softwares/software/software.component.html index b9b7aa2db..435e0422d 100644 --- a/research-hub-web/src/app/components/softwares/software/software.component.html +++ b/research-hub-web/src/app/components/softwares/software/software.component.html @@ -8,7 +8,6 @@ > diff --git a/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html index 9a76b53c7..8ef24f5ef 100644 --- a/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html +++ b/research-hub-web/src/app/components/subhubs/subhub/subhub.component.html @@ -57,7 +57,6 @@
From 055d8d975299b7858a5e075f00529d5dc2e879ba Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 11 Nov 2021 12:41:18 +1300 Subject: [PATCH 07/39] final changes to article --- .../articles/article/article.component.html | 13 +++---------- .../articles/article/article.component.ts | 19 +++---------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/research-hub-web/src/app/components/articles/article/article.component.html b/research-hub-web/src/app/components/articles/article/article.component.html index 285f1dd7c..79493f002 100644 --- a/research-hub-web/src/app/components/articles/article/article.component.html +++ b/research-hub-web/src/app/components/articles/article/article.component.html @@ -1,13 +1,8 @@