[Library | explore-redesign]: Fixes on FoS and SDGs suggest modal (checked existing subjects, added loading) - In FoS fixed scrolling, search and final response of selected fields.

1. composer.ts & resultLanding.component.ts: Removed "and Technology" from "Fields of Science" typename.
2. resultLanding.component.html: Bind (suggestClicked) to <fos> instead of (feedbackClicked).
3. input.component.ts: [Bug fix] Added check in "filter()" method if option.label.
4. sdg-selection.component.ts: [Bug fix] Set this.loading = false; inside subscribe.
5. fos.component.ts: In title, updated FOS to FoS.
6. sdg-fos-suggest.module.ts: Imported LoadingModule.
7. sdg-fos-suggest.component.ts: Show loading when sending email | Do not initialize <sdg-selection> and <fos-selection> before subjects have value (this way inputs of existing fos/sdgs are checked).
8. fos-selection.component.ts:
   a. Added @Input() inModal: boolean = false; to set activeSection, when inModal, instead of navigating with fragment.
   b. [Bug fix] Set this.loading = false; inside subscribe.
   c. Call this.setObserver(); both in ngOnInit and when keyword changes.
   d. Updated threshold of observer from 0.25 to 0.1 (large FoS categories were never triggered on scrolling, because less than 25% of their content was visible).
   e. Updated fosOptions to Map<string, boolean> to track easily checked inputs and updated getSelectedSubjects() accordingly.
9. fos-selection.component.html: In search-input of keyword no options are needed | Updated ngModel of checkbox inputs.
10. cache-interceptor.service.ts: Added check if (!properties.useLongCache) to skip cache.
This commit is contained in:
Konstantinos Triantafyllou 2023-02-20 20:54:26 +02:00 committed by konstantina.galouni
parent f17b25d66f
commit fc9e77b887
12 changed files with 65 additions and 41 deletions

View File

@ -49,6 +49,11 @@ export class CacheInterceptorService implements HttpInterceptor {
}
public checkForCachedRequests(url){
// Do not call cache when it is not enabled at all.
// This property is not correctly used here. A new property should be introduced. For now it is ok.
if (!properties.useLongCache) {
return false;
}
if(url.indexOf("refine=true") !== -1 || url.indexOf("/count?format=json") !== -1 || url.indexOf("relresulttype%3Dpublication") !== -1) {
return this.cachingRequests.some(partUrl => (url.indexOf(partUrl) !== -1));
}

View File

@ -4,7 +4,7 @@
<div *ngIf="!loading">
<div class="uk-visible@m">
<div #searchElement class="uk-flex uk-flex-right uk-margin-small-bottom">
<div search-input [searchControl]="keywordControl" [options]="fosOptions" iconPosition="left" placeholder="Write a key word to filter the content"
<div search-input [searchControl]="keywordControl" iconPosition="left" placeholder="Write a key word to filter the content"
searchInputClass="border-bottom" class="uk-width-large"></div>
</div>
</div>
@ -30,7 +30,7 @@
<div class="uk-width-1-1 uk-hidden@m">
<div class="uk-sticky uk-blur-background" uk-sticky>
<div class="uk-flex uk-flex-center uk-margin-small-bottom">
<div search-input [searchControl]="keywordControl" [options]="fosOptions" iconPosition="left" placeholder="Write a key word to filter the content"
<div search-input [searchControl]="keywordControl" iconPosition="left" placeholder="Write a key word to filter the content"
searchInputClass="border-bottom" class="uk-width-large"></div>
</div>
<div #tabs class="uk-slider uk-position-relative" uk-slider="finite: true">
@ -77,7 +77,7 @@
</h3>
<div *ngFor="let subChild of child.children" class="uk-margin-xsmall-bottom uk-text-truncate">
<label [class.uk-text-bolder]="subjects?.includes(subChild.id)">
<input [(ngModel)]="subChild.checked"
<input [ngModel]="fosOptions.get(subChild.id)" (ngModelChange)="fosOptions.set(subChild.id, $event)"
type="checkbox" class="uk-checkbox uk-margin-small-right">
<span [title]="subChild.id">{{subChild.id}}</span>
</label>
@ -110,10 +110,10 @@
</a> -->
</h3>
<div *ngFor="let subSubItem of subItem.children" class="uk-margin-xsmall-bottom uk-text-truncate">
<label>
<input [checked]="subjects.includes(subSubItem.id)"
<label [class.uk-text-bolder]="subjects?.includes(subSubItem.id)">
<input [ngModel]="fosOptions.get(subSubItem.id)" (ngModelChange)="fosOptions.set(subSubItem.id, $event)"
type="checkbox" class="uk-checkbox uk-margin-small-right">
<span [innerHTML]="highlightKeyword(subSubItem.id)" [title]="subChild.id"></span>
<span [innerHTML]="highlightKeyword(subSubItem.id)" [title]="subSubItem.id"></span>
</label>
<!-- <a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subSubItem.id)}"
class="uk-link-text" [innerHTML]="highlightKeyword(subSubItem.id)">

View File

@ -20,12 +20,13 @@ declare var UIkit;
export class FosSelectionComponent {
public properties: EnvProperties = properties;
@Input() subjects: string[];
@Input() inModal: boolean = false;
@Input() contentHeight: number = 0;
@ViewChild("searchElement") searchElement: ElementRef;
public loading: boolean;
public fos: any[] = [];
public fosOptions: any = [];
public fosOptions: Map<string, boolean>;
public activeSection: string;
public keywordControl: FormControl;
@ -54,6 +55,7 @@ export class FosSelectionComponent {
this.httpClient.get(this.properties.domain+'/assets/common-assets/vocabulary/fos.json').subscribe(data => {
this.fos = data['fos'];
this.convertFosToOptions();
this.convertFosToOptions();
if (typeof document !== 'undefined') {
setTimeout(()=> {
let slider = UIkit.slider(this.tabs.nativeElement);
@ -70,7 +72,9 @@ export class FosSelectionComponent {
} else {
this.activeSection = this.fos[0].id;
}
this.cdr.detectChanges();
this.setObserver();
this.cdr.detectChanges();
});
}
this.subscriptions.push(this.route.fragment.subscribe(fragment => {
@ -95,8 +99,8 @@ export class FosSelectionComponent {
});
}
}));
});
this.loading = false;
this.loading = false;
});
}
ngOnDestroy() {
@ -119,11 +123,19 @@ export class FosSelectionComponent {
clearTimeout(this.timeout);
}
this.timeout = setTimeout(() => {
this._router.navigate(['./'], {fragment: entry.target.id, relativeTo: this.route, state: {disableScroll: true}});
if(!this.inModal) {
this._router.navigate(['./'], {
fragment: entry.target.id,
relativeTo: this.route,
state: {disableScroll: true}
});
} else {
this.activeSection = entry.target.id;
}
}, 200);
}
});
}, {threshold: 0.25, rootMargin: '-100px'});
}, {threshold: 0.1, rootMargin: '-100px'});
this.fos.forEach(fos => {
let element = document.getElementById(fos.id);
if(element) {
@ -133,15 +145,15 @@ export class FosSelectionComponent {
}
convertFosToOptions() {
this.fosOptions = [];
this.fosOptions = new Map<string, boolean>();
this.fos.forEach(fos => {
this.fosOptions.push({id: fos.id, checked: false});
this.fosOptions.set(fos.id, false);
if(fos.children) {
fos.children.forEach(child => {
this.fosOptions.push({id: child.id, checked: false});
if(child.children) {
this.fosOptions.set(child.id, false);
if(child.children) {
child.children.forEach(child2 => {
this.fosOptions.push({id: child2.id, checked: this.subjects?.includes(child2.id)});
this.fosOptions.set(child2.id, this.subjects?.includes(child2.id));
});
}
});
@ -191,7 +203,10 @@ export class FosSelectionComponent {
}
public getSelectedSubjects() {
return this.fosOptions.filter(sub => sub.checked == true);
let checked = Array.from(this.fosOptions, function (entry) {
return {id: entry[0], checked: entry[1]};
});
return checked.filter(sub => sub.checked == true);
}
get calculatedHeight(): number {

View File

@ -172,7 +172,7 @@ import {Organization, Project} from "../../utils/result-preview/result-preview";
<!-- Projects -->
<ng-container *ngIf="projects && projects.length > 0">
<span class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
<span uk-tooltip="Project" *ngFor="let project of projects.slice(0,10) let i=index">
<span uk-tooltip="Project" *ngFor="let project of projects.slice(0,3) let i=index">
<span class="space">
{{project.funderShortname ? project.funderShortname : project.funderName}}
</span>
@ -183,25 +183,25 @@ import {Organization, Project} from "../../utils/result-preview/result-preview";
<span *ngIf="project.code"> ({{project.code}})</span>
<span *ngIf="i < projects.length-1">, </span>
</span>
<span *ngIf="projects.length > 10">...</span>
<span *ngIf="projects.length > 3">...</span>
</ng-container>
<!-- Organizations -->
<ng-container *ngIf="organizations && organizations.length > 0">
<span class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
<span uk-tooltip="Partner" *ngFor="let organization of organizations.slice(0,10) let i=index">
<span uk-tooltip="Partner" *ngFor="let organization of organizations.slice(0,3) let i=index">
<span class="space">{{organization.name}}</span>
<span *ngIf="(i < organizations.length-1) && (i < 9)">,</span>
<span *ngIf="i < organizations.length-1">, </span>
</span>
<span *ngIf="organizations.length > 10">...</span>
<span *ngIf="organizations.length > 3">...</span>
</ng-container>
<!-- Subjects -->
<ng-container *ngIf="subjects && subjects.length > 0">
<span class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
<span uk-tooltip="Subject" *ngFor="let subject of subjects.slice(0,10) let i = index">
<span uk-tooltip="Subject" *ngFor="let subject of subjects.slice(0,3) let i = index">
<span class="space">{{subject}}</span>
<span>{{(i < (subjects.slice(0, 10).length - 1)) ? "," : ""}}</span>
<span *ngIf="i < subjects.length - 1">, </span>
</span>
<span *ngIf="subjects.length > 10">...</span>
<span *ngIf="subjects.length > 3">...</span>
</ng-container>
<ng-container *ngIf="provenanceAction">
<span class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>

View File

@ -38,7 +38,7 @@ import {StringUtils} from "../../utils/string-utils.class";
<div class="uk-grid uk-grid-small uk-grid-divider" uk-grid>
<div class="uk-width-1-4 uk-text-meta">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
Fields of Science (FOS)
Fields of Science (FoS)
</div>
<div class="uk-width-expand">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">

View File

@ -15,10 +15,10 @@ import {StringUtils} from "../../../utils/string-utils.class";
template: `
<modal-alert #selectionModal [large]="true" (alertOutput)="modalOutput()" (cancelOutput)="modalCancel()"
[okDisabled]="!sent && !selectionStep1 && (form.invalid || sending)">
<sdg-selection *ngIf="subjectType == 'sdg'" #selection [class.uk-hidden]="!selectionStep1"
<sdg-selection *ngIf="subjects && subjectType == 'sdg'" #selection [class.uk-hidden]="!selectionStep1"
[subjects]="subjects" [entityType]="entityType"></sdg-selection>
<fos-selection *ngIf="subjectType == 'fos'" #selection [class.uk-hidden]="!selectionStep1"
[subjects]="subjects" [contentHeight]="selectionModal.bodyHeight"></fos-selection>
<fos-selection *ngIf="subjects && subjectType == 'fos'" #selection [class.uk-hidden]="!selectionStep1"
[subjects]="subjects" [contentHeight]="selectionModal.bodyHeight" [inModal]="true"></fos-selection>
<div [class.uk-hidden]="selectionStep1">
<div class="uk-flex uk-flex-column uk-flex-middle">
<ng-container *ngIf="!sent && !error">
@ -29,8 +29,9 @@ import {StringUtils} from "../../../utils/string-utils.class";
<span note>(Optional)</span>
</div>
<div>
<re-captcha (resolved)="handleRecaptcha($event)" [siteKey]="properties.reCaptchaSiteKey">
</re-captcha>
<re-captcha (resolved)="handleRecaptcha($event)" [siteKey]="properties.reCaptchaSiteKey"
[ngClass]="sending ? 'uk-hidden':''"></re-captcha>
<loading [ngClass]="sending ? '':'uk-hidden'"></loading>
</div>
</ng-container>
<ng-container *ngIf="sent">
@ -120,6 +121,7 @@ export class SdgFosSuggestComponent {
this.selectionModal.alertTitle = "Please send your feedback on most relevant Fields of Science for this "+this.getEntityName(this.entityType)+".";
}
} else {
this.sending = true;
// email functionality
this.form.get("subjects").setValue(this.selection.getSelectedSubjects().map(subject => subject.id));
this.subscriptions.push(this.emailService.contact(this.properties,
@ -142,7 +144,7 @@ export class SdgFosSuggestComponent {
this.selectionModal.previousButton = false;
this.selectionModal.stayOpen = false;
}
// this.sending = false;
this.sending = false;
}, error => {
console.log(error);
this.error = true;

View File

@ -8,10 +8,11 @@ import {InputModule} from "../../../sharedComponents/input/input.module";
import {SdgFosSuggestComponent} from "./sdg-fos-suggest.component";
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
import {IconsModule} from "../../../utils/icons/icons.module";
import {LoadingModule} from "../../../utils/loading/loading.module";
@NgModule({
imports: [
CommonModule, FormsModule, InputModule, SdgSelectionModule, FosSelectionModule, RecaptchaModule, AlertModalModule, IconsModule
CommonModule, FormsModule, InputModule, SdgSelectionModule, FosSelectionModule, RecaptchaModule, AlertModalModule, IconsModule, LoadingModule
],
declarations: [
SdgFosSuggestComponent

View File

@ -719,7 +719,7 @@
</div>
<!-- FOS -->
<div *ngIf="resultLandingInfo.fos && resultLandingInfo.fos.length > 0 && !viewAllMobile" class="uk-margin-small-top">
<fos [subjects]="resultLandingInfo.fos" (feedbackClicked)="feedbackClicked('Fields of Science and Technology (FOS)')"
<fos [subjects]="resultLandingInfo.fos" (suggestClicked)="suggestMobileClicked($event)"
(viewAllClicked)="viewAllMobile=$event; openFsModal(fosFsModal, 'Fields of Science (FoS)')"></fos>
</div>
</div>
@ -871,7 +871,7 @@
<fs-modal #fosFsModal *ngIf="isMobile" [classTitle]="'uk-background-primary-opacity'" (cancelEmitter)="fosFsModalCancelled()">
<ng-container *ngIf="resultLandingInfo.fos && resultLandingInfo.fos.length > 0">
<fos *ngIf="viewAllMobile=='fos'" [subjects]="resultLandingInfo.fos" [viewAll]="true"(viewAllClicked)="viewAllMobile=$event"></fos>
<fos *ngIf="viewAllMobile=='fos'" [subjects]="resultLandingInfo.fos" [viewAll]="true" (suggestClicked)="suggestMobileClicked($event)"></fos>
<sdg-fos-suggest *ngIf="viewAllMobile=='fosSuggest'" #sdgFosSuggest [title]="resultLandingInfo.title" [entityType]="resultLandingInfo.resultType"></sdg-fos-suggest>
</ng-container>
</fs-modal>

View File

@ -116,7 +116,7 @@ export class ResultLandingComponent {
'Title', 'Authors', 'Access rights',
'Publisher information', 'Funding Information',
'Persistent identifiers', 'Sustainable Development Goals (SDGs)',
'Fields of Science and Technology (FOS)', 'Other'];
'Fields of Science (FoS)', 'Other'];
public pidsArrayString: string = "";
public identifier: Identifier;
@ -993,6 +993,7 @@ export class ResultLandingComponent {
this.sdgFosSuggest.subjects=this.resultLandingInfo.fos;
this.sdgFosSuggest.subjectType="fos";
}
this.cdr.detectChanges();
this.sdgFosSuggest.openSelectionModal();
}

View File

@ -28,8 +28,8 @@ export class SdgSelectionComponent {
this.sdgs.push({code: element.code, id: element.id, label: element.label, html: element.html, checked: this.subjects?.includes(element.id)});
});
this.sdgs.push({code: '18', id: 'No SDGs are relevant for this ' + this.getEntityName(this.entityType), label: 'Not relevant', html: 'Not relevant', checked: false});
});
this.loading = false;
this.loading = false;
});
}
public get firstColumn() {

View File

@ -476,7 +476,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
return (this.showOptionsOnEmpty) ? options : [];
}
const filterValue = value.toString().toLowerCase();
options = options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
options = options.filter(option => (option.label && option.label.toLowerCase().indexOf(filterValue) != -1));
this.selectedIndex = options.findIndex(option => option.value === this.formControl.value);
if (this.selectedIndex === -1) {
this.selectedIndex = 0;

View File

@ -142,7 +142,7 @@ export class Composer {
if(subjectType == "sdg") {
typeName = "Sustainable Development Goals (SDGs)";
} else {
typeName = "Fields of Science and Technology (FoS)";
typeName = "Fields of Science (FoS)";
}
let email: Email = new Email();