From e5e4b6118c33f3ef7a93f7e4ba0ba320a57f7030 Mon Sep 17 00:00:00 2001 From: nwoodward Date: Thu, 23 Apr 2026 15:17:54 -0500 Subject: [PATCH 1/2] updates orcid icon and link displays according to their guidelines --- .../item-pages/person/person.component.html | 3 + .../item-pages/person/person.component.ts | 3 +- .../item-page-orcid-field.component.html | 13 ++ .../item-page-orcid-field.component.scss | 12 ++ .../item-page-orcid-field.component.spec.ts | 168 +++++++++++++++++ .../orcid/item-page-orcid-field.component.ts | 170 ++++++++++++++++++ .../item-types/shared/item.component.spec.ts | 2 + .../orcid-badge-and-tooltip.component.html | 18 +- .../orcid-badge-and-tooltip.component.scss | 4 - .../orcid-badge-and-tooltip.component.spec.ts | 15 +- .../orcid-badge-and-tooltip.component.ts | 44 +++++ src/assets/i18n/en.json5 | 4 + src/assets/i18n/it.json5 | 8 +- src/assets/images/orcid.logo.unauth.icon.svg | 5 + src/styles/_custom_variables.scss | 1 + .../item-pages/person/person.component.ts | 3 +- 16 files changed, 457 insertions(+), 16 deletions(-) create mode 100644 src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.html create mode 100644 src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.scss create mode 100644 src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.ts create mode 100755 src/assets/images/orcid.logo.unauth.icon.svg diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 82d42e6857c..20b591a35ef 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -49,6 +49,9 @@ [fields]="['dc.title']" [label]="'person.page.name'"> + +
{{"item.page.link.full" | translate}} diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 56cb2b3fa9b..8bfa04e0bef 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -8,6 +8,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { GenericItemPageFieldComponent } from '../../../../item-page/simple/field-components/specific-field/generic/generic-item-page-field.component'; +import { ItemPageOrcidFieldComponent } from '../../../../item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component'; import { ThemedItemPageTitleFieldComponent } from '../../../../item-page/simple/field-components/specific-field/title/themed-item-page-field.component'; import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { TabbedRelatedEntitiesSearchComponent } from '../../../../item-page/simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component'; @@ -24,7 +25,7 @@ import { ThemedThumbnailComponent } from '../../../../thumbnail/themed-thumbnail styleUrls: ['./person.component.scss'], templateUrl: './person.component.html', standalone: true, - imports: [NgIf, ThemedResultsBackButtonComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, GenericItemPageFieldComponent, RelatedItemsComponent, RouterLink, TabbedRelatedEntitiesSearchComponent, AsyncPipe, TranslateModule], + imports: [NgIf, ThemedResultsBackButtonComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, GenericItemPageFieldComponent, ItemPageOrcidFieldComponent, RelatedItemsComponent, RouterLink, TabbedRelatedEntitiesSearchComponent, AsyncPipe, TranslateModule], }) /** * The component for displaying metadata and relations of an item of the type Person diff --git a/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.html b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.html new file mode 100644 index 00000000000..8f2aed7f382 --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.html @@ -0,0 +1,13 @@ +@if (hasOrcidMetadata) { + +} diff --git a/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.scss b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.scss new file mode 100644 index 00000000000..20d4762d5bc --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.scss @@ -0,0 +1,12 @@ +:host { + .simple-view-element { + margin-bottom: 15px; + } + .simple-view-element-header { + font-size: 1.25rem; + } + .orcid-icon { + height: var(--ds-orcid-icon-height, 16px); + margin-right: 8px; + } +} diff --git a/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.spec.ts b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.spec.ts new file mode 100644 index 00000000000..f02f5b5df38 --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.spec.ts @@ -0,0 +1,168 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { + ComponentFixture, + TestBed, +} from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; +import { APP_CONFIG } from 'src/config/app-config.interface'; + +import { createSuccessfulRemoteDataObject$ } from '../../../../../../app/shared/remote-data.utils'; +import { BrowseService } from '../../../../../core/browse/browse.service'; +import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service'; +import { ConfigurationDataService } from '../../../../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../../../../core/shared/configuration-property.model'; +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageOrcidFieldComponent } from './item-page-orcid-field.component'; + +describe('ItemPageOrcidFieldComponent', () => { + let component: ItemPageOrcidFieldComponent; + let fixture: ComponentFixture; + let configurationService: jasmine.SpyObj; + + const mockItem = Object.assign(new Item(), { + metadata: { + 'person.identifier.orcid': [ + { + value: '0000-0002-1825-0097', + language: null, + authority: null, + confidence: -1, + place: 0, + }, + ], + }, + }); + + const mockConfigProperty = Object.assign(new ConfigurationProperty(), { + name: 'orcid.domain-url', + values: ['https://sandbox.orcid.org'], + }); + + const mockAppConfig = { + ui: { + ssl: false, + host: 'localhost', + port: 4000, + nameSpace: '/', + }, + markdown: { + enabled: false, + mathjax: false, + }, + }; + + beforeEach(async () => { + configurationService = jasmine.createSpyObj('ConfigurationDataService', ['findByPropertyName']); + configurationService.findByPropertyName.and.returnValue( + createSuccessfulRemoteDataObject$(mockConfigProperty), + ); + + const browseDefinitionDataServiceStub = { + findAll: jasmine.createSpy('findAll').and.returnValue(of({})), + getBrowseDefinitions: jasmine.createSpy('getBrowseDefinitions').and.returnValue(of([])), + }; + + const browseServiceStub = { + getBrowseEntriesFor: jasmine.createSpy('getBrowseEntriesFor').and.returnValue(of({})), + getBrowseDefinitions: jasmine.createSpy('getBrowseDefinitions').and.returnValue(of([])), + }; + + await TestBed.configureTestingModule({ + imports: [ + ItemPageOrcidFieldComponent, + TranslateModule.forRoot(), + ], + providers: [ + { provide: ConfigurationDataService, useValue: configurationService }, + { provide: BrowseDefinitionDataService, useValue: browseDefinitionDataServiceStub }, + { provide: BrowseService, useValue: browseServiceStub }, + { provide: APP_CONFIG, useValue: mockAppConfig }, + ], + schemas: [NO_ERRORS_SCHEMA], + }) + .compileComponents(); + + fixture = TestBed.createComponent(ItemPageOrcidFieldComponent); + component = fixture.componentInstance; + component.item = mockItem; + }); + + it('should create', () => { + fixture.detectChanges(); + expect(component).toBeTruthy(); + }); + + it('should check if item has ORCID', () => { + expect(component.hasOrcid()).toBe(true); + }); + + it('should return false when item has no ORCID', () => { + component.item = Object.assign(new Item(), { metadata: {} }); + expect(component.hasOrcid()).toBe(false); + }); + + it('should set hasOrcidMetadata property on init', () => { + fixture.detectChanges(); + expect(component.hasOrcidMetadata).toBe(true); + }); + + it('should set hasOrcidMetadata to false when item has no ORCID', () => { + component.item = Object.assign(new Item(), { metadata: {} }); + component.ngOnInit(); + expect(component.hasOrcidMetadata).toBe(false); + }); + + it('should construct ORCID URL on init', (done) => { + fixture.detectChanges(); + + component.orcidUrl$.subscribe(url => { + expect(url).toBe('https://sandbox.orcid.org/0000-0002-1825-0097'); + done(); + }); + }); + + it('should extract ORCID ID on init', () => { + fixture.detectChanges(); + expect(component.orcidId).toBe('0000-0002-1825-0097'); + }); + + it('should handle ORCID with leading slash', (done) => { + component.item = Object.assign(new Item(), { + metadata: { + 'person.identifier.orcid': [ + { + value: '/0000-0002-1825-0097', + language: null, + authority: null, + confidence: -1, + place: 0, + }, + ], + }, + }); + + component.ngOnInit(); + fixture.detectChanges(); + + expect(component.orcidId).toBe('0000-0002-1825-0097'); + + component.orcidUrl$.subscribe(url => { + expect(url).toBe('https://sandbox.orcid.org/0000-0002-1825-0097'); + done(); + }); + }); + + it('should return null when item has no ORCID metadata', (done) => { + component.item = Object.assign(new Item(), { metadata: {} }); + component.ngOnInit(); + fixture.detectChanges(); + + expect(component.orcidId).toBeNull(); + + component.orcidUrl$.subscribe(url => { + expect(url).toBeNull(); + done(); + }); + }); +}); diff --git a/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.ts b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.ts new file mode 100644 index 00000000000..ee8cac6c058 --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.ts @@ -0,0 +1,170 @@ +import { AsyncPipe } from '@angular/common'; +import { + Component, + Input, + OnInit, +} from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; +import { + combineLatest, + map, + Observable, +} from 'rxjs'; + +import { BrowseService } from '../../../../../core/browse/browse.service'; +import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service'; +import { ConfigurationDataService } from '../../../../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../../../../core/shared/configuration-property.model'; +import { Item } from '../../../../../core/shared/item.model'; +import { MetadataValue } from '../../../../../core/shared/metadata.models'; +import { getFirstSucceededRemoteDataPayload } from '../../../../../core/shared/operators'; +import { ImageField } from '../image-field'; +import { ItemPageFieldComponent } from '../item-page-field.component'; + +@Component({ + selector: 'ds-item-page-orcid-field', + templateUrl: './item-page-orcid-field.component.html', + styleUrls: ['./item-page-orcid-field.component.scss'], + standalone: true, + imports: [ + AsyncPipe, + TranslateModule, + ], +}) +/** + * This component is used for displaying ORCID identifier as a clickable link + */ +export class ItemPageOrcidFieldComponent extends ItemPageFieldComponent implements OnInit { + + /** + * The item to display metadata for + */ + @Input() item: Item; + + /** + * Separator string between multiple values of the metadata fields defined + * @type {string} + */ + separator: string; + + /** + * Fields (schema.element.qualifier) used to render their values. + * In this component, we want to display values for metadata 'person.identifier.orcid' + */ + fields: string[] = [ + 'person.identifier.orcid', + ]; + + /** + * Label i18n key for the rendered metadata + */ + label = 'item.page.orcid-profile'; + + /** + * Observable for the ORCID URL from configuration + */ + baseUrl$: Observable; + + /** + * ORCID ID (without full URL) + */ + orcidId: string | null; + + /** + * Observable for the full ORCID URL + */ + orcidUrl$: Observable; + + /** + * Whether the item has ORCID metadata + */ + hasOrcidMetadata: boolean; + + /** + * ORCID icon configuration + */ + img: ImageField = { + URI: 'assets/images/orcid.logo.icon.svg', + alt: 'item.page.orcid-icon', + heightVar: '--ds-orcid-icon-height', + }; + + /** + * Creates an instance of ItemPageOrcidFieldComponent. + * + * @param {BrowseDefinitionDataService} browseDefinitionDataService - Service for managing browse definitions + * @param {BrowseService} browseService - Service for browse functionality + * @param {ConfigurationDataService} configurationService - Service for accessing configuration properties + */ + constructor( + protected browseDefinitionDataService: BrowseDefinitionDataService, + protected browseService: BrowseService, + protected configurationService: ConfigurationDataService, + ) { + super(browseDefinitionDataService, browseService); + } + + /** + * Initializes the component and sets up observables for ORCID URL. + * Separates the display value (ORCID ID) from the link URL. + * + * @returns {void} + */ + ngOnInit(): void { + + this.hasOrcidMetadata = this.hasOrcid(); + + this.baseUrl$ = this.configurationService + .findByPropertyName('orcid.domain-url') + .pipe( + getFirstSucceededRemoteDataPayload(), + map((property: ConfigurationProperty) => + property?.values?.length > 0 ? property.values[0] : null, + ), + ); + + const metadata = this.getOrcidMetadata(); + + this.orcidId = metadata?.value.replace(/^\//, '') || null; + + this.orcidUrl$ = combineLatest([ + this.baseUrl$, + ]).pipe( + map(([baseUrl]) => { + if (!baseUrl || !this.orcidId) { + return null; + } + + const cleanBaseUrl = baseUrl.replace(/\/$/, ''); + return `${cleanBaseUrl}/${this.orcidId}`; + }), + ); + } + + /** + * Retrieves the ORCID metadata value from the item. + * Extracts the first ORCID identifier from the item's metadata fields, + * ensuring the value is not empty or whitespace only. + * + * @private + * @returns {MetadataValue | null} The ORCID metadata value if found and valid, null otherwise + */ + private getOrcidMetadata(): MetadataValue | null { + if (!this.item || !this.hasOrcid()) { + return null; + } + + const metadata = this.item.findMetadataSortedByPlace('person.identifier.orcid'); + return metadata.length > 0 && metadata[0].value?.trim() ? metadata[0] : null; + } + + /** + * Checks whether the item has ORCID metadata associated with it. + * + * @public + * @returns {boolean} True if the item has 'person.identifier.orcid' metadata, false otherwise + */ + public hasOrcid(): boolean { + return this.item?.hasMetadata('person.identifier.orcid'); + } +} diff --git a/src/app/item-page/simple/item-types/shared/item.component.spec.ts b/src/app/item-page/simple/item-types/shared/item.component.spec.ts index e1ae24ff4d2..aa865cd6598 100644 --- a/src/app/item-page/simple/item-types/shared/item.component.spec.ts +++ b/src/app/item-page/simple/item-types/shared/item.component.spec.ts @@ -68,6 +68,7 @@ import { TruncatableService } from '../../../../shared/truncatable/truncatable.s import { TruncatePipe } from '../../../../shared/utils/truncate.pipe'; import { ThemedThumbnailComponent } from '../../../../thumbnail/themed-thumbnail.component'; import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component'; +import { ItemPageOrcidFieldComponent } from '../../field-components/specific-field/orcid/item-page-orcid-field.component'; import { ThemedItemPageTitleFieldComponent } from '../../field-components/specific-field/title/themed-item-page-field.component'; import { ThemedMetadataRepresentationListComponent } from '../../metadata-representation-list/themed-metadata-representation-list.component'; import { TabbedRelatedEntitiesSearchComponent } from '../../related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component'; @@ -200,6 +201,7 @@ export function getItemPageFieldsTest(mockItem: Item, component) { RelatedItemsComponent, TabbedRelatedEntitiesSearchComponent, ThemedMetadataRepresentationListComponent, + ItemPageOrcidFieldComponent, ], }, add: { changeDetection: ChangeDetectionStrategy.Default }, diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html index 9f4821e7802..3cef67803a9 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html @@ -1,10 +1,14 @@ -ORCID {{ orcidTooltip }} + + ORCID {{ orcidTooltip }} + {{ orcidTooltip }} diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss index 6a1c259e18a..8d4ee112524 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss @@ -4,8 +4,4 @@ .orcid-icon { height: 1.2rem; - - &.not-authenticated { - filter: grayscale(100%); - } } diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts index dd47fd918bb..f6df5df38aa 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts @@ -9,7 +9,9 @@ import { import { By } from '@angular/platform-browser'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; +import { of } from 'rxjs'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; import { MetadataValue } from '../../core/shared/metadata.models'; import { OrcidBadgeAndTooltipComponent } from './orcid-badge-and-tooltip.component'; @@ -19,6 +21,9 @@ describe('OrcidBadgeAndTooltipComponent', () => { let translateService: TranslateService; beforeEach(async () => { + const configurationDataServiceStub = jasmine.createSpyObj('ConfigurationDataService', ['findByPropertyName']); + configurationDataServiceStub.findByPropertyName.and.returnValue(of({})); + await TestBed.configureTestingModule({ imports: [ OrcidBadgeAndTooltipComponent, @@ -28,6 +33,7 @@ describe('OrcidBadgeAndTooltipComponent', () => { ], providers: [ { provide: TranslateService, useValue: { instant: (key: string) => key } }, + { provide: ConfigurationDataService, useValue: configurationDataServiceStub }, ], }).compileComponents(); @@ -61,11 +67,16 @@ describe('OrcidBadgeAndTooltipComponent', () => { expect(badgeIcon).toBeTruthy(); }); - it('should display the ORCID icon in greyscale if there is no authenticated timestamp', () => { + it('should display the filled green ORCID icon if there is an authenticated timestamp', () => { + const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); + expect(badgeIcon.nativeElement.getAttribute('src')).toEqual('assets/images/orcid.logo.icon.svg'); + }); + + it('should display the unfilled green ORCID icon if there is no authenticated timestamp', () => { component.authenticatedTimestamp = null; fixture.detectChanges(); const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); - expect(badgeIcon.nativeElement.classList).toContain('not-authenticated'); + expect(badgeIcon.nativeElement.getAttribute('src')).toEqual('assets/images/orcid.logo.unauth.icon.svg'); }); }); diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts index 6e8ba7100f3..06f5da5f427 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts @@ -1,4 +1,5 @@ import { + AsyncPipe, NgClass, NgIf, } from '@angular/common'; @@ -9,8 +10,15 @@ import { } from '@angular/core'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; +import { + map, + Observable, +} from 'rxjs'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; import { MetadataValue } from '../../core/shared/metadata.models'; +import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; /** * Component to display an ORCID badge with a tooltip. @@ -20,6 +28,7 @@ import { MetadataValue } from '../../core/shared/metadata.models'; selector: 'ds-orcid-badge-and-tooltip', standalone: true, imports: [ + AsyncPipe, NgIf, NgbTooltipModule, NgClass, @@ -44,12 +53,18 @@ export class OrcidBadgeAndTooltipComponent implements OnInit { */ orcidTooltip: string; + /** + * Observable for the full ORCID URL + */ + orcidUrl$: Observable; + /** * Constructor to inject the TranslateService. * @param translateService - Service for translation. */ constructor( private translateService: TranslateService, + private configurationService: ConfigurationDataService, ) { } /** @@ -60,6 +75,35 @@ export class OrcidBadgeAndTooltipComponent implements OnInit { this.orcidTooltip = this.authenticatedTimestamp ? this.translateService.instant('person.orcid-tooltip.authenticated', { orcid: this.orcid.value }) : this.translateService.instant('person.orcid-tooltip.not-authenticated', { orcid: this.orcid.value }); + this.orcidUrl$ = this.buildOrcidUrl(); } + /** + * Build the full ORCID URL from configuration and metadata value + */ + private buildOrcidUrl(): Observable { + + + const baseUrl$ = this.configurationService + .findByPropertyName('orcid.domain-url') + .pipe( + getFirstSucceededRemoteDataPayload(), + map((property: ConfigurationProperty) => + property?.values?.length > 0 ? property.values[0] : null, + ), + ); + + + return baseUrl$.pipe( + map(baseUrl => { + if (!baseUrl || !this.orcid?.value) { + return ''; + } + + const cleanBaseUrl = baseUrl.replace(/\/$/, ''); + const cleanOrcidId = this.orcid.value.replace(/^\//, ''); + return `${cleanBaseUrl}/${cleanOrcidId}`; + }), + ); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 508730c54f7..d704b8c0844 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2833,6 +2833,10 @@ "item.page.orcid.tooltip": "Open ORCID setting page", + "item.page.orcid-ico": "ORCID icon", + + "item.page.orcid-profile": "ORCID Profile", + "item.page.person.search.title": "Articles by this author", "item.page.related-items.view-more": "Show {{ amount }} more", diff --git a/src/assets/i18n/it.json5 b/src/assets/i18n/it.json5 index 27e99e7faf7..650e814132d 100644 --- a/src/assets/i18n/it.json5 +++ b/src/assets/i18n/it.json5 @@ -4534,6 +4534,12 @@ // "item.page.orcid.tooltip": "Open ORCID setting page", "item.page.orcid.tooltip": "Apri la pagina delle impostazioni ORCID", + //"item.page.orcid-ico": "ORCID icon", + "item.page.orcid-ico": "Icona ORCID", + + //"item.page.orcid-profile": "ORCID Profile", + "item.page.orcid-profile": "Profilo ORCID", + // "item.page.person.search.title": "Articles by this author", "item.page.person.search.title": "Articoli di questo autore", @@ -11424,4 +11430,4 @@ "item.preview.organization.alternateName": "Alternative name", -} \ No newline at end of file +} diff --git a/src/assets/images/orcid.logo.unauth.icon.svg b/src/assets/images/orcid.logo.unauth.icon.svg new file mode 100755 index 00000000000..02b90a8eb1d --- /dev/null +++ b/src/assets/images/orcid.logo.unauth.icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/styles/_custom_variables.scss b/src/styles/_custom_variables.scss index 35f361e0f6d..861078d6b0a 100644 --- a/src/styles/_custom_variables.scss +++ b/src/styles/_custom_variables.scss @@ -163,4 +163,5 @@ --ds-filters-skeleton-height: 40px; --ds-filters-skeleton-spacing: 12px; + --ds-orcid-icon-height: 2em } diff --git a/src/themes/custom/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/themes/custom/app/entity-groups/research-entities/item-pages/person/person.component.ts index f1a60957eda..70096e14df7 100644 --- a/src/themes/custom/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/themes/custom/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -17,6 +17,7 @@ import { ThemedThumbnailComponent } from 'src/app/thumbnail/themed-thumbnail.com import { Context } from '../../../../../../../app/core/shared/context.model'; import { ViewMode } from '../../../../../../../app/core/shared/view-mode.model'; import { PersonComponent as BaseComponent } from '../../../../../../../app/entity-groups/research-entities/item-pages/person/person.component'; +import { ItemPageOrcidFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component'; import { listableObjectComponent } from '../../../../../../../app/shared/object-collection/shared/listable-object/listable-object.decorator'; @listableObjectComponent('Person', ViewMode.StandalonePage, Context.Any, 'custom') @@ -27,7 +28,7 @@ import { listableObjectComponent } from '../../../../../../../app/shared/object- // templateUrl: './person.component.html', templateUrl: '../../../../../../../app/entity-groups/research-entities/item-pages/person/person.component.html', standalone: true, - imports: [NgIf, ThemedResultsBackButtonComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, GenericItemPageFieldComponent, RelatedItemsComponent, RouterLink, TabbedRelatedEntitiesSearchComponent, AsyncPipe, TranslateModule], + imports: [NgIf, ThemedResultsBackButtonComponent, ThemedItemPageTitleFieldComponent, DsoEditMenuComponent, MetadataFieldWrapperComponent, ThemedThumbnailComponent, GenericItemPageFieldComponent, ItemPageOrcidFieldComponent, RelatedItemsComponent, RouterLink, TabbedRelatedEntitiesSearchComponent, AsyncPipe, TranslateModule], }) export class PersonComponent extends BaseComponent { } From 3e8d1d631061cb3dea86a9d0fc21ea47e8cdca31 Mon Sep 17 00:00:00 2001 From: nwoodward Date: Thu, 23 Apr 2026 16:45:11 -0500 Subject: [PATCH 2/2] added role link --- .../orcid-badge-and-tooltip.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html index 3cef67803a9..7ee4ae0ea22 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html @@ -1,4 +1,5 @@