Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Port main] Remove Bitstreams on edit-item-page doesn't work #3127

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/bitstream-page/bitstream-page-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export const ROUTES: Route[] = [
{
// Resolve XMLUI bitstream download URLs
path: 'handle/:prefix/:suffix/:filename',
component: BitstreamDownloadPageComponent,
canActivate: [legacyBitstreamURLRedirectGuard],
},
{
// Resolve JSPUI bitstream download URLs
path: ':prefix/:suffix/:sequence_id/:filename',
component: BitstreamDownloadPageComponent,
canActivate: [legacyBitstreamURLRedirectGuard],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<div class="container-fluid">
<div class="d-inline-block float-right space-children-mr">
<button class=" btn btn-danger" *ngIf="(isReinstatable() | async) !== true"
[disabled]="(hasChanges() | async) !== true"
<button class=" btn btn-danger" *ngIf="(isReinstatable$ | async) !== true"
[disabled]="(hasChanges$ | async) !== true"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
<button class="btn btn-warning" *ngIf="isReinstatable$ | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary"
[disabled]="(hasChanges() | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
[disabled]="(hasChanges$ | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
Expand Down Expand Up @@ -44,19 +44,19 @@ <h3 *ngIf="contentSource && (contentSource?.harvestType !== harvestTypeNone)">{{
<div class="row">
<div class="col-12">
<div class="d-inline-block float-right ml-1 space-children-mr">
<button class=" btn btn-danger" *ngIf="(isReinstatable() | async) !== true"
[disabled]="(hasChanges() | async) !== true"
<button class=" btn btn-danger" *ngIf="(isReinstatable$ | async) !== true"
[disabled]="(hasChanges$ | async) !== true"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
<button class="btn btn-warning" *ngIf="isReinstatable$ | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary"
[disabled]="(hasChanges() | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
[disabled]="(hasChanges$ | async) !== true || !isValid() || (initialHarvestType === harvestTypeNone && contentSource.harvestType === initialHarvestType)"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
Expand All @@ -66,7 +66,7 @@ <h3 *ngIf="contentSource && (contentSource?.harvestType !== harvestTypeNone)">{{
</div>
</div>
<ds-collection-source-controls
[isEnabled]="(hasChanges() | async) !== true"
[isEnabled]="(hasChanges$ | async) !== true"
[shouldShow]="contentSource?.harvestType !== harvestTypeNone"
[collection]="(collectionRD$ |async)?.payload"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,6 @@
*/
formGroup: UntypedFormGroup;

/**
* Subscription to update the current form
*/
updateSub: Subscription;

/**
* The content harvesting type used when harvesting is disabled
*/
Expand All @@ -273,28 +268,29 @@
*/
displayedNotifications: INotification[] = [];

public constructor(public objectUpdatesService: ObjectUpdatesService,
public notificationsService: NotificationsService,
protected location: Location,
protected formService: DynamicFormService,
protected translate: TranslateService,
protected route: ActivatedRoute,
protected router: Router,
protected collectionService: CollectionDataService,
protected requestService: RequestService) {
super(objectUpdatesService, notificationsService, translate);
subs: Subscription[] = [];

public constructor(
public objectUpdatesService: ObjectUpdatesService,
public notificationsService: NotificationsService,
public translateService: TranslateService,
public router: Router,
protected location: Location,
protected formService: DynamicFormService,
protected route: ActivatedRoute,
protected collectionService: CollectionDataService,
protected requestService: RequestService,
) {
super(objectUpdatesService, notificationsService, translateService, router);
}

/**
* Initialize properties to setup the Field Update and Form
*/
ngOnInit(): void {
super.ngOnInit();
this.notificationsPrefix = 'collection.edit.tabs.source.notifications.';
this.discardTimeOut = environment.collection.edit.undoTimeout;
this.url = this.router.url;
if (this.url.indexOf('?') > 0) {
this.url = this.url.substr(0, this.url.indexOf('?'));
}
this.formGroup = this.formService.createFormGroup(this.formModel);
this.collectionRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));

Expand All @@ -308,10 +304,9 @@
});

this.updateFieldTranslations();
this.translate.onLangChange
.subscribe(() => {
this.updateFieldTranslations();
});
this.subs.push(this.translateService.onLangChange.subscribe(() => {
this.updateFieldTranslations();

Check warning on line 308 in src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L308 was not covered by tests
}));
}

/**
Expand All @@ -326,7 +321,7 @@
this.update$ = this.objectUpdatesService.getFieldUpdates(this.url, [initialContentSource]).pipe(
map((updates: FieldUpdates) => updates[initialContentSource.uuid]),
);
this.updateSub = this.update$.subscribe((update: FieldUpdate) => {
this.subs.push(this.update$.subscribe((update: FieldUpdate) => {
if (update) {
const field = update.field as ContentSource;
let configId;
Expand All @@ -353,7 +348,7 @@
}
this.contentSource.metadataConfigId = configId;
}
});
}));
}

/**
Expand Down Expand Up @@ -387,18 +382,18 @@
* @param fieldModel
*/
private updateFieldTranslation(fieldModel: DynamicFormControlModel) {
fieldModel.label = this.translate.instant(this.LABEL_KEY_PREFIX + fieldModel.id);
fieldModel.label = this.translateService.instant(this.LABEL_KEY_PREFIX + fieldModel.id);
if (isNotEmpty(fieldModel.validators)) {
fieldModel.errorMessages = {};
Object.keys(fieldModel.validators).forEach((key) => {
fieldModel.errorMessages[key] = this.translate.instant(this.ERROR_KEY_PREFIX + fieldModel.id + '.' + key);
fieldModel.errorMessages[key] = this.translateService.instant(this.ERROR_KEY_PREFIX + fieldModel.id + '.' + key);
});
}
if (fieldModel instanceof DynamicOptionControlModel) {
if (isNotEmpty(fieldModel.options)) {
fieldModel.options.forEach((option) => {
if (hasNoValue(option.label)) {
option.label = this.translate.instant(this.OPTIONS_KEY_PREFIX + fieldModel.id + '.' + option.value);
option.label = this.translateService.instant(this.OPTIONS_KEY_PREFIX + fieldModel.id + '.' + option.value);
}
});
}
Expand Down Expand Up @@ -515,8 +510,6 @@
* Make sure open subscriptions are closed
*/
ngOnDestroy(): void {
if (this.updateSub) {
this.updateSub.unsubscribe();
}
this.subs.forEach((sub: Subscription) => sub.unsubscribe());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
*/
updates$: Observable<FieldUpdates>;

hasChanges$: Observable<boolean>;

isReinstatable$: Observable<boolean>;

/**
* Route to the item's page
*/
Expand All @@ -78,7 +74,7 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
public translateService: TranslateService,
public route: ActivatedRoute,
) {
super(objectUpdatesService, notificationsService, translateService);
super(objectUpdatesService, notificationsService, translateService, router);
}

/**
Expand All @@ -103,11 +99,9 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl
this.setItem(rd.payload);
});
}
super.ngOnInit();

this.discardTimeOut = environment.item.edit.undoTimeout;
this.url = this.router.url.split('?')[0];
this.hasChanges$ = this.hasChanges();
this.isReinstatable$ = this.isReinstatable();
this.hasChanges().pipe(first()).subscribe((hasChanges) => {
if (!hasChanges) {
this.initializeOriginalFields();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from '@ngx-translate/core';
import { Operation } from 'fast-json-patch';
import {
combineLatest,
Observable,
Subscription,
zip as observableZip,
Expand Down Expand Up @@ -273,7 +274,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
*/
isReinstatable(): Observable<boolean> {
return this.bundles$.pipe(
switchMap((bundles: Bundle[]) => observableZip(...bundles.map((bundle: Bundle) => this.objectUpdatesService.isReinstatable(bundle.self)))),
switchMap((bundles: Bundle[]) => combineLatest(bundles.map((bundle: Bundle) => this.objectUpdatesService.isReinstatable(bundle.self)))),
map((reinstatable: boolean[]) => reinstatable.includes(true)),
);
}
Expand All @@ -283,7 +284,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
*/
hasChanges(): Observable<boolean> {
return this.bundles$.pipe(
switchMap((bundles: Bundle[]) => observableZip(...bundles.map((bundle: Bundle) => this.objectUpdatesService.hasUpdates(bundle.self)))),
switchMap((bundles: Bundle[]) => combineLatest(bundles.map((bundle: Bundle) => this.objectUpdatesService.hasUpdates(bundle.self)))),
map((hasChanges: boolean[]) => hasChanges.includes(true)),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { getTestScheduler } from 'jasmine-marbles';
import { of as observableOf } from 'rxjs';
Expand All @@ -16,6 +17,7 @@ import {
} from '../notifications/models/notification.model';
import { NotificationType } from '../notifications/models/notification-type';
import { NotificationsService } from '../notifications/notifications.service';
import { RouterStub } from '../testing/router.stub';
import { AbstractTrackableComponent } from './abstract-trackable.component';

describe('AbstractTrackableComponent', () => {
Expand All @@ -35,6 +37,7 @@ describe('AbstractTrackableComponent', () => {
success: successNotification,
},
);
let router: RouterStub;

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

Expand All @@ -50,6 +53,8 @@ describe('AbstractTrackableComponent', () => {
isValidPage: observableOf(true),
},
);
router = new RouterStub();
router.url = url;

scheduler = getTestScheduler();

Expand All @@ -58,6 +63,7 @@ describe('AbstractTrackableComponent', () => {
providers: [
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
{ provide: NotificationsService, useValue: notificationsService },
{ provide: Router, useValue: router },
], schemas: [
NO_ERRORS_SCHEMA,
],
Expand All @@ -67,7 +73,6 @@ describe('AbstractTrackableComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(AbstractTrackableComponent);
comp = fixture.componentInstance;
comp.url = url;

fixture.detectChanges();
});
Expand Down
19 changes: 17 additions & 2 deletions src/app/shared/trackable/abstract-trackable.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { Component } from '@angular/core';
import {
Component,
OnInit,
} from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';

Expand All @@ -13,7 +17,7 @@ import { NotificationsService } from '../notifications/notifications.service';
template: '',
standalone: true,
})
export class AbstractTrackableComponent {
export class AbstractTrackableComponent implements OnInit {

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

hasChanges$: Observable<boolean>;

isReinstatable$: Observable<boolean>;

constructor(
public objectUpdatesService: ObjectUpdatesService,
public notificationsService: NotificationsService,
public translateService: TranslateService,
public router: Router,
) {

}

ngOnInit(): void {
this.url = this.router.url.split('?')[0];
this.hasChanges$ = this.hasChanges();
this.isReinstatable$ = this.isReinstatable();
}

/**
* Request the object updates service to discard all current changes to this item
* Shows a notification to remind the user that they can undo this
Expand Down
Loading