diff --git a/monitor/methodology/methodology.module.ts b/monitor/methodology/methodology.module.ts index 76d6e1a5..d9af4bfd 100644 --- a/monitor/methodology/methodology.module.ts +++ b/monitor/methodology/methodology.module.ts @@ -1,7 +1,6 @@ import {NgModule} from "@angular/core"; import {CommonModule} from "@angular/common"; import {TerminologyComponent} from "./terminology.component"; -import {SeeHowItWorksComponent} from "./see-how-it-works.component"; import {MethodolocigalApproachComponent} from "./methodological-approach.component"; import {RouterModule} from "@angular/router"; import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard"; @@ -15,7 +14,7 @@ import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module"; import {HelperModule} from "../../utils/helper/helper.module"; @NgModule({ - declarations: [TerminologyComponent, SeeHowItWorksComponent, MethodolocigalApproachComponent], + declarations: [TerminologyComponent, MethodolocigalApproachComponent], imports: [CommonModule, RouterModule.forChild([ { path: '', @@ -26,11 +25,6 @@ import {HelperModule} from "../../utils/helper/helper.module"; path: 'terminology', component: TerminologyComponent, canDeactivate: [PreviousRouteRecorder] - }, - { - path: 'how', - component: SeeHowItWorksComponent, - canDeactivate: [PreviousRouteRecorder] }, { path: 'methodological-approach', @@ -38,7 +32,7 @@ import {HelperModule} from "../../utils/helper/helper.module"; canDeactivate: [PreviousRouteRecorder] } ]), PageContentModule, HowModule, IconsModule, BreadcrumbsModule, SliderTabsModule, HelperModule], - exports: [TerminologyComponent, SeeHowItWorksComponent, MethodolocigalApproachComponent] + exports: [TerminologyComponent, MethodolocigalApproachComponent] }) export class MethodologyModule { constructor(private iconsService: IconsService) { diff --git a/monitor/methodology/see-how-it-works.component.ts b/monitor/methodology/see-how-it-works.component.ts deleted file mode 100644 index 3cb69d56..00000000 --- a/monitor/methodology/see-how-it-works.component.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {Component, OnDestroy, OnInit} from "@angular/core"; -import {Subscription} from "rxjs"; -import {Meta, Title} from "@angular/platform-browser"; -import {ActivatedRoute, Router} from "@angular/router"; -import {Stakeholder} from "../entities/stakeholder"; -import {OpenaireEntities} from "../../utils/properties/searchFields"; -import {SEOService} from "../../sharedComponents/SEO/SEO.service"; -import {properties} from "../../../../environments/environment"; -import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component"; - -@Component({ - selector: 'see-how-it-works', - template: ` -
-
- -
-
-
-
-

- Inclusion, transparency,
quality, state of the art
technology. -

-
-

Our methodological approach is based on the following operational quality - criteria:

-
    -
  • Openness and transparency: Methodological assumptions are openly and - clearly presented. -
  • -
  • Coverage and accuracy: As detailed in graph.openaire.eu - multiple data sources are ingested in the OpenAIRE research graph for coverage to the fullest extent - possible, in order to provide meaningful indicators. -
  • -
  • Clarity and replicability: We describe our construction methodology in - detail, so that - it can be verified and used by the scholarly communication community to create ongoing updates to our - proposed statistics and indicators. -
  • -
  • Readiness and timeliness: The methodology is built around - well-established open databases - and already tested knowledge extraction technologies - natural language processing (NLP)/machine-learning - (ML) - using operational - workflows in OpenAIRE to warrant timely results. -
  • -
  • Trust and robustness: Our methodology also strives to be reliable, - robust, and aligned - to other assessment methods so that it can be operationalized, used and reused, in conjunction with other - assessment methods. -
  • -
-
The text above is modified from this report (DOI: 10.2777/268348). -
-
-
-

Step-by-step

- -
-
-
- ` -}) -export class SeeHowItWorksComponent implements OnInit, OnDestroy { - public stakeholder: Stakeholder; - public tab: 'entities' | 'attributes' = 'entities'; - private subscriptions: any[] = []; - public openaireEntities = OpenaireEntities; - public breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'Resources - See how it works', keepFormat: true}]; - - constructor(private seoService: SEOService, - private meta: Meta, - private router: Router, - private route: ActivatedRoute, - private title: Title) { - } - - ngOnInit() { - this.subscriptions.push(this.route.params.subscribe(params => { - const description = "Monitor | See how it works"; - const title = "Monitor | See how it works"; - this.metaTags(title, description); - this.breadcrumbs[0].route = '/' + (params['stakeholder']?params['stakeholder']:''); - this.breadcrumbs[0].name = (params['stakeholder']?'dashboard':'home'); - })); - } - - ngOnDestroy() { - this.subscriptions.forEach(subscription => { - if (subscription instanceof Subscription) { - subscription.unsubscribe(); - } - }); - } - - metaTags(title, description) { - const url = properties.domain + properties.baseLink + this.router.url; - this.seoService.createLinkForCanonicalURL(url, false); - this.meta.updateTag({content: url}, "property='og:url'"); - this.meta.updateTag({content: description}, "name='description'"); - this.meta.updateTag({content: description}, "property='og:description'"); - this.meta.updateTag({content: title}, "property='og:title'"); - this.title.setTitle(title); - } -} diff --git a/monitor/services/resources.service.ts b/monitor/services/resources.service.ts index bb10767e..8352bd0e 100644 --- a/monitor/services/resources.service.ts +++ b/monitor/services/resources.service.ts @@ -30,12 +30,12 @@ export class ResourcesService { let items = [ new MenuItem("methodology", "Methodology", "", "", false, [], null, {}, null, null, null, null, '_self'), - ResourcesService.setLink(new MenuItem("methodology", "Terminology and construction", + ResourcesService.setLink(new MenuItem("methodological-approach", "Methodological Approach", "", "", false, [], null, {}, null, null, null, null, '_self'), - prefix + "/methodology/terminology", portal), - ResourcesService.setLink(new MenuItem("methodology", "See how it works", + prefix + "/methodology/methodological-approach", portal), + ResourcesService.setLink(new MenuItem("terminology", "Terminology and construction", "", "", false, [], null, {}, null, null, null, null, '_self'), - prefix + "/methodology/how", portal)]; + prefix + "/methodology/terminology", portal)]; items.push(new MenuItem("indicators-page", "Indicators", "", "", false, [], null, {})); items.push(ResourcesService.setLink(new MenuItem("indicator-themes", "Indicator Themes", diff --git a/sharedComponents/tabs/slider-tabs.component.ts b/sharedComponents/tabs/slider-tabs.component.ts index cd69e003..dbf79a17 100644 --- a/sharedComponents/tabs/slider-tabs.component.ts +++ b/sharedComponents/tabs/slider-tabs.component.ts @@ -18,46 +18,47 @@ declare var UIkit; @Component({ selector: 'slider-tabs', template: ` -
-
-
`, }) export class SliderTabsComponent implements AfterViewInit, OnDestroy { - //TODO now it works only for scrollable, to be extended + //TODO now it works only for scrollable and static, to be extended for dynamic /** - * Type of tabs: Static = Uikit tabs with @connect class, Dynamic = Active is defined by tabComponent.active input, + * Type of tabs: Static = Uikit tabs with @connect class or selector, Dynamic = Active is defined by tabComponent.active input, * Scrollable = Active is defined by the active fragment of URL and position of scroll * */ @Input() public type: 'static' | 'dynamic' | 'scrollable' = 'static'; /** - * Connect class in static type. Default: uk-switcher + * Connect selector in static type. Default: .uk-switcher * */ @Input() - public connect = 'uk-switcher'; + public connect = '.uk-switcher'; /** * Threshold between 0.0 to 1.0 for Intersection Observer * */ @@ -68,23 +69,24 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { * */ @Input() public position: 'horizontal' | 'left' | 'right' = 'horizontal'; - /** - * Tabs flex position: Left is the default. - * */ - @Input() - public flexPosition: 'center' | 'left' | 'right' = 'left'; + /** + * Tabs flex position: Left is the default. + * */ + @Input() + public flexPosition: 'center' | 'left' | 'right' = 'left'; /** * Tabs custom class * */ @Input() public customClass: string; @ContentChildren(SliderTabComponent) tabs: QueryList; + @ViewChild('sliderElement') sliderElement: ElementRef; @ViewChild('tabsElement') tabsElement: ElementRef; /** * Notify regarding new active element * */ @Output() activeEmitter: EventEmitter = new EventEmitter(); - public init: boolean = false; + private activeIndex: number = 0; private subscriptions: any[] = []; private observer: IntersectionObserver; private timeout: Timeout; @@ -97,15 +99,20 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { ngAfterViewInit() { if (typeof document !== 'undefined' && this.tabs.length > 0) { setTimeout(() => { - if(this.position === 'horizontal') { - let slider = UIkit.slider(this.tabsElement.nativeElement, {finite: true}); + if (this.position === 'horizontal') { + let slider = UIkit.slider(this.sliderElement.nativeElement, {finite: true}); slider.clsActive = 'uk-slider-active'; slider.updateActiveClasses(); - this.init = true; slider.slides.forEach(item => { item.classList.remove('uk-active'); }); - if (this.type === 'scrollable') { + if (this.type === 'static') { + let tabs = UIkit.tab(this.tabsElement.nativeElement, {connect: this.connect}); + tabs.show(this.activeIndex); + if (this.connect.includes('#')) { + this.scrollToStart(); + } + } else if (this.type === 'scrollable') { this.scrollable(slider); } } else { @@ -115,10 +122,20 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { } } + private scrollToStart() { + this.subscriptions.push(UIkit.util.on(this.connect, 'shown', (event): void => { + let index = event.detail[0].index(); + if (index !== this.activeIndex) { + this.activeIndex = index; + this.router.navigate(['./'], {relativeTo: this.route, fragment: this.connect.replace('#', '')}); + } + })); + } + private scrollable(slider = null) { this.activeFragment(this.route.snapshot.fragment, slider); this.subscriptions.push(this.route.fragment.subscribe(fragment => { - this.activeFragment(fragment,slider); + this.activeFragment(fragment, slider); })); this.setObserver(); } @@ -156,7 +173,7 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { if (fragment) { index = this.tabs.toArray().findIndex(item => item.id == fragment); } - if(slider) { + if (slider) { slider.show(index); } this.tabs.forEach((tab, i) => { @@ -174,6 +191,8 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { this.subscriptions.forEach(subscription => { if (subscription instanceof Subscription) { subscription.unsubscribe(); + } else if (subscription instanceof Function) { + subscription(); } }); if (this.observer) { diff --git a/utils/smooth-scroll.ts b/utils/smooth-scroll.ts index 78cb44e0..5663d6ca 100644 --- a/utils/smooth-scroll.ts +++ b/utils/smooth-scroll.ts @@ -21,6 +21,7 @@ export class SmoothScroll { this.currentComponent = event.snapshot.component.name; } } else if (event instanceof NavigationEnd) { + let headerOffset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height')) + 35; if(!this.router.getCurrentNavigation().extras?.state?.disableScroll) { if (this.interval) { clearInterval(this.interval); @@ -38,7 +39,7 @@ export class SmoothScroll { if (this.interval) { clearInterval(this.interval); } - const yOffset = -100 - this.extraOffset; + const yOffset = -headerOffset - this.extraOffset; let position = 0; let interval = setInterval(() => { if (position !== element.getBoundingClientRect().top) {