From 1093027ca192040019424e3fc98ee02c9e136f20 Mon Sep 17 00:00:00 2001 From: Alex Martzios Date: Thu, 16 Feb 2023 12:59:18 +0200 Subject: [PATCH] general fixes for all landing page types, create new fos/sdg selection components for user feedback --- .../fos-selection.component.html | 136 +++++++++++++ .../fos-selection.component.less | 0 fos/fos-selection/fos-selection.component.ts | 183 ++++++++++++++++++ fos/fos-selection/fos-selection.module.ts | 24 +++ .../dataProvider/dataProvider.component.html | 30 ++- .../landing-utils/availableOn.component.ts | 11 +- landingPages/landing-utils/fos.component.ts | 6 +- .../resultLandingUtils.module.ts | 12 +- landingPages/landing-utils/sdg.component.ts | 6 +- .../landing-utils/showPublisher.component.ts | 4 +- .../organization/organization.component.html | 2 +- landingPages/project/project.component.html | 30 ++- .../result/resultLanding.component.html | 49 +++-- .../result/resultLanding.component.ts | 23 +++ .../sdg-selection.component.html | 30 +++ .../sdg-selection.component.less | 0 sdg/sdg-selection/sdg-selection.component.ts | 38 ++++ sdg/sdg-selection/sdg-selection.module.ts | 25 +++ 18 files changed, 561 insertions(+), 48 deletions(-) create mode 100644 fos/fos-selection/fos-selection.component.html create mode 100644 fos/fos-selection/fos-selection.component.less create mode 100644 fos/fos-selection/fos-selection.component.ts create mode 100644 fos/fos-selection/fos-selection.module.ts create mode 100644 sdg/sdg-selection/sdg-selection.component.html create mode 100644 sdg/sdg-selection/sdg-selection.component.less create mode 100644 sdg/sdg-selection/sdg-selection.component.ts create mode 100644 sdg/sdg-selection/sdg-selection.module.ts diff --git a/fos/fos-selection/fos-selection.component.html b/fos/fos-selection/fos-selection.component.html new file mode 100644 index 00000000..62a78150 --- /dev/null +++ b/fos/fos-selection/fos-selection.component.html @@ -0,0 +1,136 @@ +
+ +
+
+
+
+
+
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+ + +
+
+
+
+ +
+
+

+ {{item.id}} + +

+
+
+
+
+

+ {{child.id}} + +

+
+ + +
+
+
+
+
+
+ +
+
+

+ +

+
+
+

+ +

+
+ + +
+
+
+
+
+
+
+
+ +
+

No results were found.

+
+
+
+
+
\ No newline at end of file diff --git a/fos/fos-selection/fos-selection.component.less b/fos/fos-selection/fos-selection.component.less new file mode 100644 index 00000000..e69de29b diff --git a/fos/fos-selection/fos-selection.component.ts b/fos/fos-selection/fos-selection.component.ts new file mode 100644 index 00000000..4045f12a --- /dev/null +++ b/fos/fos-selection/fos-selection.component.ts @@ -0,0 +1,183 @@ +import {HttpClient} from "@angular/common/http"; +import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from "@angular/core"; +import {FormBuilder, FormControl} from "@angular/forms"; +import { ActivatedRoute, Router } from "@angular/router"; +import {Subscription} from "rxjs"; +import {EnvProperties} from "../../utils/properties/env-properties"; +import {StringUtils} from "../../utils/string-utils.class"; +import {debounceTime, distinctUntilChanged} from "rxjs/operators"; +import Timeout = NodeJS.Timeout; + +declare var UIkit; + +@Component({ + selector: 'fos-selection', + templateUrl: 'fos-selection.component.html', + styleUrls: ['fos-selection.component.less'] +}) +export class FosSelectionComponent { + @Input() properties: EnvProperties; + @Input() subjects: string[]; + + public loading: boolean; + public fos: any[] = []; + public fosOptions: string[] = []; + public activeSection: string; + + public keywordControl: FormControl; + public keyword: string; + + public viewResults = []; + + public result = []; + + private subscriptions: Subscription[] = []; + private observer: IntersectionObserver; + private timeout: Timeout; + @ViewChild('tabs') tabs: ElementRef; + public sliderInit: boolean = false; + + constructor( + private httpClient: HttpClient, + private fb: FormBuilder, + private cdr: ChangeDetectorRef, + private route: ActivatedRoute, + private _router: Router + ) {} + + ngOnInit() { + this.loading = true; + this.httpClient.get(this.properties.domain+'/assets/common-assets/vocabulary/fos.json').subscribe(data => { + this.fos = data['fos']; + this.convertFosToOptions(); + if (typeof document !== 'undefined') { + setTimeout(()=> { + let slider = UIkit.slider(this.tabs.nativeElement); + slider.clsActive = 'uk-slider-active'; + slider.updateActiveClasses(); + this.sliderInit = true; + slider.slides.forEach(item => { + item.classList.remove('uk-active'); + }); + if (this.route.snapshot.fragment) { + this.activeSection = this.route.snapshot.fragment; + let i = this.fos.findIndex(item => item.id == this.route.snapshot.fragment); + slider.show(i); + } else { + this.activeSection = this.fos[0].id; + } + this.cdr.detectChanges(); + }); + } + this.subscriptions.push(this.route.fragment.subscribe(fragment => { + if(fragment) { + this.activeSection = fragment; + if(this.tabs) { + let slider = UIkit.slider(this.tabs.nativeElement); + let i = this.fos.findIndex(item => item.id == fragment); + slider.show(i); + } + } else { + this.activeSection = this.fos[0].id; + } + })); + this.keywordControl = this.fb.control(''); + this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => { + this.keyword = value; + this.findMatches(this.keyword); + if (typeof document !== 'undefined') { + setTimeout(() => { + this.setObserver(); + }); + } + })); + }); + this.loading = false; + } + + ngOnDestroy() { + for (let sub of this.subscriptions) { + sub.unsubscribe(); + } + if(this.observer) { + this.observer.disconnect(); + } + } + + private setObserver() { + if(this.observer) { + this.observer.disconnect(); + } + this.observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if(entry.isIntersecting) { + if(this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(() => { + this._router.navigate(['./'], {fragment: entry.target.id, relativeTo: this.route, state: {disableScroll: true}}); + }, 200); + } + }); + }, {threshold: 0.25, rootMargin: '-100px'}); + this.fos.forEach(fos => { + let element = document.getElementById(fos.id); + if(element) { + this.observer.observe(element); + } + }); + } + + convertFosToOptions() { + this.fosOptions = []; + this.fos.forEach(fos => { + this.fosOptions.push(fos.id); + if(fos.children) { + fos.children.forEach(child => { + this.fosOptions.push(child.id); + if(child.children) { + child.children.forEach(child2 => { + this.fosOptions.push(child2.id); + }); + } + }); + } + }); + } + + findMatches(value: string) { + this.viewResults = JSON.parse(JSON.stringify(this.fos)); + let matchLevel1: boolean = false; + let matchLevel2: boolean = false; + // 1st level search + if(this.viewResults.length) { + this.viewResults = this.viewResults.filter(item => { + matchLevel1 = !!item.id.includes(value?.toLowerCase()); + // // 2nd level search + if(item.children?.length && !matchLevel1) { + item.children = item.children.filter(subItem => { + matchLevel2 = !!subItem.id.includes(value?.toLowerCase()); + // 3rd level search + if(subItem.children?.length && !matchLevel2) { + subItem.children = subItem.children.filter(subSubItem => subSubItem.id.includes(value?.toLowerCase())); + } + return subItem.children?.length > 0 || matchLevel2; + }); + } + return item.children?.length > 0; + }); + } + } + + highlightKeyword(name) { + if(name.includes(this.keyword.toLowerCase())) { + return name.replace(new RegExp(this.keyword, "gi"), (matchedValue) => `${matchedValue}`); + } else { + return name; + } + } + + public urlEncodeAndQuote(str: string): string { + return StringUtils.quote(StringUtils.URIEncode(str)); + } +} \ No newline at end of file diff --git a/fos/fos-selection/fos-selection.module.ts b/fos/fos-selection/fos-selection.module.ts new file mode 100644 index 00000000..7766379f --- /dev/null +++ b/fos/fos-selection/fos-selection.module.ts @@ -0,0 +1,24 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {FormsModule} from "@angular/forms"; +import {LoadingModule} from "../../utils/loading/loading.module"; + +// import {FosSelectionComponent} from './fos-selection.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LoadingModule + ], + declarations: [ + // FosSelectionComponent + ], + providers: [ + + ], + exports: [ + // FosSelectionComponent + ] +}) +export class FosSelectionModule { + +} \ No newline at end of file diff --git a/landingPages/dataProvider/dataProvider.component.html b/landingPages/dataProvider/dataProvider.component.html index c1084fa7..4deaaf6d 100644 --- a/landingPages/dataProvider/dataProvider.component.html +++ b/landingPages/dataProvider/dataProvider.component.html @@ -75,7 +75,7 @@
-
-
+
@@ -195,8 +195,10 @@
Views
-
{{totalDownloads | number}}
-
{{totalViews | number}}
+
{{formatNumber(totalDownloads)}}
+
{{formatNumber(totalViews)}}
@@ -500,8 +502,10 @@ Downloads - - {{totalDownloads | number}} + + {{formatNumber(totalDownloads)}} @@ -511,8 +515,10 @@ Views - - {{totalViews | number}} + + {{formatNumber(totalViews)}} @@ -526,11 +532,15 @@
-
{{formatNumber(totalDownloads)}}
+
{{formatNumber(totalDownloads)}}
Downloads
-
{{formatNumber(totalViews)}}
+
{{formatNumber(totalViews)}}
Views
diff --git a/landingPages/landing-utils/availableOn.component.ts b/landingPages/landing-utils/availableOn.component.ts index edab04cb..9aac2952 100644 --- a/landingPages/landing-utils/availableOn.component.ts +++ b/landingPages/landing-utils/availableOn.component.ts @@ -9,14 +9,17 @@ declare var UIkit; template: `
- + + Source: - {{sliceString(availableOn[0].downloadNames.join("; "), 20)}} - + + {{sliceString(availableOn[0].downloadNames.join("; "), 20)}} + + diff --git a/landingPages/landing-utils/fos.component.ts b/landingPages/landing-utils/fos.component.ts index 0e893ba0..708a9d41 100644 --- a/landingPages/landing-utils/fos.component.ts +++ b/landingPages/landing-utils/fos.component.ts @@ -10,13 +10,13 @@ import {StringUtils} from "../../utils/string-utils.class";
Beta
- + {{title}} {{title}} + (click)="viewAllClick();" class="view-more-less-link uk-text-truncate"> View all & suggest {{title}} + (click)="viewAllClick();" class="view-more-less-link uk-text-truncate"> View all & suggest Feedback @@ -61,7 +61,7 @@ export class SdgComponent { @Output() viewAllClicked = new EventEmitter(); @Output() feedbackClicked = new EventEmitter(); public lessBtn: boolean = false; - public threshold: number = 4; + public threshold: number = 2; public routerHelper: RouterHelper = new RouterHelper(); public properties = properties; public title: string = "SDGs"; @@ -71,7 +71,7 @@ export class SdgComponent { // this.viewAll = true; // this.lessBtn = true; // } else { - this.viewAll = true; + // this.viewAll = true; this.viewAllClicked.emit('sdg'); // } } diff --git a/landingPages/landing-utils/showPublisher.component.ts b/landingPages/landing-utils/showPublisher.component.ts index 5aaf623c..b480018f 100644 --- a/landingPages/landing-utils/showPublisher.component.ts +++ b/landingPages/landing-utils/showPublisher.component.ts @@ -9,7 +9,7 @@ import {EnvProperties} from "../../utils/properties/env-properties"; - + {{journal['journal']}} , @@ -68,7 +68,7 @@ import {EnvProperties} from "../../utils/properties/env-properties"; - {{publisher}} + {{publisher}} ` }) diff --git a/landingPages/organization/organization.component.html b/landingPages/organization/organization.component.html index 182e7bb5..7f1fd9b7 100644 --- a/landingPages/organization/organization.component.html +++ b/landingPages/organization/organization.component.html @@ -75,7 +75,7 @@
-
+
diff --git a/landingPages/project/project.component.html b/landingPages/project/project.component.html index 47104db2..d16da1e2 100644 --- a/landingPages/project/project.component.html +++ b/landingPages/project/project.component.html @@ -113,11 +113,13 @@
-
-
+
@@ -344,8 +346,10 @@
Views
-
{{totalDownloads | number}}
-
{{totalViews | number}}
+
{{formatNumber(totalDownloads)}}
+
{{formatNumber(totalViews)}}
@@ -533,8 +537,10 @@ Downloads - - {{totalDownloads | number}} + + {{formatNumber(totalDownloads)}} @@ -544,8 +550,10 @@ Views - - {{totalViews | number}} + + {{formatNumber(totalViews)}} @@ -559,11 +567,13 @@
-
{{formatNumber(totalDownloads)}}
+
{{formatNumber(totalDownloads)}}
Downloads
-
{{formatNumber(totalViews)}}
+
{{formatNumber(totalViews)}}
Views
diff --git a/landingPages/result/resultLanding.component.html b/landingPages/result/resultLanding.component.html index 1fd5e19a..143fc0bf 100644 --- a/landingPages/result/resultLanding.component.html +++ b/landingPages/result/resultLanding.component.html @@ -109,7 +109,7 @@
- +
- +
@@ -972,6 +985,18 @@
+ + + + + +
+ +
+
+
  • diff --git a/landingPages/result/resultLanding.component.ts b/landingPages/result/resultLanding.component.ts index 20d77189..c8545786 100644 --- a/landingPages/result/resultLanding.component.ts +++ b/landingPages/result/resultLanding.component.ts @@ -142,6 +142,9 @@ export class ResultLandingComponent { // public shouldSticky: boolean = true; public viewAll: string = ""; + @ViewChild("sdgSelectionModal") sdgSelectionModal; + @ViewChild("fosSelectionModal") fosSelectionModal; + public noCommunities: boolean = false; public rightSidebarOffcanvasClicked: boolean = false; @@ -924,4 +927,24 @@ export class ResultLandingComponent { let formatted = NumberUtils.roundNumber(+num); return formatted.number + formatted.size; } + + public openSelectionModal(value: string) { + if(value == 'sdg') { + this.openSdgSelectionModal(); + } else if(value == 'fos') { + this.openFosSelectionModal(); + } + } + + private openSdgSelectionModal() { + this.sdgSelectionModal.cancelButton = false; + this.sdgSelectionModal.alertTitle = "Please select SDGs that are the most relevant for this publication."; + this.sdgSelectionModal.open(); + } + + private openFosSelectionModal() { + this.fosSelectionModal.cancelButton = false; + this.fosSelectionModal.alertTitle = "Please select FOS that are the most relevant for this publication."; + this.fosSelectionModal.open(); + } } diff --git a/sdg/sdg-selection/sdg-selection.component.html b/sdg/sdg-selection/sdg-selection.component.html new file mode 100644 index 00000000..ec6f5e64 --- /dev/null +++ b/sdg/sdg-selection/sdg-selection.component.html @@ -0,0 +1,30 @@ +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/sdg/sdg-selection/sdg-selection.component.less b/sdg/sdg-selection/sdg-selection.component.less new file mode 100644 index 00000000..e69de29b diff --git a/sdg/sdg-selection/sdg-selection.component.ts b/sdg/sdg-selection/sdg-selection.component.ts new file mode 100644 index 00000000..94c9c9dd --- /dev/null +++ b/sdg/sdg-selection/sdg-selection.component.ts @@ -0,0 +1,38 @@ +import {HttpClient} from "@angular/common/http"; +import {Component, Input} from "@angular/core"; +import {EnvProperties} from "../../utils/properties/env-properties"; + +@Component({ + selector: 'sdg-selection', + templateUrl: 'sdg-selection.component.html', + styleUrls: ['sdg-selection.component.less'] +}) +export class SdgSelectionComponent { + @Input() properties: EnvProperties; + @Input() subjects: string[]; + + public loading: boolean; + public sdgs: any = []; + + constructor( + private httpClient: HttpClient + ) {} + + ngOnInit() { + this.loading = true; + this.httpClient.get(this.properties.domain+'/assets/common-assets/vocabulary/sdg.json').subscribe(data => { + this.sdgs = data['sdg']; + console.log(this.sdgs); + this.sdgs.push({code: '18', id: 'No SDGs are relevant for this publication', label: 'No SDG relevant', html: 'No SDG relevant'}) + }); + this.loading = false; + } + + public get firstColumn() { + return this.sdgs.slice(0, this.sdgs.length/2); + } + + public get secondColumn() { + return this.sdgs.slice(this.sdgs.length/2, this.sdgs.length); + } +} \ No newline at end of file diff --git a/sdg/sdg-selection/sdg-selection.module.ts b/sdg/sdg-selection/sdg-selection.module.ts new file mode 100644 index 00000000..96f5d189 --- /dev/null +++ b/sdg/sdg-selection/sdg-selection.module.ts @@ -0,0 +1,25 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {FormsModule} from "@angular/forms"; +import {InputModule} from "../../sharedComponents/input/input.module"; +import {LoadingModule} from "../../utils/loading/loading.module"; + +// import {SdgSelectionComponent} from './sdg-selection.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LoadingModule, InputModule + ], + declarations: [ + // SdgSelectionComponent + ], + providers: [ + + ], + exports: [ + // SdgSelectionComponent + ] +}) +export class SdgSelectionModule { + +} \ No newline at end of file