Fix mobile-dropdown open-close. Fix input in mobile. Add mobile-dropdown in availableOn, fundedBy, showAuthors.

This commit is contained in:
Konstantinos Triantafyllou 2023-07-25 19:09:09 +03:00
parent 6ecde003af
commit 86ba54c7d0
14 changed files with 171 additions and 537 deletions

View File

@ -5,7 +5,6 @@ import { RouterModule } from '@angular/router';
import {IFrameModule} from '../../utils/iframe.module';
import {ErrorMessagesModule} from '../../utils/errorMessages.module';
import {MetricsModule} from '../landing-utils/metrics/metrics.module';
import {LandingModule} from '../landing-utils/landing.module';
import {PagingModule} from '../../utils/paging.module';
@ -41,7 +40,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod
@NgModule({
imports:
[CommonModule, FormsModule, RouterModule,
IFrameModule, ErrorMessagesModule, MetricsModule, LandingModule,
IFrameModule, ErrorMessagesModule, LandingModule,
DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule,
PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule,
LandingHeaderModule, AlertModalModule, NoLoadPaging, FeedbackModule,

View File

@ -17,7 +17,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
uk-tooltip [title]="getAccessLabel(availableOn[0].accessRight)">
<icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
</span>
<ng-container *ngIf="!(isMobile && usedBy == 'landing')">
<ng-container *ngIf="!isMobile">
<a uk-tooltip="Source" target="_blank"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
@ -32,18 +32,21 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</div>
</ng-container>
<ng-container *ngIf="(isMobile && usedBy == 'landing')">
<a class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link" (click)="openAvailableListFsModal()">
<span uk-tooltip="Source">{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<ng-container *ngIf="isMobile">
<a #toggle class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<icon [flex]="true" ratio="1.5" name="arrow_right"></icon>
</span>
</a>
<fs-modal #availableListFsModal classTitle="uk-tile-default uk-border-bottom">
<div class="uk-text-small download-drop">
<mobile-dropdown [toggle]="toggle">
<div class="uk-text-emphasis uk-text-bolder uk-text-center uk-padding-small uk-padding-remove-vertical uk-text-uppercase">
Sources
</div>
<div class="uk-text-small download-drop uk-padding uk-padding-remove-horizontal">
<ng-container *ngTemplateOutlet="availableOnList"></ng-container>
</div>
</fs-modal>
</mobile-dropdown>
</ng-container>
</ng-container>
</div>
@ -97,7 +100,6 @@ export class AvailableOnComponent {
/** @deprecated */
@Output() viewAllClicked = new EventEmitter();
@ViewChild("dropElement") dropElement: ElementRef;
@ViewChild("availableListFsModal") availableListFsModal: FullScreenModalComponent;
public threshold: number = 1;
public dataProviderUrl = properties.searchLinkToDataProvider.split('?')[0];
public title: string = "Download from";
@ -125,12 +127,6 @@ export class AvailableOnComponent {
return StringUtils.sliceString(str, size)
}
public openAvailableListFsModal() {
this.availableListFsModal.title = "Sources";
this.availableListFsModal.okButton = false;
this.availableListFsModal.open();
}
public getAccessLabel(accessRight) : string {
if(accessRight) {
return (accessRight + (accessRight.toLowerCase().endsWith(" access") ? "" : " access"));

View File

@ -38,11 +38,12 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span class="uk-text-emphasis">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</span>
<icon name="info" visuallyHidden="info" [type]="'outlined'" class="uk-link"></icon>
<div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
<a #toggle><icon name="info" visuallyHidden="info" [type]="'outlined'"></icon></a>
<mobile-dropdown [toggle]="toggle">
<div class="uk-margin-remove-top">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
</mobile-dropdown>
</div>
</div>

View File

@ -1,48 +0,0 @@
.metrics {
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
position: relative;
display: inline-block;
.uk-text-primary {
color: @global-primary-background !important;
}
.uk-text-background {
background-image: @global-primary-gradient;
}
.uk-dropdown {
&::before {
position: absolute;
left: 0;
transform: translateX(-100%);
top: 14px;
width: 0;
height: 0;
content: '';
border-left: 21px solid transparent;
border-right: 21px solid @global-border;
border-bottom: 21px solid transparent;
border-top: 21px solid transparent;
}
&::after {
position: absolute;
left: 0;
transform: translateX(-100%);
top: 15px;
width: 0;
height: 0;
content: '';
border-left: 20px solid transparent;
border-right: 20px solid @global-background;
border-bottom: 20px solid transparent;
border-top: 20px solid transparent;
}
}
.m-badge img {
width: 35px;
}
}

View File

@ -1,331 +0,0 @@
import {Component, Input, Output, EventEmitter, ChangeDetectorRef} from '@angular/core';
import {Metrics} from '../../../utils/entities/metrics';
import {MetricsService} from '../../../services/metrics.service';
import {ErrorCodes} from '../../../utils/properties/errorCodes';
import {Subscription, zip} from 'rxjs';
import {EnvProperties} from '../../../utils/properties/env-properties';
import {ClickEvent} from "../../../utils/click/click-outside-or-esc.directive";
import {NumberUtils} from "../../../utils/number-utils.class";
import {OpenaireEntities} from "../../../utils/properties/searchFields";
import {StringUtils} from "../../../utils/string-utils.class";
import {properties} from "../../../../../environments/environment";
import {RouterHelper} from "../../../utils/routerHelper.class";
@Component({
selector: 'metrics',
template: `
<div *ngIf="metrics && (pageViews >0 || metrics.totalViews > 0|| metrics.totalDownloads >0)" class="metrics">
<a class="m-badge uk-link-reset uk-display-block" (click)="clickedMetrics()">
<img src="assets/common-assets/logo-small-usage-counts.png" loading="lazy" alt="usage counts">
<div class="uk-margin-xsmall-top uk-text-primary uk-text-small uk-text-bold uk-text-center">
<ng-container *ngIf="isNumberLarge(total, true); else notFormattedTotal">{{formatNumber(total)}}</ng-container>
<ng-template #notFormattedTotal>{{total | number}}</ng-template>
</div>
</a>
<div class="uk-dropdown uk-background-default" uk-dropdown="pos: right-top; mode: click; offset: 30; animation: uk-animation-fade">
<div class="uk-padding-small uk-width-large@s uk-width-medium">
<div *ngIf="entityType == 'projects'" class="uk-alert uk-alert-primary uk-margin-small-bottom">
<span class="uk-text-center uk-text-small">{{openaireEntities.PROJECT}} metrics
are derived from aggregating individual {{openaireEntities.RESULTS}} metrics.
</span>
</div>
<div class="uk-child-width-1-3@m uk-grid-small uk-grid-divider uk-margin-top" uk-grid>
<div class="uk-text-center">
<div class="number uk-text-bold uk-text-background">
<ng-container *ngIf="metrics.totalDownloads == 0">-</ng-container>
<span *ngIf="metrics.totalDownloads > 0" [attr.uk-tooltip]="metrics.totalDownloads >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{metrics.totalDownloads | number}}">{{formatNumber(metrics.totalDownloads)}}</span>
<!-- <ng-container *ngIf="isNumberLarge(metrics.totalDownloads); else notFormattedDownloads">{{formatNumber(metrics.totalDownloads)}}</ng-container>-->
<!-- <ng-template #notFormattedDownloads>{{metrics.totalDownloads | number}}</ng-template>-->
</div>
<div>Downloads</div>
</div>
<div class="uk-text-center">
<div class="number uk-text-bold uk-text-background">
<ng-container *ngIf="pageViews == 0">-</ng-container>
<span *ngIf="pageViews > 0" [attr.uk-tooltip]="pageViews >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{pageViews | number}}">{{formatNumber(pageViews)}}</span>
<!-- <ng-container *ngIf="isNumberLarge(pageViews); else notFormattedPageviews">{{formatNumber(pageViews)}}</ng-container>-->
<!-- <ng-template #notFormattedPageviews>{{pageViews | number}}</ng-template>-->
</div>
<div>OpenAIRE views</div>
</div>
<div class="uk-text-center">
<div class="number uk-text-bold uk-text-background">
<ng-container *ngIf="metrics.totalViews == 0">-</ng-container>
<span *ngIf="metrics.totalViews > 0" [attr.uk-tooltip]="metrics.totalViews >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{metrics.totalViews | number}}">{{formatNumber(metrics.totalViews)}}</span>
<!-- <ng-container *ngIf="isNumberLarge(metrics.totalViews); else notFormattedTotalviews">{{formatNumber(metrics.totalViews)}}</ng-container>-->
<!-- <ng-template #notFormattedTotalviews>{{metrics.totalViews | number}}</ng-template> -->
</div>
<div>Total views</div>
</div>
</div>
<div class="uk-padding">
<div *ngIf="metricsClicked && (metrics.infos?.size > 0 || (metrics.totalViews > 0 && viewsFrameUrl) || (metrics.totalDownloads > 0 && downloadsFrameUrl))"
class="uk-position-relative uk-visible-toggle uk-slider uk-margin-small-top" tabIndex="1" uk-slider>
<div class="uk-slider-container">
<ul class="uk-slider-items uk-child-width-1-1">
<li *ngIf="metrics && metrics.infos.size > 0" class="uk-overflow-auto" style="height: 200px">
<table
class="uk-table uk-table-small uk-table-striped">
<thead>
<tr>
<th class="uk-text-center uk-text-bold">From</th>
<th class="uk-text-center uk-text-bold">Views</th>
<th class="uk-text-center uk-text-bold">Downloads</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let key of getKeys(metrics.infos)">
<td class="uk-width-1-3 uk-text-center uk-text-truncate" uk-tooltip [title]="metrics.infos.get(key).name">
<a [queryParams]="addEoscPrevInParams({datasourceId: metrics.infos.get(key).url})" [routerLink]="properties.searchLinkToDataProvider.split('?')[0]">
{{metrics.infos.get(key).name}}
</a>
</td>
<td class="uk-text-center">
<ng-container *ngIf="isNumberLarge(metrics.infos.get(key).numOfViews, true); else notFormattedNumViews">{{formatNumber(metrics.infos.get(key).numOfViews)}}</ng-container>
<ng-template #notFormattedNumViews>{{metrics.infos.get(key).numOfViews | number}}</ng-template>
<!-- <span *ngIf="metrics.infos.get(key).numOfViews > 0 && metrics.infos.get(key).openaireViews > 0">
( {{metrics.infos.get(key).openaireViews | number}} from OpenAIRE )
</span>-->
</td>
<td class="uk-text-center">
<ng-container *ngIf="isNumberLarge(metrics.infos.get(key).numOfDownloads, true); else notFormattedNumDownloads">{{formatNumber(metrics.infos.get(key).numOfDownloads)}}</ng-container>
<ng-template #notFormattedNumDownloads>{{metrics.infos.get(key).numOfDownloads | number}}</ng-template>
<!--<span *ngIf="metrics.infos.get(key).numOfDownloads > 0 && metrics.infos.get(key).openaireDownloads > 0">
( {{metrics.infos.get(key).openaireDownloads | number}} from OpenAIRE )
</span>-->
</td>
</tr>
</tbody>
</table>
</li>
<!-- remove check for datasources when with the new charts -->
<li *ngIf="metricsClicked && metrics.totalViews > 0 && viewsFrameUrl">
<i-frame [height]="200" [url]=viewsFrameUrl [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</li>
<li *ngIf="metricsClicked && metrics.totalDownloads > 0 && downloadsFrameUrl">
<i-frame [height]="200" [url]=downloadsFrameUrl [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</li>
</ul>
</div>
<a class="uk-position-center-left-out" uk-slider-item="previous"><span uk-icon="icon: chevron-left; ratio: 2"></span></a>
<a class="uk-position-center-right-out" uk-slider-item="next"><span uk-icon="icon: chevron-right; ratio: 2"></span></a>
</div>
</div>
<div class="uk-flex uk-flex-center uk-flex-middle">
<span class="uk-margin-small-right uk-text-small uk-text-meta">Powered by</span>
<a href="https://usagecounts.openaire.eu" target="_blank">
<img width="120" src="assets/common-assets/logo-large-usage-counts.png" loading="lazy" alt="usage counts">
</a>
</div>
</div>
</div>
</div>
`,
styleUrls: ['metrics.component.less']
})
export class MetricsComponent {
@Input() prevPath: string = "";
@Output() metricsResults = new EventEmitter();
@Input() id: string;
@Input() entityType: string;
@Input() entity: string;
//@Input() name: string = "";
@Input() pageViews: number = 0;
@Input() properties: EnvProperties;
@Input() shortView: boolean = false;
@Input() open = false;
@Input() viewsFrameUrl: string;
@Input() downloadsFrameUrl: string;
public metrics: Metrics;
public errorCodes: ErrorCodes;
private sub: Subscription;
private timeouts: any[] = [];
public metricsClicked: boolean = false;
public status: number;
public state: number = -1;
public openaireEntities = OpenaireEntities;
public routerHelper:RouterHelper = new RouterHelper();
constructor(private metricsService: MetricsService, private cdr: ChangeDetectorRef) {
}
ngOnInit() {
this.errorCodes = new ErrorCodes();
if (typeof document !== 'undefined') {
this.status = this.errorCodes.LOADING;
this.getMetrics();
}
}
ngOnDestroy() {
if(this.sub) {
this.sub.unsubscribe();
}
}
public get total(): number {
return +this.pageViews + +this.metrics.totalViews + +this.metrics.totalDownloads;
}
private getMetrics() {
//queries from old API - replaced with queries to the stats tool
/* this.sub = this.metricsService.getMetrics(this.id, this.entityType, this.properties).subscribe(
data => {
this.metrics = data;
this.cdr.detectChanges();
this.status = this.errorCodes.DONE;
this.metricsResults.emit({
totalViews: this.metrics.totalViews,
totalDownloads: this.metrics.totalDownloads,
pageViews: this.metrics.pageViews
});
},
err => {
if (err.status == '404') {
this.status = this.errorCodes.NOT_FOUND;
} else if (err.status == '500') {
this.status = this.errorCodes.ERROR;
} else {
this.status = this.errorCodes.NOT_AVAILABLE;
}
this.metricsResults.emit({
totalViews: 0,
totalDownloads: 0
});
}
);*/
let obs;
if (this.entityType == "results") {
obs = zip(this.metricsService.getMetricsNumber(this.id, "usagestats.results.views", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.results.downloads", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.results.views.openaire", this.properties),
this.metricsService.getMetricsNumbersByRepository(this.id, "usagestats.results.viewsdownloads.repository", this.properties)
);
} else if (this.entityType == "projects") {
obs = zip(this.metricsService.getMetricsNumber(this.id, "usagestats.projects.views", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.projects.downloads", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.projects.views.openaire", this.properties));
} else if (this.entityType == "datasources") {
obs = zip(this.metricsService.getMetricsNumber(this.id, "usagestats.views.repository.local", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.downloads.repository.local", this.properties),
this.metricsService.getMetricsNumber(this.id, "usagestats.views.openaire", this.properties),
// this.metricsService.getMetricsNumber(this.id, "usagestats.downloads.repository.openaire", this.properties)
);
}
this.sub = obs.subscribe(
data => {
this.metrics = new Metrics();
this.metrics.infos = new Map<string, { "name": string, "url": string, "numOfDownloads": string, "numOfViews": string, "openaireDownloads": string, "openaireViews": string }>();
this.metrics.totalViews = data[0] ? data[0] : 0;
this.metrics.totalDownloads = data[1] ? data[1] : 0;
this.metrics.pageViews = data[2] ? data[2] : 0;
this.metrics.infos = data[3] ? data[3] : 0;
this.cdr.detectChanges();
this.status = this.errorCodes.DONE;
this.metricsResults.emit({
totalViews: this.metrics.totalViews,
totalDownloads: this.metrics.totalDownloads,
pageViews: this.metrics.pageViews
});
},
err => {
if (err.status == '404') {
this.status = this.errorCodes.NOT_FOUND;
} else if (err.status == '500') {
this.status = this.errorCodes.ERROR;
} else {
this.status = this.errorCodes.NOT_AVAILABLE;
}
this.metricsResults.emit({
totalViews: 0,
totalDownloads: 0,
pageViews: 0
});
}
);
}
public close(event: ClickEvent) {
if(event.clicked && this.state !== -1) {
this.timeouts.forEach(timeout => {
clearTimeout(timeout);
});
this.state = -1;
this.timeouts = [];
}
}
public clickedMetrics() {
setTimeout( () => {
this.metricsClicked = true;
});
}
public toggle(event) {
this.metricsClicked = true;
event.stopPropagation();
if(this.state !== -1) {
this.timeouts.forEach(timeout => {
clearTimeout(timeout);
});
this.state = -1;
this.timeouts = [];
} else {
this.state++;
this.timeouts.push(setTimeout(() => {
this.state++;
this.timeouts.push(setTimeout(() => {
this.state++;
this.timeouts.push(setTimeout(() => {
this.state++;
this.timeouts.push(setTimeout(() => {
this.state++;
}, 400));
}, 800));
}, 300));
}, 100));
}
this.cdr.detectChanges();
}
public getKeys(map) {
return Array.from(map.keys());
}
public isNumberLarge(num: number | string, bigNum: boolean = false) {
let limit: number = bigNum ? 100000000 : 100000;
return (+num) >= limit;
}
public formatNumber(num: number | string) {
let formatted = NumberUtils.roundNumber(+num);
return formatted.number + formatted.size;
}
public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?");
obj = this.routerHelper.addQueryParam("return_path", splitted[0], obj);
if(splitted.length > 0) {
obj = this.routerHelper.addQueryParam("search_params", splitted[1], obj);
}
}
return obj;
}
}

View File

@ -1,29 +0,0 @@
/* This module contains all common components for all landing pages */
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {MetricsComponent} from './metrics.component';
import {MetricsService} from '../../../services/metrics.service';
import {ErrorMessagesModule} from '../../../utils/errorMessages.module';
import {IFrameModule} from "../../../utils/iframe.module";
import {IconsModule} from "../../../utils/icons/icons.module";
import {RouterModule} from "@angular/router";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, ErrorMessagesModule, IFrameModule, IconsModule
],
declarations: [
MetricsComponent
],
providers:[
MetricsService
],
exports: [
MetricsComponent
]
})
export class MetricsModule { }

View File

@ -21,12 +21,13 @@ import {EntityMetadataComponent} from "./entity-metadata.component";
import {IconsService} from "../../utils/icons/icons.service";
import {closed_access, open_access, unknown_access} from "../../utils/icons/icons";
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {MobileDropdownModule} from "../../utils/mobile-dropdown/mobile-dropdown.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule,
SearchInputModule, FullScreenModalModule
SearchInputModule, FullScreenModalModule, MobileDropdownModule
],
declarations: [
ShowIdentifiersComponent,ShowSubjectsComponent,

View File

@ -1,4 +1,3 @@
//import {MaterialModule} from '@angular/material';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
@ -10,8 +9,6 @@ import {ProjectServiceModule} from './projectService.module';
import {HtmlProjectReportService} from "../htmlProjectReport/htmlProjectReport.service";
import {ReportsServiceModule} from '../../services/reportsService.module';
import {SearchResearchResultsServiceModule} from '../../services/searchResearchResultsService.module';
import {MetricsModule} from '../landing-utils/metrics/metrics.module';
import {LandingModule} from '../landing-utils/landing.module';
import {LandingHeaderModule} from "../landing-utils/landing-header/landing-header.module";
@ -41,7 +38,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod
imports: [
CommonModule, FormsModule, RouterModule, LandingModule,
LoadingModalModule, AlertModalModule, ErrorMessagesModule,
IFrameModule, MetricsModule, ReportsServiceModule,
IFrameModule, ReportsServiceModule,
SearchResearchResultsServiceModule, ProjectServiceModule,
Schema2jsonldModule, SEOServiceModule, HelperModule,
LandingHeaderModule, MatSelectModule, FeedbackModule, AltMetricsModule,

View File

@ -3,8 +3,7 @@ import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {SharedModule} from '../../../openaireLibrary/shared/shared.module';
import {MetricsModule} from '../landing-utils/metrics/metrics.module';
import {SharedModule} from '../../shared/shared.module';
import {LandingModule} from '../landing-utils/landing.module';
import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module';
import {IFrameModule} from '../../utils/iframe.module';
@ -46,7 +45,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod
imports: [
CommonModule, FormsModule, LandingModule, SharedModule, RouterModule,
CiteThisModule, PagingModule, IFrameModule,
MetricsModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule,
AnnotationModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule,
OrcidModule, MatFormFieldModule, MatSelectModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule,

View File

@ -211,7 +211,7 @@ declare var UIkit;
</li>
</ul>
</div>
<mobile-dropdown *ngIf="mobile" #mobileDropdown>
<mobile-dropdown *ngIf="mobile && filteredOptions && filteredOptions.length > 0 && opened" #mobileDropdown>
<div *ngIf="placeholderInfo" class="uk-text-emphasis uk-text-bolder uk-text-center uk-padding-small uk-padding-remove-vertical uk-text-uppercase">
{{placeholderInfo.label}}
</div>

View File

@ -10,108 +10,129 @@ import {properties} from "../../../../environments/environment";
@Component({
selector: 'showAuthors',
template: `
<ng-template #author_template let-author="author" let-i="i" let-italic="italic">
<span *ngIf="isSticky || (!author.orcid && !author.orcid_pending) || !testBrowser" style="margin-right: 5px;"
<ng-template #author_template let-author="author" let-i="i" let-italic="italic">
<span *ngIf="isSticky || (!author.orcid && !author.orcid_pending) || !isBrowser" style="margin-right: 5px;"
[class.uk-text-italic]="italic">
{{author.fullName + ";"}}
</span>
<a *ngIf="!isSticky && (author.orcid || author.orcid_pending) && testBrowser" class="uk-flex-inline uk-flex-middle uk-link-text">
<img *ngIf="author.orcid" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="orcid" loading="lazy" style="width:16px; height:16px; margin-right: 3px;">
<img *ngIf="!author.orcid && author.orcid_pending" src="assets/common-assets/common/ORCIDiD_iconbw16x16.png" alt="orcid bw" loading="lazy" style="margin-right: 3px;">
<span style="margin-right: 5px;" [class.uk-text-italic]="italic">
{{author.fullName + ";"}}
</span>
</a>
<div *ngIf="!isSticky && (author.orcid || author.orcid_pending) && testBrowser"
class="default-dropdown uk-margin-remove-top uk-dropdown orcid-dropdown"
uk-dropdown="mode:click; offset: 4" style="min-width: 465px !important;">
<div class="uk-padding-small">
<h6 class="uk-margin-remove">{{author.fullName}}</h6>
<div>
<div class="uk-text-meta uk-margin-bottom">ORCID</div>
<div class="uk-text-meta uk-text-xsmall uk-margin-small-top uk-margin-small-bottom">
<img *ngIf="author.orcid" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="" loading="lazy">{{" "}}
<img *ngIf="!author.orcid && author.orcid_pending" src="assets/common-assets/common/ORCIDiD_iconbw16x16.png" alt="" loading="lazy">{{" "}}
<i *ngIf="author.orcid">Harvested from ORCID Public Data File</i>
<i *ngIf="!author.orcid && author.orcid_pending">Derived by OpenAIRE algorithms or harvested from 3d party repositories</i>
</div>
<div>
<div class="clipboard-wrapper uk-width-1-1 uk-flex uk-flex-middle uk-flex-center"
style="min-height: 43px; min-width: 280px;">
<input #element class="uk-padding-small uk-text-emphasis uk-width-medium uk-disabled"
[value]="properties.orcidURL+(author.orcid ? author.orcid : author.orcid_pending)"/>
<a [class]="'uk-link copy orcid_clipboard_btn orcid_clipboard_btn_auhtor_'+i"
title="Copy to clipboard" (click)="copyToClipboard(element)">
COPY
</a>
<ng-container *ngIf="!isSticky && (author.orcid || author.orcid_pending) && isBrowser">
<a #toggle class="uk-flex-inline uk-flex-middle uk-link-text">
<img *ngIf="author.orcid" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="orcid"
loading="lazy" style="width:16px; height:16px; margin-right: 3px;">
<img *ngIf="!author.orcid && author.orcid_pending"
src="assets/common-assets/common/ORCIDiD_iconbw16x16.png" alt="orcid bw" loading="lazy"
style="margin-right: 3px;">
<span style="margin-right: 5px;" [class.uk-text-italic]="italic">
{{author.fullName + ";"}}
</span>
</a>
<div *ngIf="!isMobile" class="default-dropdown uk-margin-remove-top uk-dropdown orcid-dropdown" uk-dropdown="mode:click; offset: 4" style="min-width: 465px !important;">
<ng-container *ngTemplateOutlet="dropdown"></ng-container>
</div>
<mobile-dropdown *ngIf="isMobile" [toggle]="toggle">
<div class="orcid-dropdown">
<ng-container *ngTemplateOutlet="dropdown"></ng-container>
</div>
<div class="uk-text-center uk-margin-small-top">
<a class="uk-button uk-button-text custom-external"
title="Visit author in ORCID" [href]="properties.orcidURL+(author.orcid ? author.orcid : author.orcid_pending)" target="_blank">
VISIT AUTHOR IN ORCID
</a>
</div>
</div>
</div>
</mobile-dropdown>
<ng-template #dropdown>
<div class="uk-padding-small">
<h6 class="uk-margin-remove">{{author.fullName}}</h6>
<div>
<div class="uk-text-meta uk-margin-bottom">ORCID</div>
<hr>
<div class="uk-margin-top uk-text-bold uk-text-emphasis uk-text-center">
{{author.fullName}} in OpenAIRE
</div>
<div class="uk-text-center uk-margin-top uk-margin-large-left uk-margin-large-right">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'" class="uk-button uk-button-primary uk-text-bold uk-padding-remove-top uk-padding-remove-bottom"
(click)="onClick()"
[queryParams]="routerHelper.createQueryParams(['orcid','oc'],[(author['orcid'] ? author['orcid'] : author['orcid_pending']),'and'])"
routerLinkActive="router-link-active" [routerLink]="properties.searchLinkToAdvancedResults">
<span class="space">Search</span>
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="uk-button uk-button-primary uk-text-bold uk-padding-remove-top uk-padding-remove-bottom uk-light"
[href]="'https://explore.openaire.eu'+properties.searchLinkToAdvancedResults+'?orcid='+(author['orcid'] ? author['orcid'] : author['orcid_pending'])+'&oc=and'"
target="_blank">
<span class="space custom-external">Search in OpenAIRE</span>
</a>
</div>
</div>
</div>
</ng-template>
<div *ngIf="authors" class="uk-height-max-medium uk-overflow-auto uk-text-small uk-text-emphasis uk-flex uk-flex-wrap">
<div class="uk-text-meta uk-text-xsmall uk-margin-small-top uk-margin-small-bottom">
<img *ngIf="author.orcid" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt=""
loading="lazy">{{" "}}
<img *ngIf="!author.orcid && author.orcid_pending"
src="assets/common-assets/common/ORCIDiD_iconbw16x16.png" alt="" loading="lazy">{{" "}}
<i *ngIf="author.orcid">Harvested from ORCID Public Data File</i>
<i *ngIf="!author.orcid && author.orcid_pending">Derived by OpenAIRE algorithms or harvested
from 3d party repositories</i>
</div>
<div>
<div class="clipboard-wrapper uk-width-1-1 uk-flex uk-flex-middle uk-flex-center"
style="min-height: 43px; min-width: 280px;">
<input #element class="uk-padding-small uk-text-emphasis uk-width-expand uk-disabled"
[value]="properties.orcidURL+(author.orcid ? author.orcid : author.orcid_pending)"/>
<button class="uk-button uk-button-link uk-margin-small-right copy orcid_clipboard_btn" [ngClass]="'orcid_clipboard_btn_auhtor_'+i"
title="Copy to clipboard" (click)="copyToClipboard(element)">
<icon name="content_copy" visuallyHidden="Copy to clipboard" [flex]="true"></icon>
</button>
</div>
<div class="uk-text-center uk-margin-small-top">
<a class="uk-button uk-button-text custom-external"
title="Visit author in ORCID"
[href]="properties.orcidURL+(author.orcid ? author.orcid : author.orcid_pending)"
target="_blank">
VISIT AUTHOR IN ORCID
</a>
</div>
</div>
</div>
<hr>
<div class="uk-margin-top uk-text-bold uk-text-emphasis uk-text-center">
{{author.fullName}} in OpenAIRE
</div>
<div class="uk-text-center uk-margin-top uk-margin-large-left uk-margin-large-right">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'"
class="uk-button uk-button-primary uk-text-bold uk-padding-remove-top uk-padding-remove-bottom"
(click)="onClick()"
[queryParams]="routerHelper.createQueryParams(['orcid','oc'],[(author['orcid'] ? author['orcid'] : author['orcid_pending']),'and'])"
routerLinkActive="router-link-active" [routerLink]="properties.searchLinkToAdvancedResults">
<span class="space">Search</span>
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'"
class="uk-button uk-button-primary uk-text-bold uk-padding-remove-top uk-padding-remove-bottom uk-light"
[href]="'https://explore.openaire.eu'+properties.searchLinkToAdvancedResults+'?orcid='+(author['orcid'] ? author['orcid'] : author['orcid_pending'])+'&oc=and'"
target="_blank">
<span class="space custom-external">Search in OpenAIRE</span>
</a>
</div>
</div>
</ng-template>
</ng-container>
</ng-template>
<div *ngIf="authors"
class="uk-height-max-medium uk-overflow-auto uk-text-small uk-text-emphasis uk-flex uk-flex-wrap">
<span class="uk-text-meta uk-margin-xsmall-right">
Authors:
</span>
<ng-container *ngFor="let author of authors.slice(0, viewAll?authors.length:authorsLimit) let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i, italic: true}"></ng-container>
</ng-container>
<span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta">
+{{authors.length-authorsLimit | number}} more
<ng-container *ngFor="let author of authors.slice(0, viewAll?authors.length:authorsLimit) let i=index">
<ng-container
*ngTemplateOutlet="author_template; context: { author: author, i:i, italic: true}"></ng-container>
</ng-container>
<span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta">
+{{authors.length - authorsLimit | number}} more
</span>
<span *ngIf="showAll && authors && authors.length > authorsLimit && !viewAll">
<span *ngIf="showAll && authors && authors.length > authorsLimit && !viewAll">
<a (click)="viewAllClick();">
+{{authors.length-authorsLimit | number}} Authors
+{{authors.length - authorsLimit | number}} Authors
</a>
</span>
<div *ngIf="viewAll && lessBtn" class="uk-text-small">
<a (click)="viewAll = !viewAll; lessBtn=false;">View less</a>
<div *ngIf="viewAll && lessBtn" class="uk-text-small">
<a (click)="viewAll = !viewAll; lessBtn=false;">View less</a>
</div>
</div>
</div>
<modal-alert *ngIf="!isMobile" #authorsModal>
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</modal-alert>
<modal-alert *ngIf="!isMobile" #authorsModal>
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</modal-alert>
<fs-modal *ngIf="isMobile" #authorsModal classTitle="uk-tile-default uk-border-bottom">
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</fs-modal>
<fs-modal *ngIf="isMobile" #authorsModal classTitle="uk-tile-default uk-border-bottom">
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</fs-modal>
`
})
@ -131,11 +152,11 @@ export class ShowAuthorsComponent {
public properties: EnvProperties = properties;
public routerHelper: RouterHelper = new RouterHelper();
testBrowser: boolean;
isBrowser: boolean;
public clipboard;
constructor(private route: ActivatedRoute, @Inject(PLATFORM_ID) private platformId: string) {
this.testBrowser = isPlatformBrowser(platformId);
this.isBrowser = isPlatformBrowser(platformId);
}
ngOnInit() {}

View File

@ -6,10 +6,12 @@ import {RouterModule} from '@angular/router';
import {ShowAuthorsComponent} from './showAuthors.component';
import {AlertModalModule} from "../modal/alertModal.module";
import {FullScreenModalModule} from "../modal/full-screen-modal/full-screen-modal.module";
import {MobileDropdownModule} from "../mobile-dropdown/mobile-dropdown.module";
import {IconsModule} from "../icons/icons.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, AlertModalModule, FullScreenModalModule
CommonModule, FormsModule, RouterModule, AlertModalModule, FullScreenModalModule, MobileDropdownModule, IconsModule
],
declarations: [
ShowAuthorsComponent
@ -20,4 +22,4 @@ import {FullScreenModalModule} from "../modal/full-screen-modal/full-screen-moda
ShowAuthorsComponent
]
})
export class ShowAuthorsModule { }
export class ShowAuthorsModule { }

View File

@ -1,10 +1,10 @@
import {Component, Input, OnInit} from "@angular/core";
import {Component, ElementRef, Input, OnInit} from "@angular/core";
@Component({
selector: 'mobile-dropdown',
template: `
<div class="uk-dropdown-mobile" [class.uk-open]="opened">
<div class="uk-dropdown-mobile-container">
<div class="uk-dropdown-mobile" [class.uk-open]="opened" (click)="close()">
<div class="uk-dropdown-mobile-container" (click)="$event.stopPropagation()">
<a class="uk-close" (click)="close()">
<icon name="close" [ratio]="1.2"></icon>
</a>
@ -15,22 +15,48 @@ import {Component, Input, OnInit} from "@angular/core";
</div>`
})
export class MobileDropdownComponent implements OnInit{
@Input() toggle: HTMLLinkElement;
@Input() toggle: HTMLAnchorElement;
public opened: boolean = false;
private static MOBILE_DROPDOWN_CONTAINER = 'mobile-dropdown-container';
constructor(private element: ElementRef) {
}
ngOnInit() {
if(this.toggle) {
this.toggle.onclick = (ev) => {
this.opened = !this.opened;
ev.preventDefault();
ev.stopPropagation();
if(this.opened) {
this.close();
} else {
this.open();
}
}
}
}
open() {
this.opened = true;
if(!this.opened) {
let body = document.getElementsByTagName('body')[0];
let container = document.getElementById(MobileDropdownComponent.MOBILE_DROPDOWN_CONTAINER);
if(!container) {
container = document.createElement('div');
container.setAttribute('id', MobileDropdownComponent.MOBILE_DROPDOWN_CONTAINER);
body.append(container);
}
let parent = this.element.nativeElement.parentElement;
parent.removeChild(this.element.nativeElement);
container.append(this.element.nativeElement);
this.opened = true;
body.setAttribute('style', 'overflow-y: hidden');
}
}
close() {
this.opened = false;
if(this.opened) {
this.opened = false;
document.getElementsByTagName('body')[0].setAttribute('style', '');
}
}
}

View File

@ -123,7 +123,7 @@
</div>
<!-- Authors -->
<div *ngIf="result.authors" class="uk-margin-xsmall-bottom">
<showAuthors [authors]="result.authors" [authorsLimit]=4 [modal]="modal"
<showAuthors [authors]="result.authors" [authorsLimit]=4 [modal]="modal" [isMobile]="isMobile"
[showAll]=true [showInline]="showInline"></showAuthors>
</div>
<!-- Identifiers -->