Skip to content

Commit cd3c4f2

Browse files
authored
Merge pull request DSpace#3127 from alexandrevryghem/w2p-113560_edit-item-add-relationships-one-by-one_contribute-main
[Port main] Remove Bitstreams on edit-item-page doesn't work
2 parents 605230d + a708175 commit cd3c4f2

7 files changed

Lines changed: 63 additions & 53 deletions

File tree

src/app/bitstream-page/bitstream-page-routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ export const ROUTES: Route[] = [
2424
{
2525
// Resolve XMLUI bitstream download URLs
2626
path: 'handle/:prefix/:suffix/:filename',
27+
component: BitstreamDownloadPageComponent,
2728
canActivate: [legacyBitstreamURLRedirectGuard],
2829
},
2930
{
3031
// Resolve JSPUI bitstream download URLs
3132
path: ':prefix/:suffix/:sequence_id/:filename',
33+
component: BitstreamDownloadPageComponent,
3234
canActivate: [legacyBitstreamURLRedirectGuard],
3335
},
3436
{

src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
<div class="container-fluid">
22
<div class="d-inline-block float-right space-children-mr">
3-
<button class=" btn btn-danger" *ngIf="(isReinstatable() | async) !== true"
4-
[disabled]="(hasChanges() | async) !== true"
3+
<button class=" btn btn-danger" *ngIf="(isReinstatable$ | async) !== true"
4+
[disabled]="(hasChanges$ | async) !== true"
55
(click)="discard()"><i
66
class="fas fa-times"></i>
77
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
88
</button>
9-
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
9+
<button class="btn btn-warning" *ngIf="isReinstatable$ | async"
1010
(click)="reinstate()"><i
1111
class="fas fa-undo-alt"></i>
1212
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
1313
</button>
1414
<button class="btn btn-primary"
15-
[disabled]="(hasChanges() | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
15+
[disabled]="(hasChanges$ | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
1616
(click)="onSubmit()"><i
1717
class="fas fa-save"></i>
1818
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
@@ -44,19 +44,19 @@ <h3 *ngIf="contentSource && (contentSource?.harvestType !== harvestTypeNone)">{{
4444
<div class="row">
4545
<div class="col-12">
4646
<div class="d-inline-block float-right ml-1 space-children-mr">
47-
<button class=" btn btn-danger" *ngIf="(isReinstatable() | async) !== true"
48-
[disabled]="(hasChanges() | async) !== true"
47+
<button class=" btn btn-danger" *ngIf="(isReinstatable$ | async) !== true"
48+
[disabled]="(hasChanges$ | async) !== true"
4949
(click)="discard()"><i
5050
class="fas fa-times"></i>
5151
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
5252
</button>
53-
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
53+
<button class="btn btn-warning" *ngIf="isReinstatable$ | async"
5454
(click)="reinstate()"><i
5555
class="fas fa-undo-alt"></i>
5656
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
5757
</button>
5858
<button class="btn btn-primary"
59-
[disabled]="(hasChanges() | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
59+
[disabled]="(hasChanges$ | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
6060
(click)="onSubmit()"><i
6161
class="fas fa-save"></i>
6262
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
@@ -66,7 +66,7 @@ <h3 *ngIf="contentSource && (contentSource?.harvestType !== harvestTypeNone)">{{
6666
</div>
6767
</div>
6868
<ds-collection-source-controls
69-
[isEnabled]="(hasChanges() | async) !== true"
69+
[isEnabled]="(hasChanges$ | async) !== true"
7070
[shouldShow]="contentSource?.harvestType !== harvestTypeNone"
7171
[collection]="(collectionRD$ |async)?.payload"
7272
>

src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,6 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
249249
*/
250250
formGroup: UntypedFormGroup;
251251

252-
/**
253-
* Subscription to update the current form
254-
*/
255-
updateSub: Subscription;
256-
257252
/**
258253
* The content harvesting type used when harvesting is disabled
259254
*/
@@ -273,28 +268,29 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
273268
*/
274269
displayedNotifications: INotification[] = [];
275270

276-
public constructor(public objectUpdatesService: ObjectUpdatesService,
277-
public notificationsService: NotificationsService,
278-
protected location: Location,
279-
protected formService: DynamicFormService,
280-
protected translate: TranslateService,
281-
protected route: ActivatedRoute,
282-
protected router: Router,
283-
protected collectionService: CollectionDataService,
284-
protected requestService: RequestService) {
285-
super(objectUpdatesService, notificationsService, translate);
271+
subs: Subscription[] = [];
272+
273+
public constructor(
274+
public objectUpdatesService: ObjectUpdatesService,
275+
public notificationsService: NotificationsService,
276+
public translateService: TranslateService,
277+
public router: Router,
278+
protected location: Location,
279+
protected formService: DynamicFormService,
280+
protected route: ActivatedRoute,
281+
protected collectionService: CollectionDataService,
282+
protected requestService: RequestService,
283+
) {
284+
super(objectUpdatesService, notificationsService, translateService, router);
286285
}
287286

288287
/**
289288
* Initialize properties to setup the Field Update and Form
290289
*/
291290
ngOnInit(): void {
291+
super.ngOnInit();
292292
this.notificationsPrefix = 'collection.edit.tabs.source.notifications.';
293293
this.discardTimeOut = environment.collection.edit.undoTimeout;
294-
this.url = this.router.url;
295-
if (this.url.indexOf('?') > 0) {
296-
this.url = this.url.substr(0, this.url.indexOf('?'));
297-
}
298294
this.formGroup = this.formService.createFormGroup(this.formModel);
299295
this.collectionRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));
300296

@@ -308,10 +304,9 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
308304
});
309305

310306
this.updateFieldTranslations();
311-
this.translate.onLangChange
312-
.subscribe(() => {
313-
this.updateFieldTranslations();
314-
});
307+
this.subs.push(this.translateService.onLangChange.subscribe(() => {
308+
this.updateFieldTranslations();
309+
}));
315310
}
316311

317312
/**
@@ -326,7 +321,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
326321
this.update$ = this.objectUpdatesService.getFieldUpdates(this.url, [initialContentSource]).pipe(
327322
map((updates: FieldUpdates) => updates[initialContentSource.uuid]),
328323
);
329-
this.updateSub = this.update$.subscribe((update: FieldUpdate) => {
324+
this.subs.push(this.update$.subscribe((update: FieldUpdate) => {
330325
if (update) {
331326
const field = update.field as ContentSource;
332327
let configId;
@@ -353,7 +348,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
353348
}
354349
this.contentSource.metadataConfigId = configId;
355350
}
356-
});
351+
}));
357352
}
358353

359354
/**
@@ -387,18 +382,18 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
387382
* @param fieldModel
388383
*/
389384
private updateFieldTranslation(fieldModel: DynamicFormControlModel) {
390-
fieldModel.label = this.translate.instant(this.LABEL_KEY_PREFIX + fieldModel.id);
385+
fieldModel.label = this.translateService.instant(this.LABEL_KEY_PREFIX + fieldModel.id);
391386
if (isNotEmpty(fieldModel.validators)) {
392387
fieldModel.errorMessages = {};
393388
Object.keys(fieldModel.validators).forEach((key) => {
394-
fieldModel.errorMessages[key] = this.translate.instant(this.ERROR_KEY_PREFIX + fieldModel.id + '.' + key);
389+
fieldModel.errorMessages[key] = this.translateService.instant(this.ERROR_KEY_PREFIX + fieldModel.id + '.' + key);
395390
});
396391
}
397392
if (fieldModel instanceof DynamicOptionControlModel) {
398393
if (isNotEmpty(fieldModel.options)) {
399394
fieldModel.options.forEach((option) => {
400395
if (hasNoValue(option.label)) {
401-
option.label = this.translate.instant(this.OPTIONS_KEY_PREFIX + fieldModel.id + '.' + option.value);
396+
option.label = this.translateService.instant(this.OPTIONS_KEY_PREFIX + fieldModel.id + '.' + option.value);
402397
}
403398
});
404399
}
@@ -515,8 +510,6 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
515510
* Make sure open subscriptions are closed
516511
*/
517512
ngOnDestroy(): void {
518-
if (this.updateSub) {
519-
this.updateSub.unsubscribe();
520-
}
513+
this.subs.forEach((sub: Subscription) => sub.unsubscribe());
521514
}
522515
}

src/app/item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
5555
*/
5656
updates$: Observable<FieldUpdates>;
5757

58-
hasChanges$: Observable<boolean>;
59-
60-
isReinstatable$: Observable<boolean>;
61-
6258
/**
6359
* Route to the item's page
6460
*/
@@ -78,7 +74,7 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
7874
public translateService: TranslateService,
7975
public route: ActivatedRoute,
8076
) {
81-
super(objectUpdatesService, notificationsService, translateService);
77+
super(objectUpdatesService, notificationsService, translateService, router);
8278
}
8379

8480
/**
@@ -103,11 +99,9 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
10399
this.setItem(rd.payload);
104100
});
105101
}
102+
super.ngOnInit();
106103

107104
this.discardTimeOut = environment.item.edit.undoTimeout;
108-
this.url = this.router.url.split('?')[0];
109-
this.hasChanges$ = this.hasChanges();
110-
this.isReinstatable$ = this.isReinstatable();
111105
this.hasChanges().pipe(first()).subscribe((hasChanges) => {
112106
if (!hasChanges) {
113107
this.initializeOriginalFields();

src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from '@ngx-translate/core';
2121
import { Operation } from 'fast-json-patch';
2222
import {
23+
combineLatest,
2324
Observable,
2425
Subscription,
2526
zip as observableZip,
@@ -273,7 +274,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
273274
*/
274275
isReinstatable(): Observable<boolean> {
275276
return this.bundles$.pipe(
276-
switchMap((bundles: Bundle[]) => observableZip(...bundles.map((bundle: Bundle) => this.objectUpdatesService.isReinstatable(bundle.self)))),
277+
switchMap((bundles: Bundle[]) => combineLatest(bundles.map((bundle: Bundle) => this.objectUpdatesService.isReinstatable(bundle.self)))),
277278
map((reinstatable: boolean[]) => reinstatable.includes(true)),
278279
);
279280
}
@@ -283,7 +284,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
283284
*/
284285
hasChanges(): Observable<boolean> {
285286
return this.bundles$.pipe(
286-
switchMap((bundles: Bundle[]) => observableZip(...bundles.map((bundle: Bundle) => this.objectUpdatesService.hasUpdates(bundle.self)))),
287+
switchMap((bundles: Bundle[]) => combineLatest(bundles.map((bundle: Bundle) => this.objectUpdatesService.hasUpdates(bundle.self)))),
287288
map((hasChanges: boolean[]) => hasChanges.includes(true)),
288289
);
289290
}

src/app/shared/trackable/abstract-trackable.component.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
TestBed,
55
waitForAsync,
66
} from '@angular/core/testing';
7+
import { Router } from '@angular/router';
78
import { TranslateModule } from '@ngx-translate/core';
89
import { getTestScheduler } from 'jasmine-marbles';
910
import { of as observableOf } from 'rxjs';
@@ -16,6 +17,7 @@ import {
1617
} from '../notifications/models/notification.model';
1718
import { NotificationType } from '../notifications/models/notification-type';
1819
import { NotificationsService } from '../notifications/notifications.service';
20+
import { RouterStub } from '../testing/router.stub';
1921
import { AbstractTrackableComponent } from './abstract-trackable.component';
2022

2123
describe('AbstractTrackableComponent', () => {
@@ -35,6 +37,7 @@ describe('AbstractTrackableComponent', () => {
3537
success: successNotification,
3638
},
3739
);
40+
let router: RouterStub;
3841

3942
const url = 'http://test-url.com/test-url';
4043

@@ -50,6 +53,8 @@ describe('AbstractTrackableComponent', () => {
5053
isValidPage: observableOf(true),
5154
},
5255
);
56+
router = new RouterStub();
57+
router.url = url;
5358

5459
scheduler = getTestScheduler();
5560

@@ -58,6 +63,7 @@ describe('AbstractTrackableComponent', () => {
5863
providers: [
5964
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
6065
{ provide: NotificationsService, useValue: notificationsService },
66+
{ provide: Router, useValue: router },
6167
], schemas: [
6268
NO_ERRORS_SCHEMA,
6369
],
@@ -67,7 +73,6 @@ describe('AbstractTrackableComponent', () => {
6773
beforeEach(() => {
6874
fixture = TestBed.createComponent(AbstractTrackableComponent);
6975
comp = fixture.componentInstance;
70-
comp.url = url;
7176

7277
fixture.detectChanges();
7378
});

src/app/shared/trackable/abstract-trackable.component.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { Component } from '@angular/core';
1+
import {
2+
Component,
3+
OnInit,
4+
} from '@angular/core';
5+
import { Router } from '@angular/router';
26
import { TranslateService } from '@ngx-translate/core';
37
import { Observable } from 'rxjs';
48

@@ -13,7 +17,7 @@ import { NotificationsService } from '../notifications/notifications.service';
1317
template: '',
1418
standalone: true,
1519
})
16-
export class AbstractTrackableComponent {
20+
export class AbstractTrackableComponent implements OnInit {
1721

1822
/**
1923
* The time span for being able to undo discarding changes
@@ -23,14 +27,25 @@ export class AbstractTrackableComponent {
2327
public url: string;
2428
public notificationsPrefix = 'static-pages.form.notification';
2529

30+
hasChanges$: Observable<boolean>;
31+
32+
isReinstatable$: Observable<boolean>;
33+
2634
constructor(
2735
public objectUpdatesService: ObjectUpdatesService,
2836
public notificationsService: NotificationsService,
2937
public translateService: TranslateService,
38+
public router: Router,
3039
) {
3140

3241
}
3342

43+
ngOnInit(): void {
44+
this.url = this.router.url.split('?')[0];
45+
this.hasChanges$ = this.hasChanges();
46+
this.isReinstatable$ = this.isReinstatable();
47+
}
48+
3449
/**
3550
* Request the object updates service to discard all current changes to this item
3651
* Shows a notification to remind the user that they can undo this

0 commit comments

Comments
 (0)