Skip to content

Commit 79f43f4

Browse files
milanmajchrakMatus Kasak
andauthored
MENDELU/Fixed ORCID badge (#1272)
* Fixed ORCID badge --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
1 parent fea2f20 commit 79f43f4

3 files changed

Lines changed: 72 additions & 34 deletions

File tree

src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
</a>
1313
}
1414
@if ((mdRepresentation.representationType==='authority_controlled')) {
15-
@let isOrcid = isOrcidAuthority();
15+
@let orcidDomainUrl = orcidDomainUrl$ | async;
16+
@let isOrcid = isOrcidAuthority(orcidDomainUrl);
1617
@if (isOrcid) {
17-
<a class="dont-break-out orcid-author-link" [href]="getOrcidUrl()" target="_blank" rel="noopener noreferrer">
18+
<a class="dont-break-out orcid-author-link" [href]="getOrcidUrl(orcidDomainUrl)" target="_blank" rel="noopener noreferrer">
1819
{{mdRepresentation.getValue()}}
1920
<i class="fa-brands fa-orcid orcid-icon" aria-hidden="true"></i>
2021
</a>

src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.spec.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,6 @@ const mockOrcidWithWhitespaceRepresentation = Object.assign(new MetadatumReprese
4242
authority: ' 1234-5678-9012-3456 ',
4343
});
4444

45-
const mockOrcidFullUrlRepresentation = Object.assign(new MetadatumRepresentation('type'), {
46-
key: 'dc.contributor.author',
47-
value: 'Doe, John',
48-
authority: 'https://orcid.org/1234-5678-9012-3456',
49-
});
50-
51-
const mockOrcidFullUrlSandboxRepresentation = Object.assign(new MetadatumRepresentation('type'), {
52-
key: 'dc.contributor.author',
53-
value: 'Smith, Jane',
54-
authority: 'https://sandbox.orcid.org/1234-5678-9012-345X',
55-
});
56-
5745
const mockConfigurationDataService = {
5846
findByPropertyName: jasmine.createSpy('findByPropertyName').and.returnValue(
5947
createSuccessfulRemoteDataObject$({ values: ['https://orcid.org'] }),
Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,73 @@
1-
import { Component } from '@angular/core';
1+
import {
2+
AsyncPipe,
3+
} from '@angular/common';
4+
import {
5+
Component,
6+
OnInit,
7+
} from '@angular/core';
28
import { RouterLink } from '@angular/router';
39

10+
import { BehaviorSubject } from 'rxjs';
11+
12+
import { ConfigurationDataService } from '../../../../core/data/configuration-data.service';
413
import { MetadatumRepresentation } from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model';
14+
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
515
import { VALUE_LIST_BROWSE_DEFINITION } from '../../../../core/shared/value-list-browse-definition.resource-type';
616
import { MetadataRepresentationListElementComponent } from '../metadata-representation-list-element.component';
717

818
/**
9-
* Regex pattern for full ORCID URL authority values stored by the backend
10-
* (e.g. https://orcid.org/0000-0001-2345-6789 or https://sandbox.orcid.org/0000-0001-2345-678X).
19+
* Regex pattern for ORCID identifiers: four groups of four digits separated by hyphens.
20+
* The last group may end with an X (checksum digit).
21+
* Example: 0000-0001-2345-6789 or 0000-0001-2345-678X
1122
*/
12-
const ORCID_URL_PATTERN = /^https?:\/\/[^/]+\/((\d{4}-){3}(\d{3}X|\d{4}))$/i;
23+
const ORCID_PATTERN = /^\d{4}-\d{4}-\d{4}-(\d{3}X|\d{4})$/;
1324

1425
@Component({
1526
selector: 'ds-plain-text-metadata-list-element',
1627
templateUrl: './plain-text-metadata-list-element.component.html',
1728
styleUrls: ['./plain-text-metadata-list-element.component.scss'],
1829
standalone: true,
1930
imports: [
31+
AsyncPipe,
2032
RouterLink,
2133
],
2234
})
2335
/**
2436
* A component for displaying MetadataRepresentation objects in the form of plain text
2537
* It will simply use the value retrieved from MetadataRepresentation.getValue() to display as plain text
2638
*/
27-
export class PlainTextMetadataListElementComponent extends MetadataRepresentationListElementComponent {
39+
export class PlainTextMetadataListElementComponent extends MetadataRepresentationListElementComponent implements OnInit {
40+
41+
/**
42+
* The base ORCID domain URL fetched from backend configuration.
43+
* Remains null until successfully loaded — ORCID linking is disabled when null.
44+
*/
45+
orcidDomainUrl$ = new BehaviorSubject<string | null>(null);
46+
47+
constructor(private configurationService: ConfigurationDataService) {
48+
super();
49+
}
50+
51+
ngOnInit(): void {
52+
this.configurationService.findByPropertyName('orcid.domain-url').pipe(
53+
getFirstCompletedRemoteData(),
54+
).subscribe(rd => {
55+
if (rd.hasFailed) {
56+
console.error('PlainTextMetadataListElementComponent: failed to fetch backend config property "orcid.domain-url". ORCID author linking will be disabled.');
57+
return;
58+
}
59+
if (!rd.hasSucceeded || !rd.payload?.values?.length) {
60+
console.error('PlainTextMetadataListElementComponent: backend config property "orcid.domain-url" returned no values. ORCID author linking will be disabled.');
61+
return;
62+
}
63+
const url = rd.payload.values[0].trim();
64+
if (!url || !/^https?:\/\//i.test(url)) {
65+
console.error(`PlainTextMetadataListElementComponent: backend config property "orcid.domain-url" has invalid value "${url}". ORCID author linking will be disabled.`);
66+
return;
67+
}
68+
this.orcidDomainUrl$.next(url);
69+
});
70+
}
2871

2972
/**
3073
* Get the appropriate query parameters for this browse link, depending on whether the browse definition
@@ -41,30 +84,36 @@ export class PlainTextMetadataListElementComponent extends MetadataRepresentatio
4184
}
4285

4386
/**
44-
* Check if the authority value of this metadata is a full ORCID URL.
45-
* The backend OrcidAuthorityAssign script stores authority as full URLs
46-
* (e.g. https://orcid.org/0000-0001-2345-6789).
87+
* Check if the authority value of this metadata is an ORCID identifier.
88+
* Authority is expected to be a bare ORCID ID (e.g. 0000-0001-2345-6789).
89+
* Requires the orcidDomainUrl to be loaded from backend configuration.
4790
*/
48-
isOrcidAuthority(): boolean {
91+
isOrcidAuthority(orcidDomainUrl: string | null): boolean {
92+
if (orcidDomainUrl === null) {
93+
return false;
94+
}
4995
if (this.mdRepresentation instanceof MetadatumRepresentation) {
5096
const authority = this.mdRepresentation.authority?.trim();
51-
return !!authority && ORCID_URL_PATTERN.test(authority);
97+
return !!authority && ORCID_PATTERN.test(authority);
5298
}
5399
return false;
54100
}
55101

56102
/**
57-
* Return the full ORCID profile URL from the authority value.
58-
* Since the backend stores authority as a full URL, this simply returns it.
59-
* Returns an empty string if the authority is not a valid ORCID URL.
103+
* Build the full ORCID profile URL by combining the configured domain URL with the authority ORCID ID.
104+
* Returns an empty string if preconditions are not met (no domain URL or no valid authority).
60105
*/
61-
getOrcidUrl(): string {
62-
if (this.mdRepresentation instanceof MetadatumRepresentation) {
63-
const authority = this.mdRepresentation.authority?.trim();
64-
if (authority && ORCID_URL_PATTERN.test(authority)) {
65-
return authority;
66-
}
106+
getOrcidUrl(orcidDomainUrl: string | null): string {
107+
if (orcidDomainUrl === null) {
108+
return '';
109+
}
110+
const authority = this.mdRepresentation instanceof MetadatumRepresentation
111+
? this.mdRepresentation.authority?.trim()
112+
: undefined;
113+
if (!authority) {
114+
return '';
67115
}
68-
return '';
116+
const base = orcidDomainUrl.endsWith('/') ? orcidDomainUrl : orcidDomainUrl + '/';
117+
return `${base}${authority}`;
69118
}
70119
}

0 commit comments

Comments
 (0)