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

Edit section in sidebar menu: edit page of selected item / collection / community does not refresh #2308

Merged
merged 4 commits into from
Jun 16, 2023
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChange, SimpleChanges } from '@angular/core';

import { Observable } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
Expand Down Expand Up @@ -31,7 +31,7 @@ import { NONE_ENTITY_TYPE } from '../../core/shared/item-relationships/item-type
styleUrls: ['../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.scss'],
templateUrl: '../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.html'
})
export class CollectionFormComponent extends ComColFormComponent<Collection> implements OnInit {
export class CollectionFormComponent extends ComColFormComponent<Collection> implements OnInit, OnChanges {
/**
* @type {Collection} A new collection when a collection is being created, an existing Input collection when a collection is being edited
*/
Expand Down Expand Up @@ -61,12 +61,23 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
protected dsoService: CommunityDataService,
protected requestService: RequestService,
protected objectCache: ObjectCacheService,
protected entityTypeService: EntityTypeDataService) {
protected entityTypeService: EntityTypeDataService,
protected chd: ChangeDetectorRef) {
super(formService, translate, notificationsService, authService, requestService, objectCache);
}

ngOnInit() {
/**
* Detect changes to the dso and initialize the form,
* if the dso changes, exists and it is not the first change
*/
ngOnChanges(changes: SimpleChanges) {
const dsoChange: SimpleChange = changes.dso;
if (this.dso && dsoChange && !dsoChange.isFirstChange()) {
this.initializeForm();
}
}

initializeForm() {
let currentRelationshipValue: MetadataValue[];
if (this.dso && this.dso.metadata) {
currentRelationshipValue = this.dso.metadata['dspace.entity.type'];
Expand Down Expand Up @@ -96,6 +107,7 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
this.formModel = [...collectionFormModels, this.entityTypeSelection];

super.ngOnInit();
this.chd.detectChanges();
});

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SharedModule } from '../../../shared/shared.module';
import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { of as observableOf } from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { CollectionMetadataComponent } from './collection-metadata.component';
Expand Down Expand Up @@ -52,6 +52,11 @@ describe('CollectionMetadataComponent', () => {
setStaleByHrefSubstring: {}
});

const routerMock = {
events: observableOf(new NavigationEnd(1, 'url', 'url')),
navigate: jasmine.createSpy('navigate'),
};

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
Expand All @@ -62,6 +67,7 @@ describe('CollectionMetadataComponent', () => {
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: createSuccessfulRemoteDataObject(collection) }) } } },
{ provide: NotificationsService, useValue: notificationsService },
{ provide: RequestService, useValue: requestService },
{ provide: Router, useValue: routerMock}
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
Expand All @@ -70,8 +76,11 @@ describe('CollectionMetadataComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(CollectionMetadataComponent);
comp = fixture.componentInstance;
router = (comp as any).router;
itemTemplateService = (comp as any).itemTemplateService;
spyOn(comp, 'ngOnInit');
spyOn(comp, 'initTemplateItem');

routerMock.events = observableOf(new NavigationEnd(1, 'url', 'url'));
fixture.detectChanges();
});

Expand All @@ -83,9 +92,8 @@ describe('CollectionMetadataComponent', () => {

describe('addItemTemplate', () => {
it('should navigate to the collection\'s itemtemplate page', () => {
spyOn(router, 'navigate');
comp.addItemTemplate();
expect(router.navigate).toHaveBeenCalledWith([getCollectionItemTemplateRoute(collection.uuid)]);
expect(routerMock.navigate).toHaveBeenCalledWith([getCollectionItemTemplateRoute(collection.uuid)]);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Component } from '@angular/core';
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ComcolMetadataComponent } from '../../../shared/comcol/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component';
import { Collection } from '../../../core/shared/collection.model';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, NavigationEnd, Router, Scroll } from '@angular/router';
import { ItemTemplateDataService } from '../../../core/data/item-template-data.service';
import { combineLatest as combineLatestObservable, Observable } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data';
Expand All @@ -23,7 +23,7 @@ import { hasValue } from '../../../shared/empty.util';
selector: 'ds-collection-metadata',
templateUrl: './collection-metadata.component.html',
})
export class CollectionMetadataComponent extends ComcolMetadataComponent<Collection> {
export class CollectionMetadataComponent extends ComcolMetadataComponent<Collection> implements OnInit {
protected frontendURL = '/collections/';
protected type = Collection.type;

Expand All @@ -40,13 +40,27 @@ export class CollectionMetadataComponent extends ComcolMetadataComponent<Collect
protected notificationsService: NotificationsService,
protected translate: TranslateService,
protected requestService: RequestService,
protected chd: ChangeDetectorRef
) {
super(collectionDataService, router, route, notificationsService, translate);
}

/**
* Cheking if the navigation is done and if so, initialize the collection's item template,
* to ensure that the item template is always up to date.
* Check when a NavigationEnd event (URL change) or a Scroll event followed by a NavigationEnd event (refresh event), occurs
*/
ngOnInit(): void {
super.ngOnInit();
this.initTemplateItem();
this.router.events.subscribe((event) => {
if (
event instanceof NavigationEnd ||
(event instanceof Scroll && event.routerEvent instanceof NavigationEnd)
) {
super.ngOnInit();
this.initTemplateItem();
this.chd.detectChanges();
}
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input } from '@angular/core';
import { Component, Input, OnChanges, SimpleChange, SimpleChanges } from '@angular/core';
import {
DynamicFormControlModel,
DynamicFormService,
Expand All @@ -23,7 +23,7 @@ import { environment } from '../../../environments/environment';
styleUrls: ['../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.scss'],
templateUrl: '../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.html'
})
export class CommunityFormComponent extends ComColFormComponent<Community> {
export class CommunityFormComponent extends ComColFormComponent<Community> implements OnChanges {
/**
* @type {Community} A new community when a community is being created, an existing Input community when a community is being edited
*/
Expand Down Expand Up @@ -81,4 +81,11 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
protected objectCache: ObjectCacheService) {
super(formService, translate, notificationsService, authService, requestService, objectCache);
}

ngOnChanges(changes: SimpleChanges) {
const dsoChange: SimpleChange = changes.dso;
if (this.dso && dsoChange && !dsoChange.isFirstChange()) {
super.ngOnInit();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
import { Item } from '../../../core/shared/item.model';
import { ActivatedRoute } from '@angular/router';
import { ItemOperation } from '../item-operation/itemOperation.model';
import { distinctUntilChanged, first, map, mergeMap, switchMap, toArray } from 'rxjs/operators';
import { distinctUntilChanged, map, mergeMap, switchMap, toArray } from 'rxjs/operators';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data';
import { getItemEditRoute, getItemPageRoute } from '../../item-page-routing-paths';
Expand Down Expand Up @@ -82,7 +82,6 @@ export class ItemStatusComponent implements OnInit {
ngOnInit(): void {
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso));
this.itemRD$.pipe(
first(),
map((data: RemoteData<Item>) => data.payload)
).subscribe((item: Item) => {
this.statusData = Object.assign({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,39 +127,41 @@ export class ComColFormComponent<T extends Collection | Community> implements On
}

ngOnInit(): void {
this.formModel.forEach(
(fieldModel: DynamicInputModel) => {
fieldModel.value = this.dso.firstMetadataValue(fieldModel.name);
}
);
this.formGroup = this.formService.createFormGroup(this.formModel);
if (hasValue(this.formModel)) {
this.formModel.forEach(
(fieldModel: DynamicInputModel) => {
fieldModel.value = this.dso.firstMetadataValue(fieldModel.name);
}
);
this.formGroup = this.formService.createFormGroup(this.formModel);

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

if (hasValue(this.dso.id)) {
this.subs.push(
observableCombineLatest([
this.dsoService.getLogoEndpoint(this.dso.id),
this.dso.logo
]).subscribe(([href, logoRD]: [string, RemoteData<Bitstream>]) => {
this.uploadFilesOptions.url = href;
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
// If the object already contains a logo, send out a PUT request instead of POST for setting a new logo
if (hasValue(logoRD.payload)) {
this.uploadFilesOptions.method = RestRequestMethod.PUT;
}
this.initializedUploaderOptions.next(true);
})
);
} else {
// Set a placeholder URL to not break the uploader component. This will be replaced once the object is created.
this.uploadFilesOptions.url = 'placeholder';
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
this.initializedUploaderOptions.next(true);
if (hasValue(this.dso.id)) {
this.subs.push(
observableCombineLatest([
this.dsoService.getLogoEndpoint(this.dso.id),
this.dso.logo
]).subscribe(([href, logoRD]: [string, RemoteData<Bitstream>]) => {
this.uploadFilesOptions.url = href;
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
// If the object already contains a logo, send out a PUT request instead of POST for setting a new logo
if (hasValue(logoRD.payload)) {
this.uploadFilesOptions.method = RestRequestMethod.PUT;
}
this.initializedUploaderOptions.next(true);
})
);
} else {
// Set a placeholder URL to not break the uploader component. This will be replaced once the object is created.
this.uploadFilesOptions.url = 'placeholder';
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
this.initializedUploaderOptions.next(true);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
import { Observable } from 'rxjs';
import { RemoteData } from '../../../../../core/data/remote-data';
import { ActivatedRoute, Router } from '@angular/router';
import { first, map, take } from 'rxjs/operators';
import { map, take } from 'rxjs/operators';
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../../../../../core/shared/operators';
import { hasValue, isEmpty } from '../../../../empty.util';
import { ResourceType } from '../../../../../core/shared/resource-type';
Expand Down Expand Up @@ -42,7 +42,7 @@ export class ComcolMetadataComponent<TDomain extends Community | Collection> imp
}

ngOnInit(): void {
this.dsoRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));
this.dsoRD$ = this.route.parent.data.pipe(map((data) => data.dso));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core';

import { Observable } from 'rxjs';
import { first, map } from 'rxjs/operators';
import { map } from 'rxjs/operators';

import { ActivatedRoute, Router } from '@angular/router';
import { RemoteData } from '../../../../core/data/remote-data';
Expand Down Expand Up @@ -53,7 +53,7 @@ export class EditComColPageComponent<TDomain extends DSpaceObject> implements On
this.pages = this.route.routeConfig.children
.map((child: any) => child.path)
.filter((path: string) => isNotEmpty(path)); // ignore reroutes
this.dsoRD$ = this.route.data.pipe(first(), map((data) => data.dso));
this.dsoRD$ = this.route.data.pipe(map((data) => data.dso));
}

/**
Expand Down