From caa57ccb23462f553c078a16c0cf55b75fd54a3d Mon Sep 17 00:00:00 2001 From: Tuan Nguyen Date: Wed, 25 Oct 2023 17:33:32 -0400 Subject: [PATCH] add altmetrics and plumx --- config/config.yml | 5 +- src/app/item-page/item-page.module.ts | 2 + .../item-page-metrics-field.component.html | 6 ++ .../item-page-metrics-field.component.spec.ts | 57 +++++++++++++++++++ .../item-page-metrics-field.component.ts | 49 ++++++++++++++++ .../publication/publication.component.html | 3 + src/config/config.server.ts | 2 + src/config/ui-server-config.interface.ts | 5 ++ 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.html create mode 100644 src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.ts diff --git a/config/config.yml b/config/config.yml index d2ca036e04e..332146a753b 100644 --- a/config/config.yml +++ b/config/config.yml @@ -11,9 +11,12 @@ ui: # Trust X-FORWARDED-* headers from proxies (default = true) useProxies: true + altmetric: https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js + plumx: https://cdn.plu.mx/widget-popup.js + rest: ssl: true - host: ys.library.yorku.ca + host: api7.dspace.org port: 443 nameSpace: /server diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index a8d41d15352..25ff28d52f2 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -60,6 +60,7 @@ import { ThemedItemAlertsComponent } from './alerts/themed-item-alerts.component import { ThemedFullFileSectionComponent } from './full/field-components/file-section/themed-full-file-section.component'; +import { ItemPageMetricsFieldComponent } from './simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -102,6 +103,7 @@ const DECLARATIONS = [ OrcidQueueComponent, ItemAlertsComponent, ThemedItemAlertsComponent, + ItemPageMetricsFieldComponent, BitstreamRequestACopyPageComponent, ]; diff --git a/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.html b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.html new file mode 100644 index 00000000000..4b11ea49716 --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.html @@ -0,0 +1,6 @@ + +
+
+ +
\ No newline at end of file diff --git a/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.spec.ts b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.spec.ts new file mode 100644 index 00000000000..d26719e5115 --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.spec.ts @@ -0,0 +1,57 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Item } from 'src/app/core/shared/item.model'; +import { of as observableOf } from 'rxjs'; +import { ItemPageMetricsFieldComponent } from './item-page-metrics-field.component'; +import { APP_CONFIG } from 'src/config/app-config.interface'; + +describe('ItemPageMetricsFieldComponent', () => { + let component: ItemPageMetricsFieldComponent; + let fixture: ComponentFixture; + const URI = '/10.13039/501100000289'; + + const appConfigProvider = { + provide: APP_CONFIG, + useValue: { ui: { altmetric: 'altmetric-url', plumx: 'plumx-url' } } + }; + + beforeEach(async () => { + TestBed.configureTestingModule({ + declarations: [ItemPageMetricsFieldComponent], + providers: [appConfigProvider], + }); + + fixture = TestBed.createComponent(ItemPageMetricsFieldComponent); + component = fixture.componentInstance; + + const mockItem: Item = Object.assign(new Item(), { + bundles: observableOf({}), + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title', + }, + ], + 'dc.identifier.uri': [{ value: 'http://dx.doi.org' + URI }], + }, + }); + + component.item = mockItem; + + fixture.detectChanges(); + }); + + it('should set data-doi attribute correctly', () => { + const doiAttribute = fixture.nativeElement.querySelector('.altmetric-embed').getAttribute('data-doi'); + expect(doiAttribute).toBe(URI); + }); + + it('should generate a valid anchor element', () => { + const metricsFieldElement = fixture.nativeElement; + const anchorElement = metricsFieldElement.querySelector('a'); + expect(anchorElement).not.toBeNull(); + + const expectedHref = 'https://plu.mx/plum/a/?doi=' + URI; + expect(anchorElement.getAttribute('href')).toBe(expectedHref); + }); +}); diff --git a/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.ts b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.ts new file mode 100644 index 00000000000..5e20002d9cf --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/metrics/item-page-metrics-field/item-page-metrics-field.component.ts @@ -0,0 +1,49 @@ +import { Component, Input, Inject, OnInit } from '@angular/core'; +import { AltmetricMenuItemModel } from 'src/app/shared/menu/menu-item/models/altmetric.model'; +import { Item } from 'src/app/core/shared/item.model'; +import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; + +@Component({ + selector: 'ds-item-page-metrics-field', + templateUrl: './item-page-metrics-field.component.html', +}) +export class ItemPageMetricsFieldComponent implements OnInit { + + @Input() metrics = { url: '', disabled: true } as AltmetricMenuItemModel; + @Input() item: Item; + + constructor(@Inject(APP_CONFIG) private appConfig: AppConfig) {} + + ngOnInit() { + this.metrics.url = this.item.firstMetadataValue('dc.identifier.uri') ? (new URL(this.item.firstMetadataValue('dc.identifier.uri')).pathname) : ''; + if (this.metrics.url !== '') { + this.metrics.disabled = false; + } + + this.loadExternalScript(this.appConfig.ui.altmetric) + .catch(error => console.error('Script loading error:', error)); + + this.loadExternalScript(this.appConfig.ui.plumx) + .catch(error => console.error('Script loading error:', error)); + } + + private loadExternalScript(scriptUrl: string): Promise { + return new Promise((resolve, reject) => { + if (!this.metrics.disabled) { + const script = document.createElement('script'); + script.src = scriptUrl; + script.onload = () => { + console.log('External script has been loaded: ' + scriptUrl); + resolve(); + }; + script.onerror = (error) => { + this.metrics.disabled = true; + reject(error); + }; + document.body.appendChild(script); + } else { + resolve(); + } + }); + } +} diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index 3749f639644..efb126c9083 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -47,7 +47,10 @@ [fields]="['dc.publisher']" [label]="'publication.page.publisher'"> + + +
{ appConfig.ui.port = isNotEmpty(ENV('PORT', true)) ? getNumberFromString(ENV('PORT', true)) : appConfig.ui.port; appConfig.ui.nameSpace = isNotEmpty(ENV('NAMESPACE', true)) ? ENV('NAMESPACE', true) : appConfig.ui.nameSpace; appConfig.ui.ssl = isNotEmpty(ENV('SSL', true)) ? getBooleanFromString(ENV('SSL', true)) : appConfig.ui.ssl; + appConfig.ui.altmetric = isNotEmpty(ENV('ALTMETRIC', true)) ? ENV('ALTMETRIC', true) : appConfig.ui.altmetric; + appConfig.ui.plumx = isNotEmpty(ENV('PLUMX', true)) ? ENV('PLUMX', true) : appConfig.ui.plumx; // apply existing non convention REST environment variables appConfig.rest.host = isNotEmpty(ENV('REST_HOST', true)) ? ENV('REST_HOST', true) : appConfig.rest.host; diff --git a/src/config/ui-server-config.interface.ts b/src/config/ui-server-config.interface.ts index 70e2fa3e262..ae9ad58ffe1 100644 --- a/src/config/ui-server-config.interface.ts +++ b/src/config/ui-server-config.interface.ts @@ -13,4 +13,9 @@ export class UIServerConfig extends ServerConfig { // Trust X-FORWARDED-* headers from proxies useProxies: boolean; + + // Altmetric script URL + altmetric?: string; + // Plumx script URL + plumx?: string; }