Skip to content

Commit 9754c00

Browse files
alisaismailatiFrancescoMolinaro
authored andcommitted
Merged in task/dspace-cris-2023_02_x/DSC-1520 (pull request DSpace#1721)
Task/dspace cris 2023 02 x/DSC-1520 Approved-by: Francesco Molinaro
2 parents 1b19d0f + 085428c commit 9754c00

8 files changed

Lines changed: 158 additions & 13 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<div [class]="field.styleValue">
2-
<span class="text-value">
3-
<a [target]="target" href="{{identifier?.href}}">{{ identifier?.text }}</a>
4-
</span>
5-
</div>
2+
<div class="d-flex align-items-center identifier-container-{{iconPosition}}">
3+
<a href="{{iconLink}}" [ngbTooltip]="iconLink" target="_blank" *ngIf="subTypeIcon && iconPosition !== iconPositionEnum.NONE">
4+
<img class="source-icon" [src]="subTypeIcon" alt="source-icon" >
5+
</a>
6+
<span class="text-value">
7+
<a [target]="target" href="{{identifier?.href}}">{{ identifier?.text }}</a>
8+
</span>
9+
</div>
10+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.source-icon {
2+
height: var(--ds-identifier-sybetype-icon-height);
3+
min-height: 16px;
4+
width: auto;
5+
}
6+
7+
.identifier-container-LEFT {
8+
flex-direction: row;
9+
.source-icon {
10+
margin-right: 0.2em;
11+
}
12+
}
13+
14+
.identifier-container-RIGHT {
15+
flex-direction: row-reverse;
16+
justify-content: flex-end;
17+
.source-icon {
18+
margin-left: 0.2em;
19+
}
20+
}

src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/rendering-types/identifier/identifier.component.ts

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import { IdentifierSubtypesConfig, IdentifierSubtypesIconPositionEnum } from './../../../../../../../../config/identifier-subtypes-config.interface';
12
import { Component, Inject, OnInit } from '@angular/core';
23
import { FieldRenderingType, MetadataBoxFieldRendering } from '../metadata-box.decorator';
34
import { ResolverStrategyService } from '../../../../../../services/resolver-strategy.service';
4-
import { hasValue, isNotEmpty } from '../../../../../../../shared/empty.util';
5+
import { hasNoValue, hasValue, isNotEmpty } from '../../../../../../../shared/empty.util';
56
import { MetadataLinkValue } from '../../../../../../models/cris-layout-metadata-link-value.model';
67
import { RenderingTypeValueModelComponent } from '../rendering-type-value.model';
78
import { Item } from '../../../../../../../core/shared/item.model';
89
import { TranslateService } from '@ngx-translate/core';
910
import { LayoutField } from '../../../../../../../core/layout/models/box.model';
1011
import { MetadataValue } from '../../../../../../../core/shared/metadata.models';
12+
import { environment } from 'src/environments/environment';
1113

1214
/**
1315
* This component renders the identifier metadata fields.
@@ -37,6 +39,31 @@ export class IdentifierComponent extends RenderingTypeValueModelComponent implem
3739
*/
3840
target = '_blank';
3941

42+
/**
43+
* The identifier subtype configurations
44+
*/
45+
identifierSubtypeConfig: IdentifierSubtypesConfig[] = environment.identifierSubtypes;
46+
47+
/**
48+
* The icon to display for the identifier subtype
49+
*/
50+
subTypeIcon: string;
51+
52+
/**
53+
* The position of the icon relative to the identifier
54+
*/
55+
iconPosition: IdentifierSubtypesIconPositionEnum = IdentifierSubtypesIconPositionEnum.NONE;
56+
57+
/**
58+
* The link to navigate to when the icon is clicked
59+
*/
60+
iconLink = '';
61+
62+
/**
63+
* The identifier subtype to render
64+
*/
65+
iconPositionEnum = IdentifierSubtypesIconPositionEnum;
66+
4067
constructor(
4168
@Inject('fieldProvider') public fieldProvider: LayoutField,
4269
@Inject('itemProvider') public itemProvider: Item,
@@ -80,27 +107,82 @@ export class IdentifierComponent extends RenderingTypeValueModelComponent implem
80107
return identifier;
81108
}
82109

110+
/**
111+
* Create a MetadataLinkValue object with the given href and text
112+
* @param href the href value
113+
* @param text the text value
114+
* @returns MetadataLinkValue object
115+
*/
116+
private createMetadataLinkValue(href: string, text: string): MetadataLinkValue {
117+
text = text.trim() !== '' ? text : href;
118+
return { href, text };
119+
}
120+
83121
/**
84122
* Set href and text of the component based on urn
85-
* and the given metadata value
123+
* and the given metadata value.
124+
* Is handling the case when the urn is configured in the default-app-config
125+
* and the link is pre-configured.
86126
* @param metadataValue the metadata value
87127
* @param urn URN type (doi, hdl, mailto)
88128
*/
89129
composeLink(metadataValue: string, urn: string): MetadataLinkValue {
130+
const subtypeValue = this.getIdentifierSubtypeValue();
131+
132+
if (hasValue(subtypeValue)) {
133+
const href = this.validateLink(metadataValue) ? metadataValue : `${subtypeValue.link}/${metadataValue}`;
134+
return this.createMetadataLinkValue(href, metadataValue);
135+
}
136+
90137
let value = metadataValue;
91-
const rep = urn + ':';
138+
const rep = `${urn}:`;
92139
if (metadataValue.startsWith(rep)) {
93140
value = metadataValue.replace(rep, '');
94141
}
95142
const href = this.resolver.getBaseUrl(urn) + value;
96-
const text = isNotEmpty(value) && value !== '' ? value : href;
97-
return {
98-
href,
99-
text
100-
};
143+
return this.createMetadataLinkValue(href, value);
101144
}
102145

103146
ngOnInit(): void {
104147
this.identifier = this.getIdentifierFromValue();
148+
this.setIconDetails();
149+
}
150+
151+
/**
152+
* Sets the icon details based on the identifier subtype configuration.
153+
* If the identifier subtype is not empty, it searches for the subtype with a matching name to the rendering subtype.
154+
* If a matching subtype is found, it sets the icon position, subtype icon, and icon link based on the subtype's properties.
155+
*/
156+
private setIconDetails() {
157+
const subtypeVal = this.getIdentifierSubtypeValue();
158+
if (hasNoValue(subtypeVal)) {
159+
return;
160+
}
161+
this.iconPosition = subtypeVal.iconPosition;
162+
this.subTypeIcon = subtypeVal.iconPosition !== IdentifierSubtypesIconPositionEnum.NONE ? subtypeVal?.icon : '';
163+
this.iconLink = subtypeVal?.link;
164+
}
165+
166+
/**
167+
* Retrieves the value of the identifier subtype configuration based on the rendering subtype.
168+
* @returns The identifier subtype configuration object.
169+
*/
170+
private getIdentifierSubtypeValue(): IdentifierSubtypesConfig {
171+
if (isNotEmpty(this.identifierSubtypeConfig)) {
172+
const subtypeVal = this.identifierSubtypeConfig.find((subtype) => subtype.name === this.renderingSubType);
173+
return subtypeVal;
174+
}
175+
}
176+
177+
/**
178+
* Check if the given link is valid
179+
* @param link the link to check
180+
* @returns true if the link is valid, false otherwise
181+
*/
182+
private validateLink(link: string): boolean {
183+
const urlRegex = /^(http|https):\/\/[^ "]+$/;
184+
return urlRegex.test(link);
105185
}
106186
}
187+
188+

src/config/app-config.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { SearchResultConfig } from './search-result-config.interface';
3434
import { MiradorConfig } from './mirador-config.interfaces';
3535
import { LoaderConfig } from './loader-config.interfaces';
3636
import { MetaTagsConfig } from './meta-tags.config';
37+
import { IdentifierSubtypesConfig } from './identifier-subtypes-config.interface';
3738
import { DatadogRumConfig } from './datadog-rum-config.interfaces';
3839

3940
interface AppConfig extends Config {
@@ -75,6 +76,7 @@ interface AppConfig extends Config {
7576
mirador: MiradorConfig;
7677
loader: LoaderConfig;
7778
metaTags: MetaTagsConfig;
79+
identifierSubtypes: IdentifierSubtypesConfig[];
7880
datadogRum?: DatadogRumConfig;
7981
}
8082

src/config/default-app-config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { SearchResultConfig } from './search-result-config.interface';
3737
import { MiradorConfig } from './mirador-config.interfaces';
3838
import { LoaderConfig } from './loader-config.interfaces';
3939
import { MetaTagsConfig } from './meta-tags.config';
40+
import { IdentifierSubtypesConfig, IdentifierSubtypesIconPositionEnum } from './identifier-subtypes-config.interface';
4041
import { DatadogRumConfig } from './datadog-rum-config.interfaces';
4142

4243
export class DefaultAppConfig implements AppConfig {
@@ -806,6 +807,14 @@ export class DefaultAppConfig implements AppConfig {
806807
'DSpace-CRIS enables secure, integrated and interoperable research information and data management – in a single solution.'
807808
};
808809

810+
identifierSubtypes: IdentifierSubtypesConfig[] = [
811+
{
812+
name: 'ror',
813+
icon: 'assets/images/ror.logo.icon.svg',
814+
iconPosition: IdentifierSubtypesIconPositionEnum.LEFT,
815+
link: 'https://ror.org'
816+
}
817+
];
809818
datadogRum: DatadogRumConfig = {
810819
clientToken: undefined,
811820
applicationId: undefined,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Represents the configuration for identifier subtypes.
3+
*/
4+
export interface IdentifierSubtypesConfig {
5+
name: string; // The name of the identifier subtype
6+
icon: string; // The icon to display for the identifier subtype
7+
iconPosition: IdentifierSubtypesIconPositionEnum; // The position of the icon relative to the identifier
8+
link: string; // The link to navigate to when the icon is clicked
9+
}
10+
11+
export enum IdentifierSubtypesIconPositionEnum {
12+
NONE = 'NONE',
13+
LEFT = 'LEFT',
14+
RIGHT = 'RIGHT',
15+
}

src/environments/environment.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BuildConfig } from 'src/config/build-config.interface';
33
import { RestRequestMethod } from '../app/core/data/rest-request-method';
44
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
55
import { AdvancedAttachmentElementType } from '../config/advanced-attachment-rendering.config';
6+
import { IdentifierSubtypesIconPositionEnum } from 'src/config/identifier-subtypes-config.interface';
67

78
export const environment: BuildConfig = {
89
production: false,
@@ -588,5 +589,14 @@ export const environment: BuildConfig = {
588589
metaTags: {
589590
defaultLogo: '/assets/images/dspace-cris-logo.png',
590591
defaultDescription: 'DSpace is the most widely used repository software with more than 3000 installations around the world. It is free, open source and completely customisable to fit the needs of any organisation.'
591-
}
592+
},
593+
594+
identifierSubtypes: [
595+
{
596+
name: 'ror',
597+
icon: 'assets/images/ror.logo.icon.svg',
598+
iconPosition: IdentifierSubtypesIconPositionEnum.LEFT,
599+
link: 'https://ror.org'
600+
}
601+
]
592602
};

src/styles/_custom_variables.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,6 @@
145145

146146
--ds-comcol-logo-max-width: 500px;
147147
--ds-comcol-logo-max-height: 500px;
148+
149+
--ds-identifier-sybetype-icon-height: 24px;
148150
}

0 commit comments

Comments
 (0)