Skip to content

Commit c515cb2

Browse files
authored
Merge pull request DSpace#2562 from alexandrevryghem/theme-fixes_contribute-main
Fix match theme by handle with canonical prefix https://hdl.handle.net/ not working
2 parents 55435a2 + 7529ed8 commit c515cb2

22 files changed

Lines changed: 495 additions & 302 deletions

src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
22
import { ActivatedRoute } from '@angular/router';
33

4-
import { BehaviorSubject, combineLatest as observableCombineLatest } from 'rxjs';
4+
import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription } from 'rxjs';
55

66
import { RemoteData } from '../../core/data/remote-data';
77
import { Collection } from '../../core/shared/collection.model';
@@ -50,6 +50,8 @@ export class CommunityPageSubCollectionListComponent implements OnInit, OnDestro
5050
*/
5151
subCollectionsRDObs: BehaviorSubject<RemoteData<PaginatedList<Collection>>> = new BehaviorSubject<RemoteData<PaginatedList<Collection>>>({} as any);
5252

53+
subscriptions: Subscription[] = [];
54+
5355
constructor(
5456
protected cds: CollectionDataService,
5557
protected paginationService: PaginationService,
@@ -77,7 +79,7 @@ export class CommunityPageSubCollectionListComponent implements OnInit, OnDestro
7779
const pagination$ = this.paginationService.getCurrentPagination(this.config.id, this.config);
7880
const sort$ = this.paginationService.getCurrentSort(this.config.id, this.sortConfig);
7981

80-
observableCombineLatest([pagination$, sort$]).pipe(
82+
this.subscriptions.push(observableCombineLatest([pagination$, sort$]).pipe(
8183
switchMap(([currentPagination, currentSort]) => {
8284
return this.cds.findByParent(this.community.id, {
8385
currentPage: currentPagination.currentPage,
@@ -87,11 +89,12 @@ export class CommunityPageSubCollectionListComponent implements OnInit, OnDestro
8789
})
8890
).subscribe((results) => {
8991
this.subCollectionsRDObs.next(results);
90-
});
92+
}));
9193
}
9294

9395
ngOnDestroy(): void {
94-
this.paginationService.clearPagination(this.config.id);
96+
this.paginationService.clearPagination(this.config?.id);
97+
this.subscriptions.map((subscription: Subscription) => subscription.unsubscribe());
9598
}
9699

97100
}

src/app/community-page/sub-community-list/community-page-sub-community-list.component.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
22
import { ActivatedRoute } from '@angular/router';
33

4-
import { BehaviorSubject, combineLatest as observableCombineLatest } from 'rxjs';
4+
import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription } from 'rxjs';
55

66
import { RemoteData } from '../../core/data/remote-data';
77
import { Community } from '../../core/shared/community.model';
@@ -52,6 +52,8 @@ export class CommunityPageSubCommunityListComponent implements OnInit, OnDestroy
5252
*/
5353
subCommunitiesRDObs: BehaviorSubject<RemoteData<PaginatedList<Community>>> = new BehaviorSubject<RemoteData<PaginatedList<Community>>>({} as any);
5454

55+
subscriptions: Subscription[] = [];
56+
5557
constructor(
5658
protected cds: CommunityDataService,
5759
protected paginationService: PaginationService,
@@ -79,7 +81,7 @@ export class CommunityPageSubCommunityListComponent implements OnInit, OnDestroy
7981
const pagination$ = this.paginationService.getCurrentPagination(this.config.id, this.config);
8082
const sort$ = this.paginationService.getCurrentSort(this.config.id, this.sortConfig);
8183

82-
observableCombineLatest([pagination$, sort$]).pipe(
84+
this.subscriptions.push(observableCombineLatest([pagination$, sort$]).pipe(
8385
switchMap(([currentPagination, currentSort]) => {
8486
return this.cds.findByParent(this.community.id, {
8587
currentPage: currentPagination.currentPage,
@@ -89,11 +91,12 @@ export class CommunityPageSubCommunityListComponent implements OnInit, OnDestroy
8991
})
9092
).subscribe((results) => {
9193
this.subCommunitiesRDObs.next(results);
92-
});
94+
}));
9395
}
9496

9597
ngOnDestroy(): void {
96-
this.paginationService.clearPagination(this.config.id);
98+
this.paginationService.clearPagination(this.config?.id);
99+
this.subscriptions.map((subscription: Subscription) => subscription.unsubscribe());
97100
}
98101

99102
}

src/app/core/data/configuration-data.service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable max-classes-per-file */
21
import { Injectable } from '@angular/core';
32
import { Observable } from 'rxjs';
43
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';

src/app/curation-form/curation-form.component.spec.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
1+
import { ComponentFixture, TestBed, waitForAsync, fakeAsync, flush } from '@angular/core/testing';
22
import { TranslateModule } from '@ngx-translate/core';
33
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
44
import { CurationFormComponent } from './curation-form.component';
@@ -16,6 +16,7 @@ import { ConfigurationDataService } from '../core/data/configuration-data.servic
1616
import { ConfigurationProperty } from '../core/shared/configuration-property.model';
1717
import { getProcessDetailRoute } from '../process-page/process-page-routing.paths';
1818
import { HandleService } from '../shared/handle.service';
19+
import { of as observableOf } from 'rxjs';
1920

2021
describe('CurationFormComponent', () => {
2122
let comp: CurationFormComponent;
@@ -54,7 +55,7 @@ describe('CurationFormComponent', () => {
5455
});
5556

5657
handleService = {
57-
normalizeHandle: (a) => a
58+
normalizeHandle: (a: string) => observableOf(a),
5859
} as any;
5960

6061
notificationsService = new NotificationsServiceStub();
@@ -151,12 +152,13 @@ describe('CurationFormComponent', () => {
151152
], []);
152153
});
153154

154-
it(`should show an error notification and return when an invalid dsoHandle is provided`, () => {
155+
it(`should show an error notification and return when an invalid dsoHandle is provided`, fakeAsync(() => {
155156
comp.dsoHandle = 'test-handle';
156-
spyOn(handleService, 'normalizeHandle').and.returnValue(null);
157+
spyOn(handleService, 'normalizeHandle').and.returnValue(observableOf(null));
157158
comp.submit();
159+
flush();
158160

159161
expect(notificationsService.error).toHaveBeenCalled();
160162
expect(scriptDataService.invoke).not.toHaveBeenCalled();
161-
});
163+
}));
162164
});
Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
1+
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
22
import { ScriptDataService } from '../core/data/processes/script-data.service';
33
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
4-
import { getFirstCompletedRemoteData } from '../core/shared/operators';
5-
import { find, map } from 'rxjs/operators';
4+
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
5+
import { map } from 'rxjs/operators';
66
import { NotificationsService } from '../shared/notifications/notifications.service';
77
import { TranslateService } from '@ngx-translate/core';
88
import { hasValue, isEmpty, isNotEmpty } from '../shared/empty.util';
99
import { RemoteData } from '../core/data/remote-data';
1010
import { Router } from '@angular/router';
11-
import { ProcessDataService } from '../core/data/processes/process-data.service';
1211
import { Process } from '../process-page/processes/process.model';
1312
import { ConfigurationDataService } from '../core/data/configuration-data.service';
1413
import { ConfigurationProperty } from '../core/shared/configuration-property.model';
15-
import { Observable } from 'rxjs';
14+
import { Observable, Subscription } from 'rxjs';
1615
import { getProcessDetailRoute } from '../process-page/process-page-routing.paths';
1716
import { HandleService } from '../shared/handle.service';
1817

1918
export const CURATION_CFG = 'plugin.named.org.dspace.curate.CurationTask';
19+
2020
/**
2121
* Component responsible for rendering the Curation Task form
2222
*/
2323
@Component({
2424
selector: 'ds-curation-form',
2525
templateUrl: './curation-form.component.html'
2626
})
27-
export class CurationFormComponent implements OnInit {
27+
export class CurationFormComponent implements OnDestroy, OnInit {
2828

2929
config: Observable<RemoteData<ConfigurationProperty>>;
3030
tasks: string[];
@@ -33,10 +33,11 @@ export class CurationFormComponent implements OnInit {
3333
@Input()
3434
dsoHandle: string;
3535

36+
subs: Subscription[] = [];
37+
3638
constructor(
3739
private scriptDataService: ScriptDataService,
3840
private configurationDataService: ConfigurationDataService,
39-
private processDataService: ProcessDataService,
4041
private notificationsService: NotificationsService,
4142
private translateService: TranslateService,
4243
private handleService: HandleService,
@@ -45,23 +46,26 @@ export class CurationFormComponent implements OnInit {
4546
) {
4647
}
4748

49+
ngOnDestroy(): void {
50+
this.subs.forEach((sub: Subscription) => sub.unsubscribe());
51+
}
52+
4853
ngOnInit(): void {
4954
this.form = new UntypedFormGroup({
5055
task: new UntypedFormControl(''),
5156
handle: new UntypedFormControl('')
5257
});
5358

5459
this.config = this.configurationDataService.findByPropertyName(CURATION_CFG);
55-
this.config.pipe(
56-
find((rd: RemoteData<ConfigurationProperty>) => rd.hasSucceeded),
57-
map((rd: RemoteData<ConfigurationProperty>) => rd.payload)
58-
).subscribe((configProperties) => {
60+
this.subs.push(this.config.pipe(
61+
getFirstSucceededRemoteDataPayload(),
62+
).subscribe((configProperties: ConfigurationProperty) => {
5963
this.tasks = configProperties.values
6064
.filter((value) => isNotEmpty(value) && value.includes('='))
6165
.map((value) => value.split('=')[1].trim());
6266
this.form.get('task').patchValue(this.tasks[0]);
6367
this.cdr.detectChanges();
64-
});
68+
}));
6569
}
6670

6771
/**
@@ -77,33 +81,41 @@ export class CurationFormComponent implements OnInit {
7781
*/
7882
submit() {
7983
const taskName = this.form.get('task').value;
80-
let handle;
84+
let handle$: Observable<string | null>;
8185
if (this.hasHandleValue()) {
82-
handle = this.handleService.normalizeHandle(this.dsoHandle);
83-
if (isEmpty(handle)) {
84-
this.notificationsService.error(this.translateService.get('curation.form.submit.error.head'),
85-
this.translateService.get('curation.form.submit.error.invalid-handle'));
86-
return;
87-
}
86+
handle$ = this.handleService.normalizeHandle(this.dsoHandle).pipe(
87+
map((handle: string | null) => {
88+
if (isEmpty(handle)) {
89+
this.notificationsService.error(this.translateService.get('curation.form.submit.error.head'),
90+
this.translateService.get('curation.form.submit.error.invalid-handle'));
91+
}
92+
return handle;
93+
}),
94+
);
8895
} else {
89-
handle = this.handleService.normalizeHandle(this.form.get('handle').value);
90-
if (isEmpty(handle)) {
91-
handle = 'all';
92-
}
96+
handle$ = this.handleService.normalizeHandle(this.form.get('handle').value).pipe(
97+
map((handle: string | null) => isEmpty(handle) ? 'all' : handle),
98+
);
9399
}
94100

95-
this.scriptDataService.invoke('curate', [
96-
{ name: '-t', value: taskName },
97-
{ name: '-i', value: handle },
98-
], []).pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<Process>) => {
99-
if (rd.hasSucceeded) {
100-
this.notificationsService.success(this.translateService.get('curation.form.submit.success.head'),
101-
this.translateService.get('curation.form.submit.success.content'));
102-
this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
103-
} else {
104-
this.notificationsService.error(this.translateService.get('curation.form.submit.error.head'),
105-
this.translateService.get('curation.form.submit.error.content'));
101+
this.subs.push(handle$.subscribe((handle: string) => {
102+
if (hasValue(handle)) {
103+
this.subs.push(this.scriptDataService.invoke('curate', [
104+
{ name: '-t', value: taskName },
105+
{ name: '-i', value: handle },
106+
], []).pipe(
107+
getFirstCompletedRemoteData(),
108+
).subscribe((rd: RemoteData<Process>) => {
109+
if (rd.hasSucceeded) {
110+
this.notificationsService.success(this.translateService.get('curation.form.submit.success.head'),
111+
this.translateService.get('curation.form.submit.success.content'));
112+
void this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
113+
} else {
114+
this.notificationsService.error(this.translateService.get('curation.form.submit.error.head'),
115+
this.translateService.get('curation.form.submit.error.content'));
116+
}
117+
}));
106118
}
107-
});
119+
}));
108120
}
109121
}

src/app/root/root.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { AuthService } from '../core/auth/auth.service';
1313
import { CSSVariableService } from '../shared/sass-helper/css-variable.service';
1414
import { MenuService } from '../shared/menu/menu.service';
1515
import { HostWindowService } from '../shared/host-window.service';
16-
import { ThemeConfig } from '../../config/theme.model';
16+
import { ThemeConfig } from '../../config/theme.config';
1717
import { Angulartics2DSpace } from '../statistics/angulartics/dspace-provider';
1818
import { environment } from '../../environments/environment';
1919
import { slideSidebarPadding } from '../shared/animations/slide';

0 commit comments

Comments
 (0)