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 efb92a35621..1b08649235d 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
@@ -51,6 +51,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 bb8d79ca138..6b1c296d074 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
@@ -5,6 +5,7 @@ import { ViewMode } from '@dspace/core/shared/view-mode.model';
import { TranslateModule } from '@ngx-translate/core';
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 { AuthorityRelatedEntitiesSearchComponent } from '../../../../item-page/simple/related-entities/authority-related-entities-search/authority-related-entities-search.component';
@@ -26,6 +27,7 @@ import { ThemedThumbnailComponent } from '../../../../thumbnail/themed-thumbnail
AuthorityRelatedEntitiesSearchComponent,
DsoEditMenuComponent,
GenericItemPageFieldComponent,
+ ItemPageOrcidFieldComponent,
MetadataFieldWrapperComponent,
RelatedItemsComponent,
RouterLink,
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..92a4d7807ed
--- /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) {
+
+}
\ No newline at end of file
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..782b02a55b3
--- /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/core/utilities/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..01ea00274f9
--- /dev/null
+++ b/src/app/item-page/simple/field-components/specific-field/orcid/item-page-orcid-field.component.ts
@@ -0,0 +1,169 @@
+import { AsyncPipe } from '@angular/common';
+import {
+ Component,
+ Input,
+ OnInit,
+} from '@angular/core';
+import { TranslatePipe } 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'],
+ imports: [
+ AsyncPipe,
+ TranslatePipe,
+ ],
+})
+/**
+ * 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 c3abc701dc3..fd3871953ed 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
@@ -73,6 +73,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';
@@ -202,6 +203,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 @@
-
+
+
+
{{ 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 9555f6dae02..c295426ebfb 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
@@ -7,7 +7,9 @@ import { By } from '@angular/platform-browser';
import { MetadataValue } from '@dspace/core/shared/metadata.models';
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
+import { of } from 'rxjs';
+import { ConfigurationDataService } from '../../core/data/configuration-data.service';
import { OrcidBadgeAndTooltipComponent } from './orcid-badge-and-tooltip.component';
describe('OrcidBadgeAndTooltipComponent', () => {
@@ -16,6 +18,9 @@ describe('OrcidBadgeAndTooltipComponent', () => {
let translateService: TranslateService;
beforeEach(async () => {
+ const configurationDataServiceStub = jasmine.createSpyObj('ConfigurationDataService', ['findByPropertyName']);
+ configurationDataServiceStub.findByPropertyName.and.returnValue(of({}));
+
await TestBed.configureTestingModule({
imports: [
OrcidBadgeAndTooltipComponent,
@@ -24,6 +29,7 @@ describe('OrcidBadgeAndTooltipComponent', () => {
],
providers: [
{ provide: TranslateService, useValue: { instant: (key: string) => key } },
+ { provide: ConfigurationDataService, useValue: configurationDataServiceStub },
],
}).compileComponents();
@@ -57,11 +63,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 green unfilled 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 31119699f5b..df00af09f21 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,7 @@
-import { NgClass } from '@angular/common';
+import {
+ AsyncPipe,
+ NgClass,
+} from '@angular/common';
import {
Component,
Input,
@@ -7,6 +10,14 @@ import {
import { MetadataValue } from '@dspace/core/shared/metadata.models';
import { NgbTooltip } 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 { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
/**
* Component to display an ORCID badge with a tooltip.
@@ -15,6 +26,7 @@ import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'ds-orcid-badge-and-tooltip',
imports: [
+ AsyncPipe,
NgbTooltip,
NgClass,
],
@@ -38,22 +50,53 @@ 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,
) { }
- /**
- * Initializes the component.
- * Sets the tooltip text based on the presence of the authenticated timestamp.
- */
ngOnInit() {
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 32577407f5d..abaa2a79ff1 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -3077,6 +3077,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 0cbf0c9b5a5..d590790d521 100644
--- a/src/assets/i18n/it.json5
+++ b/src/assets/i18n/it.json5
@@ -5046,6 +5046,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",
@@ -12968,4 +12974,4 @@
"admin.edit-user-agreement.title": "Edit User Agreement",
-}
\ 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 0df8410a8d4..999d6a6373d 100644
--- a/src/styles/_custom_variables.scss
+++ b/src/styles/_custom_variables.scss
@@ -174,4 +174,5 @@
--ds-filters-skeleton-height: 40px;
--ds-filters-skeleton-spacing: 12px;
--ds-identifier-subtype-icon-height: 24px;
+ --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 5bb6ae3a686..6b3a91fdf4d 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
@@ -14,6 +14,7 @@ import { ThemedResultsBackButtonComponent } from 'src/app/shared/results-back-bu
import { ThemedThumbnailComponent } from 'src/app/thumbnail/themed-thumbnail.component';
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 { AuthorityRelatedEntitiesSearchComponent } from '../../../../../../../app/item-page/simple/related-entities/authority-related-entities-search/authority-related-entities-search.component';
import { listableObjectComponent } from '../../../../../../../app/shared/object-collection/shared/listable-object/listable-object.decorator';
@@ -29,6 +30,7 @@ import { listableObjectComponent } from '../../../../../../../app/shared/object-
AuthorityRelatedEntitiesSearchComponent,
DsoEditMenuComponent,
GenericItemPageFieldComponent,
+ ItemPageOrcidFieldComponent,
MetadataFieldWrapperComponent,
RelatedItemsComponent,
RouterLink,