Skip to content

Commit

Permalink
Move the extra code in PortalModule into MysteryService
Browse files Browse the repository at this point in the history
  • Loading branch information
ommann committed Jul 11, 2024
1 parent 783b174 commit c39c9db
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 146 deletions.
19 changes: 11 additions & 8 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,26 @@
// :author: CSC - IT Center for Science Ltd., Espoo Finland [email protected]
// :license: MIT

import { Component, Inject, PLATFORM_ID } from '@angular/core';
import { Component, inject, Inject, PLATFORM_ID } from '@angular/core';
import { DOCUMENT, isPlatformBrowser, PlatformLocation } from '@angular/common';
import { AppConfigService } from '@shared/services/app-config-service.service';
import { OidcSecurityService } from 'angular-auth-oidc-client';
import { NavigationStart, Router, RouterOutlet } from '@angular/router';
import { take } from 'rxjs/operators';
import { AppSettingsService } from '@shared/services/app-settings.service';
import { AppSettingsService } from '@shared/services/app-settings.service';
import { LayoutComponent } from './layout/layout.component';
import { MysteryService } from '@portal/services/mystery.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
standalone: true,
imports: [LayoutComponent, RouterOutlet],
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
standalone: true,
imports: [LayoutComponent, RouterOutlet],
})
export class AppComponent {
mysteryService = inject(MysteryService);

title = 'research-fi-portal';

constructor(
Expand Down
4 changes: 2 additions & 2 deletions src/app/layout/layout.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import { NgModule } from '@angular/core';
// import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
// import { FormsModule } from '@angular/forms';
// import { ErrorModalComponent } from './error-modal/error-modal.component';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
// import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
// import { WINDOW_PROVIDERS } from '../shared/services/window.service';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
// import { TooltipModule } from 'ngx-bootstrap/tooltip';

@NgModule({
imports: [
Expand Down
147 changes: 13 additions & 134 deletions src/app/portal/portal.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
// :license: MIT

// import { Title, Meta } from '@angular/platform-browser';
import { NgModule, OnDestroy } from '@angular/core';
import { NgModule } from '@angular/core';
// import { CommonModule } from '@angular/common';

// import { TooltipModule } from 'ngx-bootstrap/tooltip';
// import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import {
/*import {
FontAwesomeModule,
FaIconLibrary,
} from '@fortawesome/angular-fontawesome';
import {
} from '@fortawesome/angular-fontawesome';*/
/*import {
faExternalLinkAlt,
faInfoCircle,
} from '@fortawesome/free-solid-svg-icons';
} from '@fortawesome/free-solid-svg-icons';*/

// import { MatAutocompleteModule } from '@angular/material/autocomplete';
// import { MatChipsModule } from '@angular/material/chips';
Expand Down Expand Up @@ -87,12 +87,12 @@ import { MatMenuModule } from '@angular/material/menu';*/
// import { HighlightSearchPipe } from './pipes/highlight.pipe';
// import { LinksPipe } from './pipes/links.pipe';

import {
/*import {
Location,
LocationStrategy,
PathLocationStrategy,
ViewportScroller,
} from '@angular/common';
} from '@angular/common';*/

// import { TooltipComponent } from './components/results/tooltip/tooltip.component';
// import { WINDOW_PROVIDERS } from '../shared/services/window.service';
Expand All @@ -114,18 +114,18 @@ import {
// import { ScrollSpyDirective } from './directives/scroll-spy.directive';
// import { SingleFigureComponent } from './components/science-politics/figures/single-figure/single-figure.component';
// import { RelatedLinksComponent } from './components/single/related-links/related-links.component';
import { Event, Scroll, Router } from '@angular/router'; // Router required by scroll logic
// import { Event, Scroll, Router } from '@angular/router'; // Router required by scroll logic
// import { ServiceInfoComponent } from './components/service-info/service-info.component';
// import { PrivacyComponent } from './components/privacy/privacy.component';
// import { AccessibilityComponent } from './components/accessibility/accessibility.component';

// import { SharedModule } from '../shared/shared.module';
import { filter } from 'rxjs/operators';
// import { filter } from 'rxjs/operators';
// import { NewsCardComponent } from './components/news/news-card/news-card.component';
// import { SitemapComponent } from './components/sitemap/sitemap.component';
// import { TabItemComponent } from './components/result-tab/tab-item/tab-item.component';
import { HistoryService } from './services/history.service';
import { TabChangeService } from './services/tab-change.service';
// import { HistoryService } from './services/history.service';
// import { TabChangeService } from './services/tab-change.service';
// import { NewsPaginationComponent } from './components/news/news-pagination/news-pagination.component';
// import { CarouselComponent } from './components/science-politics/figures/carousel/carousel.component';
// import { BarComponent } from './components/visualisation/bar/bar.component';
Expand All @@ -151,7 +151,7 @@ import { TabChangeService } from './services/tab-change.service';
// import { MatTableModule } from '@angular/material/table';
// import { MatSortModule } from '@angular/material/sort';
// import { HandleInfrastructureLinkPipe } from './pipes/handle-infrastructure-link.pipe';
import { Subscription } from 'rxjs';
// import { Subscription } from 'rxjs';
// import { NoResultsComponent } from './components/results/no-results/no-results.component';
// import { FundingCallCategoryFiltersComponent } from './components/results/funding-call-category-filters/funding-call-category-filters.component';
// import { SingleResultLinkComponent } from './components/single/single-result-link/single-result-link.component';
Expand Down Expand Up @@ -311,125 +311,4 @@ import { Subscription } from 'rxjs';
// HighlightSearchPipe,
],
})
export class PortalModule implements OnDestroy {
startPage;
routeSub: Subscription;

isResultPage(url: string) {
// Check if the page is on results, and that the tabname ends with 's' (not single result)
return (
url?.includes('/results') &&
url?.split('/')[2].split('?')[0].slice(-1) === 's'
);
}

newPage(oldUrl: string, newUrl: string) {
// Check if both urls are on the results page (tab change)
if (this.isResultPage(oldUrl) && this.isResultPage(newUrl)) {
return false;
// Check deepest locations without query params
} else if (
oldUrl?.split('/').slice(-1)[0].split('?')[0] ===
newUrl.split('/').slice(-1)[0].split('?')[0]
) {
return false;
// Same for fragments
} else if (
oldUrl?.split('/').slice(-1)[0].split('#')[0] ===
newUrl.split('/').slice(-1)[0].split('#')[0]
) {
return false;
// Otherwise new page
} else {
return true;
}
}

constructor(
library: FaIconLibrary,
router: Router,
viewportScroller: ViewportScroller,
private historyService: HistoryService,
private tabChangeService: TabChangeService
) {
console.log('PortalModule HERE!');

this.startPage = router.parseUrl(router.url).queryParams.page || 1;

// Scroll to top of page
// Timeout value of 0 helps Firefox to scroll
const scrollToTop = () => {
console.log("scrollToTop");

setTimeout(() => viewportScroller.scrollToPosition([0, 0]), 0);
};

// Used to prevent scroll to top when filters are selected
this.routeSub = router.events
.pipe(filter((e: Event): e is Scroll => e instanceof Scroll))
.subscribe((e) => {
console.log("routeSub fires");

const currentUrl = e.routerEvent.url;
const history = this.historyService.history;
const resultPages = tabChangeService.tabData
.map((tab) => tab.link)
.filter((item) => item);

// Trigger new page so first tab focuses skip links
const prevPageLocation = history[history.length - 2];
const currentPageLocation = currentUrl;
if (this.newPage(prevPageLocation, currentPageLocation)) {
this.tabChangeService.triggerNewPage();
}

// Check that route is in results and not in single result
if (
currentUrl.includes('/results') &&
!resultPages.some((item) =>
currentUrl.includes(`/${item.slice(0, -1)}/`)
)
) {
const targetPage = +router.parseUrl(currentUrl).queryParams.page || 1;
// Different page or coming from different route
if (
this.startPage !== targetPage ||
!history[history.length - 2]?.includes('/results')
) {
scrollToTop();
}
this.startPage = targetPage;

// Similar to /results but for /funding-calls
} else if (currentUrl.includes('/funding-calls')) {
const targetPage = +router.parseUrl(currentUrl).queryParams.page || 1;
// Different page or coming from different route
if (
this.startPage !== targetPage ||
!history[history.length - 2]?.includes('/funding-calls')
) {
scrollToTop();
}
this.startPage = targetPage;
} else if (currentUrl.includes('/science-research-figures')) {
// scroll to top only in single figure view
if (!history[history.length - 2]?.includes('figures/s')) {
scrollToTop();
}
if (!currentUrl.includes('filter')) {
scrollToTop();
}
} else {
scrollToTop();
}
});

console.log("Adding global icons");
// Add global icons
library.addIcons(faExternalLinkAlt as any, faInfoCircle as any);
}

ngOnDestroy(): void {
this.routeSub?.unsubscribe();
}
}
export class PortalModule {}
135 changes: 135 additions & 0 deletions src/app/portal/services/mystery.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { Event, Router, Scroll } from '@angular/router';
import { ViewportScroller } from '@angular/common';
import { HistoryService } from '@portal/services/history.service';
import { TabChangeService } from '@portal/services/tab-change.service';
import { filter } from 'rxjs/operators';
import { faExternalLinkAlt, faInfoCircle } from '@fortawesome/free-solid-svg-icons';

@Injectable({
providedIn: 'root'
})
export class MysteryService implements OnDestroy {
startPage;
routeSub: Subscription;

isResultPage(url: string) {
// Check if the page is on results, and that the tabname ends with 's' (not single result)
return (
url?.includes('/results') &&
url?.split('/')[2].split('?')[0].slice(-1) === 's'
);
}

newPage(oldUrl: string, newUrl: string) {
// Check if both urls are on the results page (tab change)
if (this.isResultPage(oldUrl) && this.isResultPage(newUrl)) {
return false;
// Check deepest locations without query params
} else if (
oldUrl?.split('/').slice(-1)[0].split('?')[0] ===
newUrl.split('/').slice(-1)[0].split('?')[0]
) {
return false;
// Same for fragments
} else if (
oldUrl?.split('/').slice(-1)[0].split('#')[0] ===
newUrl.split('/').slice(-1)[0].split('#')[0]
) {
return false;
// Otherwise new page
} else {
return true;
}
}

constructor(
library: FaIconLibrary,
router: Router,
viewportScroller: ViewportScroller,
private historyService: HistoryService,
private tabChangeService: TabChangeService
) {
console.log('XXX MysteryService HERE!');

this.startPage = router.parseUrl(router.url).queryParams.page || 1;

// Scroll to top of page
// Timeout value of 0 helps Firefox to scroll
const scrollToTop = () => {
console.log("XXX scrollToTop");

setTimeout(() => viewportScroller.scrollToPosition([0, 0]), 0);
};

// Used to prevent scroll to top when filters are selected
this.routeSub = router.events
.pipe(filter((e: Event): e is Scroll => e instanceof Scroll))
.subscribe((e) => {
console.log("XXX routeSub fires");

const currentUrl = e.routerEvent.url;
const history = this.historyService.history;
const resultPages = tabChangeService.tabData
.map((tab) => tab.link)
.filter((item) => item);

// Trigger new page so first tab focuses skip links
const prevPageLocation = history[history.length - 2];
const currentPageLocation = currentUrl;
if (this.newPage(prevPageLocation, currentPageLocation)) {
this.tabChangeService.triggerNewPage();
}

// Check that route is in results and not in single result
if (
currentUrl.includes('/results') &&
!resultPages.some((item) =>
currentUrl.includes(`/${item.slice(0, -1)}/`)
)
) {
const targetPage = +router.parseUrl(currentUrl).queryParams.page || 1;
// Different page or coming from different route
if (
this.startPage !== targetPage ||
!history[history.length - 2]?.includes('/results')
) {
scrollToTop();
}
this.startPage = targetPage;

// Similar to /results but for /funding-calls
} else if (currentUrl.includes('/funding-calls')) {
const targetPage = +router.parseUrl(currentUrl).queryParams.page || 1;
// Different page or coming from different route
if (
this.startPage !== targetPage ||
!history[history.length - 2]?.includes('/funding-calls')
) {
scrollToTop();
}
this.startPage = targetPage;
} else if (currentUrl.includes('/science-research-figures')) {
// scroll to top only in single figure view
if (!history[history.length - 2]?.includes('figures/s')) {
scrollToTop();
}
if (!currentUrl.includes('filter')) {
scrollToTop();
}
} else {
scrollToTop();
}
});

console.log("XXX Adding global icons");
// Add global icons
library.addIcons(faExternalLinkAlt as any, faInfoCircle as any);
}

ngOnDestroy(): void {
this.routeSub?.unsubscribe();
}
}
Loading

0 comments on commit c39c9db

Please sign in to comment.