mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #2308 from 4Science/DURACOM-155
Edit section in sidebar menu: edit page of selected item / collection / community does not refresh
This commit is contained in:
@@ -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 { Observable } from 'rxjs';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
@@ -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'],
|
styleUrls: ['../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.scss'],
|
||||||
templateUrl: '../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.html'
|
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
|
* @type {Collection} A new collection when a collection is being created, an existing Input collection when a collection is being edited
|
||||||
*/
|
*/
|
||||||
@@ -61,12 +61,23 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
|
|||||||
protected dsoService: CommunityDataService,
|
protected dsoService: CommunityDataService,
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected entityTypeService: EntityTypeDataService) {
|
protected entityTypeService: EntityTypeDataService,
|
||||||
|
protected chd: ChangeDetectorRef) {
|
||||||
super(formService, translate, notificationsService, authService, requestService, objectCache);
|
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[];
|
let currentRelationshipValue: MetadataValue[];
|
||||||
if (this.dso && this.dso.metadata) {
|
if (this.dso && this.dso.metadata) {
|
||||||
currentRelationshipValue = this.dso.metadata['dspace.entity.type'];
|
currentRelationshipValue = this.dso.metadata['dspace.entity.type'];
|
||||||
@@ -96,6 +107,7 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
|
|||||||
this.formModel = [...collectionFormModels, this.entityTypeSelection];
|
this.formModel = [...collectionFormModels, this.entityTypeSelection];
|
||||||
|
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
|
this.chd.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import { SharedModule } from '../../../shared/shared.module';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
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 { of as observableOf } from 'rxjs';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { CollectionMetadataComponent } from './collection-metadata.component';
|
import { CollectionMetadataComponent } from './collection-metadata.component';
|
||||||
@@ -52,6 +52,11 @@ describe('CollectionMetadataComponent', () => {
|
|||||||
setStaleByHrefSubstring: {}
|
setStaleByHrefSubstring: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const routerMock = {
|
||||||
|
events: observableOf(new NavigationEnd(1, 'url', 'url')),
|
||||||
|
navigate: jasmine.createSpy('navigate'),
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
@@ -62,6 +67,7 @@ describe('CollectionMetadataComponent', () => {
|
|||||||
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: createSuccessfulRemoteDataObject(collection) }) } } },
|
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: createSuccessfulRemoteDataObject(collection) }) } } },
|
||||||
{ provide: NotificationsService, useValue: notificationsService },
|
{ provide: NotificationsService, useValue: notificationsService },
|
||||||
{ provide: RequestService, useValue: requestService },
|
{ provide: RequestService, useValue: requestService },
|
||||||
|
{ provide: Router, useValue: routerMock}
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -70,8 +76,11 @@ describe('CollectionMetadataComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(CollectionMetadataComponent);
|
fixture = TestBed.createComponent(CollectionMetadataComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
router = (comp as any).router;
|
|
||||||
itemTemplateService = (comp as any).itemTemplateService;
|
itemTemplateService = (comp as any).itemTemplateService;
|
||||||
|
spyOn(comp, 'ngOnInit');
|
||||||
|
spyOn(comp, 'initTemplateItem');
|
||||||
|
|
||||||
|
routerMock.events = observableOf(new NavigationEnd(1, 'url', 'url'));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -83,9 +92,8 @@ describe('CollectionMetadataComponent', () => {
|
|||||||
|
|
||||||
describe('addItemTemplate', () => {
|
describe('addItemTemplate', () => {
|
||||||
it('should navigate to the collection\'s itemtemplate page', () => {
|
it('should navigate to the collection\'s itemtemplate page', () => {
|
||||||
spyOn(router, 'navigate');
|
|
||||||
comp.addItemTemplate();
|
comp.addItemTemplate();
|
||||||
expect(router.navigate).toHaveBeenCalledWith([getCollectionItemTemplateRoute(collection.uuid)]);
|
expect(routerMock.navigate).toHaveBeenCalledWith([getCollectionItemTemplateRoute(collection.uuid)]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -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 { ComcolMetadataComponent } from '../../../shared/comcol/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
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 { ItemTemplateDataService } from '../../../core/data/item-template-data.service';
|
||||||
import { combineLatest as combineLatestObservable, Observable } from 'rxjs';
|
import { combineLatest as combineLatestObservable, Observable } from 'rxjs';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
@@ -23,7 +23,7 @@ import { hasValue } from '../../../shared/empty.util';
|
|||||||
selector: 'ds-collection-metadata',
|
selector: 'ds-collection-metadata',
|
||||||
templateUrl: './collection-metadata.component.html',
|
templateUrl: './collection-metadata.component.html',
|
||||||
})
|
})
|
||||||
export class CollectionMetadataComponent extends ComcolMetadataComponent<Collection> {
|
export class CollectionMetadataComponent extends ComcolMetadataComponent<Collection> implements OnInit {
|
||||||
protected frontendURL = '/collections/';
|
protected frontendURL = '/collections/';
|
||||||
protected type = Collection.type;
|
protected type = Collection.type;
|
||||||
|
|
||||||
@@ -40,13 +40,27 @@ export class CollectionMetadataComponent extends ComcolMetadataComponent<Collect
|
|||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected translate: TranslateService,
|
protected translate: TranslateService,
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
|
protected chd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
super(collectionDataService, router, route, notificationsService, translate);
|
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 {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
this.router.events.subscribe((event) => {
|
||||||
this.initTemplateItem();
|
if (
|
||||||
|
event instanceof NavigationEnd ||
|
||||||
|
(event instanceof Scroll && event.routerEvent instanceof NavigationEnd)
|
||||||
|
) {
|
||||||
|
super.ngOnInit();
|
||||||
|
this.initTemplateItem();
|
||||||
|
this.chd.detectChanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input, OnChanges, SimpleChange, SimpleChanges } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
DynamicFormControlModel,
|
DynamicFormControlModel,
|
||||||
DynamicFormService,
|
DynamicFormService,
|
||||||
@@ -23,7 +23,7 @@ import { environment } from '../../../environments/environment';
|
|||||||
styleUrls: ['../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.scss'],
|
styleUrls: ['../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.scss'],
|
||||||
templateUrl: '../../shared/comcol/comcol-forms/comcol-form/comcol-form.component.html'
|
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
|
* @type {Community} A new community when a community is being created, an existing Input community when a community is being edited
|
||||||
*/
|
*/
|
||||||
@@ -81,4 +81,11 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
|
|||||||
protected objectCache: ObjectCacheService) {
|
protected objectCache: ObjectCacheService) {
|
||||||
super(formService, translate, notificationsService, authService, requestService, objectCache);
|
super(formService, translate, notificationsService, authService, requestService, objectCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
const dsoChange: SimpleChange = changes.dso;
|
||||||
|
if (this.dso && dsoChange && !dsoChange.isFirstChange()) {
|
||||||
|
super.ngOnInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
|
|||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ItemOperation } from '../item-operation/itemOperation.model';
|
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 { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { getItemEditRoute, getItemPageRoute } from '../../item-page-routing-paths';
|
import { getItemEditRoute, getItemPageRoute } from '../../item-page-routing-paths';
|
||||||
@@ -82,7 +82,6 @@ export class ItemStatusComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso));
|
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso));
|
||||||
this.itemRD$.pipe(
|
this.itemRD$.pipe(
|
||||||
first(),
|
|
||||||
map((data: RemoteData<Item>) => data.payload)
|
map((data: RemoteData<Item>) => data.payload)
|
||||||
).subscribe((item: Item) => {
|
).subscribe((item: Item) => {
|
||||||
this.statusData = Object.assign({
|
this.statusData = Object.assign({
|
||||||
|
@@ -127,39 +127,41 @@ export class ComColFormComponent<T extends Collection | Community> implements On
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.formModel.forEach(
|
if (hasValue(this.formModel)) {
|
||||||
(fieldModel: DynamicInputModel) => {
|
this.formModel.forEach(
|
||||||
fieldModel.value = this.dso.firstMetadataValue(fieldModel.name);
|
(fieldModel: DynamicInputModel) => {
|
||||||
}
|
fieldModel.value = this.dso.firstMetadataValue(fieldModel.name);
|
||||||
);
|
}
|
||||||
this.formGroup = this.formService.createFormGroup(this.formModel);
|
|
||||||
|
|
||||||
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 {
|
this.formGroup = this.formService.createFormGroup(this.formModel);
|
||||||
// Set a placeholder URL to not break the uploader component. This will be replaced once the object is created.
|
|
||||||
this.uploadFilesOptions.url = 'placeholder';
|
this.updateFieldTranslations();
|
||||||
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
|
this.translate.onLangChange
|
||||||
this.initializedUploaderOptions.next(true);
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
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 { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../../../../../core/shared/operators';
|
||||||
import { hasValue, isEmpty } from '../../../../empty.util';
|
import { hasValue, isEmpty } from '../../../../empty.util';
|
||||||
import { ResourceType } from '../../../../../core/shared/resource-type';
|
import { ResourceType } from '../../../../../core/shared/resource-type';
|
||||||
@@ -42,7 +42,7 @@ export class ComcolMetadataComponent<TDomain extends Community | Collection> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { first, map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
@@ -53,7 +53,7 @@ export class EditComColPageComponent<TDomain extends DSpaceObject> implements On
|
|||||||
this.pages = this.route.routeConfig.children
|
this.pages = this.route.routeConfig.children
|
||||||
.map((child: any) => child.path)
|
.map((child: any) => child.path)
|
||||||
.filter((path: string) => isNotEmpty(path)); // ignore reroutes
|
.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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user