Merge remote-tracking branch 'origin/master' into angular-14

This commit is contained in:
Konstantinos Triantafyllou 2022-10-24 16:37:14 +03:00
commit cdffb018b6
5 changed files with 53 additions and 146 deletions

View File

@ -1,7 +1,6 @@
import {NgModule} from "@angular/core"; import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common"; import {CommonModule} from "@angular/common";
import {TerminologyComponent} from "./terminology.component"; import {TerminologyComponent} from "./terminology.component";
import {SeeHowItWorksComponent} from "./see-how-it-works.component";
import {MethodolocigalApproachComponent} from "./methodological-approach.component"; import {MethodolocigalApproachComponent} from "./methodological-approach.component";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard"; 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"; import {HelperModule} from "../../utils/helper/helper.module";
@NgModule({ @NgModule({
declarations: [TerminologyComponent, SeeHowItWorksComponent, MethodolocigalApproachComponent], declarations: [TerminologyComponent, MethodolocigalApproachComponent],
imports: [CommonModule, RouterModule.forChild([ imports: [CommonModule, RouterModule.forChild([
{ {
path: '', path: '',
@ -27,11 +26,6 @@ import {HelperModule} from "../../utils/helper/helper.module";
path: 'terminology', path: 'terminology',
component: TerminologyComponent, component: TerminologyComponent,
canDeactivate: [PreviousRouteRecorder] canDeactivate: [PreviousRouteRecorder]
},
{
path: 'how',
component: SeeHowItWorksComponent,
canDeactivate: [PreviousRouteRecorder]
}, },
{ {
path: 'methodological-approach', path: 'methodological-approach',
@ -39,7 +33,7 @@ import {HelperModule} from "../../utils/helper/helper.module";
canDeactivate: [PreviousRouteRecorder] canDeactivate: [PreviousRouteRecorder]
} }
]), PageContentModule, HowModule, IconsModule, BreadcrumbsModule, SliderTabsModule, HelperModule], ]), PageContentModule, HowModule, IconsModule, BreadcrumbsModule, SliderTabsModule, HelperModule],
exports: [TerminologyComponent, SeeHowItWorksComponent, MethodolocigalApproachComponent] exports: [TerminologyComponent, MethodolocigalApproachComponent]
}) })
export class MethodologyModule { export class MethodologyModule {
constructor(private iconsService: IconsService) { constructor(private iconsService: IconsService) {

View File

@ -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: `
<div class="uk-container uk-container-large uk-section uk-section-small uk-padding-remove-bottom">
<div class="uk-padding-small uk-padding-remove-horizontal">
<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>
</div>
</div>
<div class="uk-section" uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-fade; delay: 250">
<div id="how" class="uk-container uk-container-large">
<h2 class="uk-h1" uk-scrollspy-class>
Inclusion, transparency, <br> quality, state of the art <br> technology<span class="uk-text-primary">.</span>
</h2>
<div class="uk-margin-large-top uk-card uk-card-default uk-card-body" uk-scrollspy-class>
<p class="uk-margin-top">Our methodological approach is based on the following operational quality
criteria:</p>
<ul>
<li><span class="uk-text-bold">Openness and transparency:</span> Methodological assumptions are openly and
clearly presented.
</li>
<li><span class="uk-text-bold">Coverage and accuracy:</span> As detailed in <a
href="https://graph.openaire.eu/" target="_blank">graph.openaire.eu</a>
multiple data sources are ingested in the OpenAIRE research graph for coverage to the fullest extent
possible, in order to provide meaningful indicators.
</li>
<li><span class="uk-text-bold">Clarity and replicability:</span> 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.
</li>
<li><span class="uk-text-bold">Readiness and timeliness:</span> 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.
</li>
<li><span class="uk-text-bold">Trust and robustness:</span> 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.
</li>
</ul>
<div class="uk-text-small uk-text-italic uk-text-right">The text above is modified from <a
href="https://op.europa.eu/en/publication-detail/-/publication/56cc104f-0ebb-11ec-b771-01aa75ed71a1"
target="_blank">this report</a> (DOI: 10.2777/268348).
</div>
</div>
<div class="uk-margin-large-top uk-padding-small" uk-scrollspy-class>
<h3 class="uk-h4">Step-by-step</h3>
<how></how>
</div>
</div>
</div>
`
})
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);
}
}

View File

@ -30,12 +30,12 @@ export class ResourcesService {
let items = [ let items = [
new MenuItem("methodology", "Methodology", "", "", false, [], new MenuItem("methodology", "Methodology", "", "", false, [],
null, {}, null, null, null, null, '_self'), 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'), "", "", false, [], null, {}, null, null, null, null, '_self'),
prefix + "/methodology/terminology", portal), prefix + "/methodology/methodological-approach", portal),
ResourcesService.setLink(new MenuItem("methodology", "See how it works", ResourcesService.setLink(new MenuItem("terminology", "Terminology and construction",
"", "", false, [], null, {}, null, null, null, null, '_self'), "", "", false, [], null, {}, null, null, null, null, '_self'),
prefix + "/methodology/how", portal)]; prefix + "/methodology/terminology", portal)];
items.push(new MenuItem("indicators-page", "Indicators", items.push(new MenuItem("indicators-page", "Indicators",
"", "", false, [], null, {})); "", "", false, [], null, {}));
items.push(ResourcesService.setLink(new MenuItem("indicator-themes", "Indicator Themes", items.push(ResourcesService.setLink(new MenuItem("indicator-themes", "Indicator Themes",

View File

@ -18,46 +18,47 @@ declare var UIkit;
@Component({ @Component({
selector: 'slider-tabs', selector: 'slider-tabs',
template: ` template: `
<div #tabsElement class="uk-position-relative" [class.uk-slider]="position === 'horizontal'" <div #sliderElement class="uk-position-relative" [class.uk-slider]="position === 'horizontal'"
[ngClass]="customClass"> [ngClass]="customClass">
<div [class.uk-slider-container-tabs]="position === 'horizontal'"> <div [class.uk-slider-container-tabs]="position === 'horizontal'">
<ul class="uk-tab" [class.uk-flex-nowrap]="position === 'horizontal'" <ul #tabsElement class="uk-tab" [class.uk-flex-nowrap]="position === 'horizontal'"
[class.uk-slider-items]="position === 'horizontal'" [class.uk-slider-items]="position === 'horizontal'"
[class.uk-tab-left]="position === 'left'" [class.uk-tab-right]="position === 'right'" [class.uk-tab-left]="position === 'left'" [class.uk-tab-right]="position === 'right'"
[attr.uk-tab]="type === 'static'?('connect: .' + connect):null" [attr.uk-tab]="type === 'static'?('connect:' + connect):null"
[ngClass]="'uk-flex-' + flexPosition"> [ngClass]="'uk-flex-' + flexPosition">
<ng-container *ngIf="type === 'static'">
<li *ngFor="let tab of tabs.toArray()" class="uk-text-capitalize">
<a>{{tab.title}}</a>
</li>
</ng-container>
<ng-container *ngIf="type === 'scrollable'"> <ng-container *ngIf="type === 'scrollable'">
<li *ngFor="let tab of tabs.toArray()" class="uk-text-capitalize" [class.uk-active]="tab.active"> <li *ngFor="let tab of tabs.toArray()" class="uk-text-capitalize" [class.uk-active]="tab.active">
<a routerLink="./" [fragment]="tab.id">{{tab.title}}</a> <a routerLink="./" [fragment]="tab.id">{{tab.title}}</a>
</li> </li>
</ng-container>
<ng-container *ngIf="type === 'static'">
<li *ngFor="let tab of tabs.toArray()" class="uk-text-capitalize">
<a>{{tab.title}}</a>
</li>
</ng-container> </ng-container>
</ul> </ul>
</div> </div>
<a *ngIf="position === 'horizontal'" class="uk-position-center-left uk-blur-background" uk-slider-item="previous"><span <a *ngIf="position === 'horizontal'" class="uk-position-center-left uk-blur-background" uk-slider-item="previous"><span
uk-icon="chevron-left"></span></a> uk-icon="chevron-left"></span></a>
<a *ngIf="position === 'horizontal'" class="uk-position-center-right uk-blur-background" uk-slider-item="next"><span <a *ngIf="position === 'horizontal'" class="uk-position-center-right uk-blur-background"
uk-slider-item="next"><span
uk-icon="chevron-right"></span></a> uk-icon="chevron-right"></span></a>
</div> </div>
`, `,
}) })
export class SliderTabsComponent implements AfterViewInit, OnDestroy { 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 * Scrollable = Active is defined by the active fragment of URL and position of scroll
* */ * */
@Input() @Input()
public type: 'static' | 'dynamic' | 'scrollable' = 'static'; public type: 'static' | 'dynamic' | 'scrollable' = 'static';
/** /**
* Connect class in static type. Default: uk-switcher * Connect selector in static type. Default: .uk-switcher
* */ * */
@Input() @Input()
public connect = 'uk-switcher'; public connect = '.uk-switcher';
/** /**
* Threshold between 0.0 to 1.0 for Intersection Observer * Threshold between 0.0 to 1.0 for Intersection Observer
* */ * */
@ -68,23 +69,24 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy {
* */ * */
@Input() @Input()
public position: 'horizontal' | 'left' | 'right' = 'horizontal'; public position: 'horizontal' | 'left' | 'right' = 'horizontal';
/** /**
* Tabs flex position: Left is the default. * Tabs flex position: Left is the default.
* */ * */
@Input() @Input()
public flexPosition: 'center' | 'left' | 'right' = 'left'; public flexPosition: 'center' | 'left' | 'right' = 'left';
/** /**
* Tabs custom class * Tabs custom class
* */ * */
@Input() @Input()
public customClass: string; public customClass: string;
@ContentChildren(SliderTabComponent) tabs: QueryList<SliderTabComponent>; @ContentChildren(SliderTabComponent) tabs: QueryList<SliderTabComponent>;
@ViewChild('sliderElement') sliderElement: ElementRef;
@ViewChild('tabsElement') tabsElement: ElementRef; @ViewChild('tabsElement') tabsElement: ElementRef;
/** /**
* Notify regarding new active element * Notify regarding new active element
* */ * */
@Output() activeEmitter: EventEmitter<string> = new EventEmitter<string>(); @Output() activeEmitter: EventEmitter<string> = new EventEmitter<string>();
public init: boolean = false; private activeIndex: number = 0;
private subscriptions: any[] = []; private subscriptions: any[] = [];
private observer: IntersectionObserver; private observer: IntersectionObserver;
private timeout: Timeout; private timeout: Timeout;
@ -97,15 +99,20 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy {
ngAfterViewInit() { ngAfterViewInit() {
if (typeof document !== 'undefined' && this.tabs.length > 0) { if (typeof document !== 'undefined' && this.tabs.length > 0) {
setTimeout(() => { setTimeout(() => {
if(this.position === 'horizontal') { if (this.position === 'horizontal') {
let slider = UIkit.slider(this.tabsElement.nativeElement, {finite: true}); let slider = UIkit.slider(this.sliderElement.nativeElement, {finite: true});
slider.clsActive = 'uk-slider-active'; slider.clsActive = 'uk-slider-active';
slider.updateActiveClasses(); slider.updateActiveClasses();
this.init = true;
slider.slides.forEach(item => { slider.slides.forEach(item => {
item.classList.remove('uk-active'); 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); this.scrollable(slider);
} }
} else { } 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) { private scrollable(slider = null) {
this.activeFragment(this.route.snapshot.fragment, slider); this.activeFragment(this.route.snapshot.fragment, slider);
this.subscriptions.push(this.route.fragment.subscribe(fragment => { this.subscriptions.push(this.route.fragment.subscribe(fragment => {
this.activeFragment(fragment,slider); this.activeFragment(fragment, slider);
})); }));
this.setObserver(); this.setObserver();
} }
@ -156,7 +173,7 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy {
if (fragment) { if (fragment) {
index = this.tabs.toArray().findIndex(item => item.id == fragment); index = this.tabs.toArray().findIndex(item => item.id == fragment);
} }
if(slider) { if (slider) {
slider.show(index); slider.show(index);
} }
this.tabs.forEach((tab, i) => { this.tabs.forEach((tab, i) => {
@ -174,6 +191,8 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy {
this.subscriptions.forEach(subscription => { this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) { if (subscription instanceof Subscription) {
subscription.unsubscribe(); subscription.unsubscribe();
} else if (subscription instanceof Function) {
subscription();
} }
}); });
if (this.observer) { if (this.observer) {

View File

@ -21,6 +21,7 @@ export class SmoothScroll {
this.currentComponent = event.snapshot.component.name; this.currentComponent = event.snapshot.component.name;
} }
} else if (event instanceof NavigationEnd) { } 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.router.getCurrentNavigation().extras?.state?.disableScroll) {
if (this.interval) { if (this.interval) {
clearInterval(this.interval); clearInterval(this.interval);
@ -38,7 +39,7 @@ export class SmoothScroll {
if (this.interval) { if (this.interval) {
clearInterval(this.interval); clearInterval(this.interval);
} }
const yOffset = -100 - this.extraOffset; const yOffset = -headerOffset - this.extraOffset;
let position = 0; let position = 0;
let interval = setInterval(() => { let interval = setInterval(() => {
if (position !== element.getBoundingClientRect().top) { if (position !== element.getBoundingClientRect().top) {