Skip to content

Commit af1bd74

Browse files
committed
Merged dspace-cris-2023_02_x into task/dspace-cris-2023_02_x/DSC-1794
2 parents 1ef5738 + 2cbd7fe commit af1bd74

52 files changed

Lines changed: 902 additions & 379 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/app/core/services/internal-link.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('InternalLinkService', () => {
5858

5959
it('should return unchanged link for external link', () => {
6060
const result = service.getRelativePath('https://externalDomain/my-link');
61-
expect(result).toBe('https://externalDomain/my-link');
61+
expect(result).toBe('/https://externalDomain/my-link');
6262
});
6363

6464
it('should return unchanged link for internal link with leading "/"', () => {

src/app/core/services/internal-link.service.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,41 @@ export class InternalLinkService {
3939
* @returns The relative path for the given internal link.
4040
*/
4141
public getRelativePath(link: string): string {
42-
// Create a Domain object for the provided link
42+
// Obtaining the base URL, disregarding query parameters
43+
const baseUrl = link.split('?')[0];
4344
const currentDomain = new URL(this.currentURL).hostname;
4445

45-
if (link.startsWith(this.currentURL)) {
46-
const currentSegments = link.substring(this.currentURL.length);
46+
if (baseUrl.startsWith(this.currentURL) || baseUrl.startsWith(currentDomain)) {
47+
const base = baseUrl.startsWith(this.currentURL) ? this.currentURL : currentDomain;
48+
const currentSegments = baseUrl.substring(base.length);
4749
return currentSegments.startsWith('/') ? currentSegments : `/${currentSegments}`;
4850
}
4951

50-
if (link.startsWith(currentDomain)) {
51-
const currentSegments = link.substring(currentDomain.length);
52-
return currentSegments.startsWith('/') ? currentSegments : `/${currentSegments}`;
52+
return baseUrl.startsWith('/') ? baseUrl : `/${baseUrl}`;
53+
}
54+
55+
/**
56+
* Parse the query parameters from a given URL link.
57+
*
58+
* @param link The URL link containing query parameters.
59+
* @returns An object containing the parsed query parameters.
60+
*/
61+
public getQueryParams(link: string): Record<string, string> {
62+
const queryParams: Record<string, string> = {};
63+
64+
const queryStringStartIndex = link.indexOf('?');
65+
if (queryStringStartIndex !== -1) {
66+
const paramsString = link.substring(queryStringStartIndex + 1);
67+
const paramsArray = paramsString.split('&');
68+
69+
paramsArray.forEach(param => {
70+
const [key, value] = param.split('=');
71+
if (key && value) {
72+
queryParams[key] = decodeURIComponent(value.replace(/\+/g, ' '));
73+
}
74+
});
5375
}
5476

55-
return link;
77+
return queryParams;
5678
}
5779
}

src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.html

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,32 @@
1111
</span>
1212
</div>
1313
<div [ngClass]="showThumbnails ? 'col-9 col-xl-10' : 'col-md-12'">
14-
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
15-
<ds-truncatable [id]="dso.id">
16-
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" [attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
17-
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
18-
[innerHTML]="dsoTitle"></a>
19-
<span *ngIf="linkType == linkTypes.None"
20-
class="lead item-list-title dont-break-out"
21-
[innerHTML]="dsoTitle"></span>
22-
<span class="text-muted">
23-
<ds-truncatable-part [id]="dso.id" [minLines]="1">
24-
<span *ngIf="dso.allMetadata(['creativeworkseries.issn']).length > 0"
25-
class="item-list-journals">
26-
<span *ngFor="let value of allMetadataValues(['creativeworkseries.issn']); let last=last;">
27-
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
28-
</span>
29-
</span>
30-
</ds-truncatable-part>
31-
</span>
32-
</ds-truncatable>
14+
<div class="d-flex justify-content-between">
15+
<div class="flex-fill">
16+
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
17+
<ds-truncatable [id]="dso.id">
18+
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" [attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
19+
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
20+
[innerHTML]="dsoTitle"></a>
21+
<span *ngIf="linkType == linkTypes.None"
22+
class="lead item-list-title dont-break-out"
23+
[innerHTML]="dsoTitle"></span>
24+
<span class="text-muted">
25+
<ds-truncatable-part [id]="dso.id" [minLines]="1">
26+
<span *ngIf="dso.allMetadata(['creativeworkseries.issn']).length > 0"
27+
class="item-list-journals">
28+
<span *ngFor="let value of allMetadataValues(['creativeworkseries.issn']); let last=last;">
29+
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
30+
</span>
31+
</span>
32+
</ds-truncatable-part>
33+
</span>
34+
</ds-truncatable>
35+
<ds-metric-badges *ngIf="showMetrics" class="d-block clearfix" [item]="dso"></ds-metric-badges>
36+
</div>
37+
<div class="align-self-center">
38+
<ds-metric-donuts [item]="dso"></ds-metric-donuts>
39+
</div>
40+
</div>
3341
</div>
3442
</div>

src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,29 @@
1818
</span>
1919
</div>
2020
<div [ngClass]="showThumbnails ? 'col-9 col-xl-10' : 'col-md-12'">
21-
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
22-
<ds-truncatable [id]="dso.id">
23-
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
24-
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
25-
[routerLink]="[itemPageRoute]" class="lead"
26-
[innerHTML]="dsoTitle || ('orgunit.listelement.no-title' | translate)"></a>
27-
<span *ngIf="linkType == linkTypes.None"
28-
class="lead"
29-
[innerHTML]="dsoTitle || ('orgunit.listelement.no-title' | translate)"></span>
30-
<div *ngIf="dso.allMetadata(['dc.description.*']).length > 0" class="text-muted">
31-
<ds-truncatable-part [id]="dso.id" [minLines]="3">
32-
<span class="item-list-org-unit-description" [innerHTML]="firstMetadataValue('dc.description.abstract')"></span>
33-
</ds-truncatable-part>
34-
</div>
35-
<ds-additional-metadata [object]="dso"></ds-additional-metadata>
36-
</ds-truncatable>
21+
<div class="d-flex justify-content-between">
22+
<div class="flex-fill">
23+
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
24+
<ds-truncatable [id]="dso.id">
25+
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
26+
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
27+
[routerLink]="[itemPageRoute]" class="lead"
28+
[innerHTML]="dsoTitle || ('orgunit.listelement.no-title' | translate)"></a>
29+
<span *ngIf="linkType == linkTypes.None"
30+
class="lead"
31+
[innerHTML]="dsoTitle || ('orgunit.listelement.no-title' | translate)"></span>
32+
<div *ngIf="dso.allMetadata(['dc.description.*']).length > 0" class="text-muted">
33+
<ds-truncatable-part [id]="dso.id" [minLines]="3">
34+
<span class="item-list-org-unit-description" [innerHTML]="firstMetadataValue('dc.description.abstract')"></span>
35+
</ds-truncatable-part>
36+
</div>
37+
<ds-additional-metadata [object]="dso"></ds-additional-metadata>
38+
</ds-truncatable>
39+
<ds-metric-badges *ngIf="showMetrics" class="d-block clearfix" [item]="dso"></ds-metric-badges>
40+
</div>
41+
<div class="align-self-center" *ngIf="showMetrics">
42+
<ds-metric-donuts [item]="dso"></ds-metric-donuts>
43+
</div>
3744
</div>
45+
</div>
3846
</div>

src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
</div>
4242
<ds-additional-metadata [object]="dso"></ds-additional-metadata>
4343
</ds-truncatable>
44+
<ds-metric-badges *ngIf="showMetrics" class="d-block clearfix" [item]="dso"></ds-metric-badges>
4445
</div>
4546
<div class="align-self-center" *ngIf="showMetrics">
4647
<ds-metric-donuts [item]="dso"></ds-metric-donuts>

src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.html

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,34 @@
1818
</span>
1919
</div>
2020
<div [ngClass]="showThumbnails ? 'col-9 col-xl-10' : 'col-md-12'">
21-
<ds-truncatable [id]="dso.id">
22-
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
23-
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
24-
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
25-
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
26-
[innerHTML]="dsoTitle"></a>
27-
<span *ngIf="linkType == linkTypes.None"
28-
class="lead item-list-title dont-break-out"
29-
[innerHTML]="dsoTitle"></span>
30-
<!--<span class="text-muted">-->
31-
<!--<ds-truncatable-part [id]="dso.id" [minLines]="1">-->
32-
<!--<span *ngIf="dso.allMetadata(['project.identifier.status']).length > 0"-->
33-
<!--class="item-list-status">-->
34-
<!--<span *ngFor="let value of allMetadataValues(['project.identifier.status']); let last=last;">-->
35-
<!--<span [innerHTML]="value"><span [innerHTML]="value"></span></span>-->
36-
<!--</span>-->
37-
<!--</span>-->
38-
<!--</ds-truncatable-part>-->
39-
<!--</span>-->
40-
<ds-additional-metadata [object]="dso"></ds-additional-metadata>
41-
</ds-truncatable>
21+
<div class="d-flex justify-content-between">
22+
<div class="flex-fill">
23+
<ds-truncatable [id]="dso.id">
24+
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
25+
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
26+
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
27+
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
28+
[innerHTML]="dsoTitle"></a>
29+
<span *ngIf="linkType == linkTypes.None"
30+
class="lead item-list-title dont-break-out"
31+
[innerHTML]="dsoTitle"></span>
32+
<!--<span class="text-muted">-->
33+
<!--<ds-truncatable-part [id]="dso.id" [minLines]="1">-->
34+
<!--<span *ngIf="dso.allMetadata(['project.identifier.status']).length > 0"-->
35+
<!--class="item-list-status">-->
36+
<!--<span *ngFor="let value of allMetadataValues(['project.identifier.status']); let last=last;">-->
37+
<!--<span [innerHTML]="value"><span [innerHTML]="value"></span></span>-->
38+
<!--</span>-->
39+
<!--</span>-->
40+
<!--</ds-truncatable-part>-->
41+
<!--</span>-->
42+
<ds-additional-metadata [object]="dso"></ds-additional-metadata>
43+
</ds-truncatable>
44+
<ds-metric-badges *ngIf="showMetrics" class="d-block clearfix" [item]="dso"></ds-metric-badges>
45+
</div>
46+
<div class="align-self-center">
47+
<ds-metric-donuts [item]="dso"></ds-metric-donuts>
48+
</div>
49+
</div>
4250
</div>
4351
</div>

src/app/register-page/create-profile/create-profile.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ <h3 class="mb-4">{{'register-page.create-profile.header' | translate}}</h3>
1414
<div class="card-body">
1515
<div class="row">
1616
<div class="col-12">
17-
<label class="font-weight-bold"
17+
<label class="font-weight-bold mr-4"
1818
for="email">{{'register-page.create-profile.identification.email' | translate}}</label>
1919
<span id="email">{{(registration$ |async).email}}</span></div>
2020
</div>
Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
<div class="d-flex space-children-mr justify-content-end" *ngIf="contextMenuObject">
2-
<ng-container *ngFor="let entry of (getStandAloneMenuEntries() | async)">
3-
<ng-container *ngComponentOutlet="entry; injector: objectInjector;"></ng-container>
4-
</ng-container>
5-
<div ngbDropdown #itemOptions="ngbDropdown" placement="bottom-right"
6-
class="float-right ml-1" [ngClass]="optionCount === 0 ? 'd-none' : 'd-inline-block'">
7-
<button class="btn btn-outline-primary" id="context-menu" ngbDropdownToggle>
8-
<i class="fas fa-ellipsis-h" aria-hidden="true"></i>
9-
</button>
10-
<div id="itemOptionsDropdownMenu" aria-labelledby="context-menu" ngbDropdownMenu>
11-
<h6 class="dropdown-header">{{'context-menu.actions.label' | translate}}</h6>
12-
<ng-container *ngFor="let entry of (getContextMenuEntries() | async)">
13-
<ng-container *ngComponentOutlet="entry; injector: objectInjector;"></ng-container>
14-
</ng-container>
1+
<div *ngIf="contextMenuObject">
2+
<div class="d-flex space-children-mr justify-content-end" *dsRenderOnlyForBrowser="true">
3+
<ng-container *ngFor="let entry of (getStandAloneMenuEntries() | async)">
4+
<ng-container *ngComponentOutlet="entry; injector: objectInjector;"></ng-container>
5+
</ng-container>
6+
<div ngbDropdown #itemOptions="ngbDropdown" placement="bottom-right"
7+
class="float-right ml-1" [ngClass]="optionCount === 0 ? 'd-none' : 'd-inline-block'">
8+
<button class="btn btn-outline-primary" id="context-menu" ngbDropdownToggle>
9+
<i class="fas fa-ellipsis-h" aria-hidden="true"></i>
10+
</button>
11+
<div id="itemOptionsDropdownMenu" aria-labelledby="context-menu" ngbDropdownMenu>
12+
<h6 class="dropdown-header">{{ 'context-menu.actions.label' | translate }}</h6>
13+
<ng-container *ngFor="let entry of (getContextMenuEntries() | async)">
14+
<ng-container *ngComponentOutlet="entry; injector: objectInjector;"></ng-container>
15+
</ng-container>
16+
</div>
1517
</div>
1618
</div>
1719
</div>

src/app/shared/context-menu/context-menu.component.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2-
import { Component, Injector, NO_ERRORS_SCHEMA } from '@angular/core';
2+
import { Component, Injector, NO_ERRORS_SCHEMA, PLATFORM_ID } from '@angular/core';
33
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
44
import { By } from '@angular/platform-browser';
55

@@ -27,6 +27,7 @@ import { NotificationsServiceStub } from '../testing/notifications-service.stub'
2727
import { AuthService } from '../../core/auth/auth.service';
2828
import { EPersonMock } from '../testing/eperson.mock';
2929
import { ItemExportFormConfiguration, ItemExportService } from '../search/item-export/item-export.service';
30+
import { BrowserOnlyDirective } from '../utils/browser-only.directive';
3031

3132
describe('ContextMenuComponent', () => {
3233
let component: ContextMenuComponent;
@@ -98,7 +99,8 @@ describe('ContextMenuComponent', () => {
9899
useClass: TranslateLoaderMock
99100
}
100101
}),
101-
NgbDropdownModule
102+
NgbDropdownModule,
103+
BrowserOnlyDirective
102104
],
103105
declarations: [ContextMenuComponent, TestComponent, ExportItemMenuComponent, StatisticsMenuComponent, SubscriptionMenuComponent],
104106
providers: [
@@ -110,6 +112,7 @@ describe('ContextMenuComponent', () => {
110112
{ provide: AuthService, useValue: authService },
111113
{ provide: AuthorizationDataService, useValue: authorizationDataService },
112114
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
115+
{ provide: PLATFORM_ID, useValue: 'browser' },
113116
Injector
114117
],
115118
schemas: [NO_ERRORS_SCHEMA]

src/app/shared/context-menu/context-menu.component.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ export class ContextMenuComponent implements OnInit {
6161
private cdr: ChangeDetectorRef,
6262
private configurationService: ConfigurationDataService,
6363
private injector: Injector
64-
) {
65-
}
64+
) { }
6665

6766
ngOnInit(): void {
6867
this.objectInjector = Injector.create({
@@ -91,7 +90,7 @@ export class ContextMenuComponent implements OnInit {
9190
private retrieveSelectedContextMenuEntries(isStandAlone: boolean): Observable<any[]> {
9291
const list = this.contextMenuObjectType ? getContextMenuEntriesForDSOType(this.contextMenuObjectType) : [];
9392
return from(list).pipe(
94-
filter((renderOptions: ContextMenuEntryRenderOptions) => isNotEmpty(renderOptions ?.componentRef) && renderOptions ?.isStandAlone === isStandAlone),
93+
filter((renderOptions: ContextMenuEntryRenderOptions) => isNotEmpty(renderOptions?.componentRef) && renderOptions?.isStandAlone === isStandAlone),
9594
map((renderOptions: ContextMenuEntryRenderOptions) => renderOptions.componentRef),
9695
concatMap((constructor: GenericConstructor<ContextMenuEntryComponent>) => {
9796
const entryComp: ContextMenuEntryComponent = new constructor();

0 commit comments

Comments
 (0)