got rid of TNormalized everywhere

This commit is contained in:
lotte
2019-01-29 16:03:50 +01:00
parent 58b45801b7
commit 0050f58bf0
50 changed files with 223 additions and 191 deletions

View File

@@ -3,7 +3,6 @@ import { CommunityDataService } from '../../core/data/community-data.service';
import { RouteService } from '../../shared/services/route.service'; import { RouteService } from '../../shared/services/route.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component'; import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model';
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';
@@ -15,7 +14,7 @@ import { CollectionDataService } from '../../core/data/collection-data.service';
styleUrls: ['./create-collection-page.component.scss'], styleUrls: ['./create-collection-page.component.scss'],
templateUrl: './create-collection-page.component.html' templateUrl: './create-collection-page.component.html'
}) })
export class CreateCollectionPageComponent extends CreateComColPageComponent<Collection, NormalizedCollection> { export class CreateCollectionPageComponent extends CreateComColPageComponent<Collection> {
protected frontendURL = '/collections/'; protected frontendURL = '/collections/';
public constructor( public constructor(

View File

@@ -1,12 +1,8 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Community } from '../../core/shared/community.model';
import { CommunityDataService } from '../../core/data/community-data.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { NormalizedCommunity } from '../../core/cache/models/normalized-community.model';
import { DeleteComColPageComponent } from '../../shared/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { DeleteComColPageComponent } from '../../shared/comcol-forms/delete-comcol-page/delete-comcol-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { CollectionDataService } from '../../core/data/collection-data.service'; import { CollectionDataService } from '../../core/data/collection-data.service';
import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model';
import { Collection } from '../../core/shared/collection.model'; import { Collection } from '../../core/shared/collection.model';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@@ -18,7 +14,7 @@ import { TranslateService } from '@ngx-translate/core';
styleUrls: ['./delete-collection-page.component.scss'], styleUrls: ['./delete-collection-page.component.scss'],
templateUrl: './delete-collection-page.component.html' templateUrl: './delete-collection-page.component.html'
}) })
export class DeleteCollectionPageComponent extends DeleteComColPageComponent<Collection, NormalizedCollection> { export class DeleteCollectionPageComponent extends DeleteComColPageComponent<Collection> {
protected frontendURL = '/collections/'; protected frontendURL = '/collections/';
public constructor( public constructor(

View File

@@ -13,7 +13,7 @@ import { CollectionDataService } from '../../core/data/collection-data.service';
styleUrls: ['./edit-collection-page.component.scss'], styleUrls: ['./edit-collection-page.component.scss'],
templateUrl: './edit-collection-page.component.html' templateUrl: './edit-collection-page.component.html'
}) })
export class EditCollectionPageComponent extends EditComColPageComponent<Collection, NormalizedCollection> { export class EditCollectionPageComponent extends EditComColPageComponent<Collection> {
protected frontendURL = '/collections/'; protected frontendURL = '/collections/';
public constructor( public constructor(

View File

@@ -4,7 +4,6 @@ import { CommunityDataService } from '../../core/data/community-data.service';
import { RouteService } from '../../shared/services/route.service'; import { RouteService } from '../../shared/services/route.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component'; import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
import { NormalizedCommunity } from '../../core/cache/models/normalized-community.model';
/** /**
* Component that represents the page where a user can create a new Community * Component that represents the page where a user can create a new Community
@@ -14,7 +13,7 @@ import { NormalizedCommunity } from '../../core/cache/models/normalized-communit
styleUrls: ['./create-community-page.component.scss'], styleUrls: ['./create-community-page.component.scss'],
templateUrl: './create-community-page.component.html' templateUrl: './create-community-page.component.html'
}) })
export class CreateCommunityPageComponent extends CreateComColPageComponent<Community, NormalizedCommunity> { export class CreateCommunityPageComponent extends CreateComColPageComponent<Community> {
protected frontendURL = '/communities/'; protected frontendURL = '/communities/';
public constructor( public constructor(

View File

@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { CommunityDataService } from '../../core/data/community-data.service'; import { CommunityDataService } from '../../core/data/community-data.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { NormalizedCommunity } from '../../core/cache/models/normalized-community.model';
import { DeleteComColPageComponent } from '../../shared/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { DeleteComColPageComponent } from '../../shared/comcol-forms/delete-comcol-page/delete-comcol-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@@ -15,7 +14,7 @@ import { TranslateService } from '@ngx-translate/core';
styleUrls: ['./delete-community-page.component.scss'], styleUrls: ['./delete-community-page.component.scss'],
templateUrl: './delete-community-page.component.html' templateUrl: './delete-community-page.component.html'
}) })
export class DeleteCommunityPageComponent extends DeleteComColPageComponent<Community, NormalizedCommunity> { export class DeleteCommunityPageComponent extends DeleteComColPageComponent<Community> {
protected frontendURL = '/communities/'; protected frontendURL = '/communities/';
public constructor( public constructor(

View File

@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { CommunityDataService } from '../../core/data/community-data.service'; import { CommunityDataService } from '../../core/data/community-data.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { NormalizedCommunity } from '../../core/cache/models/normalized-community.model';
import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component'; import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component';
/** /**
@@ -13,7 +12,7 @@ import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-p
styleUrls: ['./edit-community-page.component.scss'], styleUrls: ['./edit-community-page.component.scss'],
templateUrl: './edit-community-page.component.html' templateUrl: './edit-community-page.component.html'
}) })
export class EditCommunityPageComponent extends EditComColPageComponent<Community, NormalizedCommunity> { export class EditCommunityPageComponent extends EditComColPageComponent<Community> {
protected frontendURL = '/communities/'; protected frontendURL = '/communities/';
public constructor( public constructor(

View File

@@ -1,10 +1,10 @@
<div class="container"> <div class="container">
<div class="item-metadata"> <div class="item-metadata">
<button class="btn btn-primary w-100 my-2" (click)="addMetadata()">{{"item.edit.metadata.add-button" | translate}}</button> <button class="btn btn-primary w-100 my-2" (click)="update()">{{"item.edit.metadata.add-button" | translate}}</button>
<table class="table table-responsive table-striped"> <table class="table table-responsive table-striped">
<tbody> <tbody>
<tr *ngFor="let metadatum of item.metadata; let i=index"> <tr *ngFor="let metadatum of item.metadata; let i=index">
<ds-edit-in-place-field [metadata]="metadatum" class="d-flex" (mdUpdate)="update()" (mdRemove)="removeMetadata(i)"></ds-edit-in-place-field> <ds-edit-in-place-field [metadata]="metadatum" class="d-flex" (mdUpdate)="update()" (mdRemove)="update()"></ds-edit-in-place-field>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { ItemDataService } from '../../../core/data/item-data.service'; import { ItemDataService } from '../../../core/data/item-data.service';
import { Metadatum } from '../../../core/shared/metadatum.model'; import { Metadatum } from '../../../core/shared/metadatum.model';
import { DSOChangeAnalyzer } from '../../../core/data/dso-change-analyzer.service';
@Component({ @Component({
selector: 'ds-item-metadata', selector: 'ds-item-metadata',
@@ -16,22 +17,24 @@ export class ItemMetadataComponent {
* The item to display the metadata for * The item to display the metadata for
*/ */
@Input() item: Item; @Input() item: Item;
updateItem: Item;
constructor(private itemService: ItemDataService) { constructor(private itemService: ItemDataService, private dsoChanges: DSOChangeAnalyzer<Item>) {
this.updateItem = Object.assign({}, this.item);
} }
update() { update() {
this.itemService.update(this.item).subscribe(); this.dsoChanges.diff(this.item, this.updateItem);
} }
removeMetadata(i: number) { // submit() {
this.item.metadata = this.item.metadata.filter((metadatum: Metadatum, index: number) => index !== i); //
this.update(); // }
} //
// discard() {
addMetadata() { //
this.item.metadata = [new Metadatum(), ...this.item.metadata]; // }
this.update(); //
} // undo() {
//
// }
} }

View File

@@ -3,10 +3,10 @@ import { GenericConstructor } from '../shared/generic-constructor';
import { NormalizedAuthStatus } from './models/normalized-auth-status.model'; import { NormalizedAuthStatus } from './models/normalized-auth-status.model';
import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model'; import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model';
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
import { EPerson } from '../eperson/models/eperson.model'; import { CacheableObject } from '../cache/object-cache.reducer';
export class AuthObjectFactory { export class AuthObjectFactory {
public static getConstructor(type): GenericConstructor<NormalizedObject> { public static getConstructor(type): GenericConstructor<NormalizedObject<CacheableObject>> {
switch (type) { switch (type) {
case AuthType.EPerson: { case AuthType.EPerson: {
return NormalizedEPerson return NormalizedEPerson

View File

@@ -131,7 +131,7 @@ export class AuthService {
* @returns {Observable<boolean>} * @returns {Observable<boolean>}
*/ */
public isAuthenticated(): Observable<boolean> { public isAuthenticated(): Observable<boolean> {
return of(true); return this.store.pipe(select(isAuthenticated));
} }
/** /**
@@ -152,7 +152,7 @@ export class AuthService {
// TODO this should be cleaned up, AuthStatus could be parsed by the RemoteDataService as a whole... // TODO this should be cleaned up, AuthStatus could be parsed by the RemoteDataService as a whole...
// Review when https://jira.duraspace.org/browse/DS-4006 is fixed // Review when https://jira.duraspace.org/browse/DS-4006 is fixed
// See https://github.com/DSpace/dspace-angular/issues/292 // See https://github.com/DSpace/dspace-angular/issues/292
const person$ = this.rdbService.buildSingle<NormalizedEPerson, EPerson>(status.eperson.toString()); const person$ = this.rdbService.buildSingle<EPerson>(status.eperson.toString());
return person$.pipe(map((eperson) => eperson.payload)); return person$.pipe(map((eperson) => eperson.payload));
} else { } else {
throw(new Error('Not authenticated')); throw(new Error('Not authenticated'));

View File

@@ -7,7 +7,7 @@ import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
@mapsTo(AuthStatus) @mapsTo(AuthStatus)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedAuthStatus extends NormalizedObject { export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
@autoserialize @autoserialize
id: string; id: string;

View File

@@ -10,7 +10,6 @@ import { AuthService } from './auth.service';
import { AuthTokenInfo } from './models/auth-token-info.model'; import { AuthTokenInfo } from './models/auth-token-info.model';
import { CheckAuthenticationTokenAction } from './auth.actions'; import { CheckAuthenticationTokenAction } from './auth.actions';
import { EPerson } from '../eperson/models/eperson.model'; import { EPerson } from '../eperson/models/eperson.model';
import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model';
/** /**
* The auth service. * The auth service.
@@ -40,7 +39,7 @@ export class ServerAuthService extends AuthService {
if (status.authenticated) { if (status.authenticated) {
// TODO this should be cleaned up, AuthStatus could be parsed by the RemoteDataService as a whole... // TODO this should be cleaned up, AuthStatus could be parsed by the RemoteDataService as a whole...
const person$ = this.rdbService.buildSingle<NormalizedEPerson, EPerson>(status.eperson.toString()); const person$ = this.rdbService.buildSingle<EPerson>(status.eperson.toString());
return person$.pipe( return person$.pipe(
map((eperson) => eperson.payload) map((eperson) => eperson.payload)
); );

View File

@@ -35,7 +35,7 @@ export class NormalizedObjectBuildService {
* *
* @param {TDomain} domainModel a domain model * @param {TDomain} domainModel a domain model
*/ */
normalize<TDomain extends CacheableObject, TNormalized extends NormalizedObject>(domainModel: TDomain): TNormalized { normalize<T extends CacheableObject>(domainModel: T): NormalizedObject<T> {
const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type); const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type);
const relationships = getRelationships(normalizedConstructor) || []; const relationships = getRelationships(normalizedConstructor) || [];

View File

@@ -25,6 +25,7 @@ import {
getRequestFromRequestUUID, getRequestFromRequestUUID,
getResourceLinksFromResponse getResourceLinksFromResponse
} from '../../shared/operators'; } from '../../shared/operators';
import { CacheableObject } from '../object-cache.reducer';
@Injectable() @Injectable()
export class RemoteDataBuildService { export class RemoteDataBuildService {
@@ -32,7 +33,7 @@ export class RemoteDataBuildService {
protected requestService: RequestService) { protected requestService: RequestService) {
} }
buildSingle<TNormalized extends NormalizedObject, TDomain>(href$: string | Observable<string>): Observable<RemoteData<TDomain>> { buildSingle<T extends CacheableObject>(href$: string | Observable<string>): Observable<RemoteData<T>> {
if (typeof href$ === 'string') { if (typeof href$ === 'string') {
href$ = observableOf(href$); href$ = observableOf(href$);
} }
@@ -49,7 +50,7 @@ export class RemoteDataBuildService {
const payload$ = const payload$ =
observableCombineLatest( observableCombineLatest(
href$.pipe( href$.pipe(
switchMap((href: string) => this.objectCache.getBySelfLink<TNormalized>(href)), switchMap((href: string) => this.objectCache.getBySelfLink<NormalizedObject<T>>(href)),
startWith(undefined)), startWith(undefined)),
requestEntry$.pipe( requestEntry$.pipe(
getResourceLinksFromResponse(), getResourceLinksFromResponse(),
@@ -72,8 +73,8 @@ export class RemoteDataBuildService {
} }
}), }),
hasValueOperator(), hasValueOperator(),
map((normalized: TNormalized) => { map((normalized: NormalizedObject<T>) => {
return this.build<TNormalized, TDomain>(normalized); return this.build<T>(normalized);
}), }),
startWith(undefined), startWith(undefined),
distinctUntilChanged() distinctUntilChanged()
@@ -106,7 +107,7 @@ export class RemoteDataBuildService {
); );
} }
buildList<TNormalized extends NormalizedObject, TDomain>(href$: string | Observable<string>): Observable<RemoteData<PaginatedList<TDomain>>> { buildList<T extends CacheableObject>(href$: string | Observable<string>): Observable<RemoteData<PaginatedList<T>>> {
if (typeof href$ === 'string') { if (typeof href$ === 'string') {
href$ = observableOf(href$); href$ = observableOf(href$);
} }
@@ -116,9 +117,9 @@ export class RemoteDataBuildService {
getResourceLinksFromResponse(), getResourceLinksFromResponse(),
flatMap((resourceUUIDs: string[]) => { flatMap((resourceUUIDs: string[]) => {
return this.objectCache.getList(resourceUUIDs).pipe( return this.objectCache.getList(resourceUUIDs).pipe(
map((normList: TNormalized[]) => { map((normList: Array<NormalizedObject<T>>) => {
return normList.map((normalized: TNormalized) => { return normList.map((normalized: NormalizedObject<T>) => {
return this.build<TNormalized, TDomain>(normalized); return this.build<T>(normalized);
}); });
})); }));
}), }),
@@ -148,7 +149,7 @@ export class RemoteDataBuildService {
return this.toRemoteDataObservable(requestEntry$, payload$); return this.toRemoteDataObservable(requestEntry$, payload$);
} }
build<TNormalized, TDomain>(normalized: TNormalized): TDomain { build<T extends CacheableObject>(normalized: NormalizedObject<T>): T {
const links: any = {}; const links: any = {};
const relationships = getRelationships(normalized.constructor) || []; const relationships = getRelationships(normalized.constructor) || [];

View File

@@ -11,7 +11,7 @@ import { SupportLevel } from './support-level.model';
*/ */
@mapsTo(BitstreamFormat) @mapsTo(BitstreamFormat)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedBitstreamFormat extends NormalizedObject { export class NormalizedBitstreamFormat extends NormalizedObject<BitstreamFormat> {
/** /**
* Short description of this Bitstream Format * Short description of this Bitstream Format

View File

@@ -10,7 +10,7 @@ import { ResourceType } from '../../shared/resource-type';
*/ */
@mapsTo(Bitstream) @mapsTo(Bitstream)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedBitstream extends NormalizedDSpaceObject { export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
/** /**
* The size of this bitstream in bytes * The size of this bitstream in bytes

View File

@@ -10,7 +10,7 @@ import { ResourceType } from '../../shared/resource-type';
*/ */
@mapsTo(Bundle) @mapsTo(Bundle)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedBundle extends NormalizedDSpaceObject { export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
/** /**
* The primary bitstream of this Bundle * The primary bitstream of this Bundle
*/ */

View File

@@ -10,7 +10,7 @@ import { ResourceType } from '../../shared/resource-type';
*/ */
@mapsTo(Collection) @mapsTo(Collection)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedCollection extends NormalizedDSpaceObject { export class NormalizedCollection extends NormalizedDSpaceObject<Collection> {
/** /**
* A string representing the unique handle of this Collection * A string representing the unique handle of this Collection

View File

@@ -10,7 +10,7 @@ import { ResourceType } from '../../shared/resource-type';
*/ */
@mapsTo(Community) @mapsTo(Community)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedCommunity extends NormalizedDSpaceObject { export class NormalizedCommunity extends NormalizedDSpaceObject<Community> {
/** /**
* A string representing the unique handle of this Community * A string representing the unique handle of this Community

View File

@@ -10,7 +10,7 @@ import { NormalizedObject } from './normalized-object.model';
* An model class for a DSpaceObject. * An model class for a DSpaceObject.
*/ */
@mapsTo(DSpaceObject) @mapsTo(DSpaceObject)
export class NormalizedDSpaceObject extends NormalizedObject { export class NormalizedDSpaceObject<T extends DSpaceObject> extends NormalizedObject<T> {
/** /**
* The link to the rest endpoint where this object can be found * The link to the rest endpoint where this object can be found

View File

@@ -10,7 +10,7 @@ import { ResourceType } from '../../shared/resource-type';
*/ */
@mapsTo(Item) @mapsTo(Item)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedItem extends NormalizedDSpaceObject { export class NormalizedItem extends NormalizedDSpaceObject<Item> {
/** /**
* A string representing the unique handle of this Item * A string representing the unique handle of this Item

View File

@@ -11,9 +11,10 @@ import { NormalizedResourcePolicy } from './normalized-resource-policy.model';
import { NormalizedEPerson } from '../../eperson/models/normalized-eperson.model'; import { NormalizedEPerson } from '../../eperson/models/normalized-eperson.model';
import { NormalizedGroup } from '../../eperson/models/normalized-group.model'; import { NormalizedGroup } from '../../eperson/models/normalized-group.model';
import { NormalizedMetadataSchema } from '../../metadata/normalized-metadata-schema.model'; import { NormalizedMetadataSchema } from '../../metadata/normalized-metadata-schema.model';
import { CacheableObject } from '../object-cache.reducer';
export class NormalizedObjectFactory { export class NormalizedObjectFactory {
public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject> { public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject<CacheableObject>> {
switch (type) { switch (type) {
case ResourceType.Bitstream: { case ResourceType.Bitstream: {
return NormalizedBitstream return NormalizedBitstream

View File

@@ -4,7 +4,7 @@ import { ResourceType } from '../../shared/resource-type';
/** /**
* An abstract model class for a NormalizedObject. * An abstract model class for a NormalizedObject.
*/ */
export abstract class NormalizedObject implements CacheableObject { export abstract class NormalizedObject<T extends CacheableObject> implements CacheableObject {
/** /**
* The link to the rest endpoint where this object can be found * The link to the rest endpoint where this object can be found

View File

@@ -12,7 +12,7 @@ import { ActionType } from './action-type.model';
*/ */
@mapsTo(ResourcePolicy) @mapsTo(ResourcePolicy)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedResourcePolicy extends NormalizedObject { export class NormalizedResourcePolicy extends NormalizedObject<ResourcePolicy> {
/** /**
* The action that is allowed by this Resource Policy * The action that is allowed by this Resource Policy

View File

@@ -78,7 +78,7 @@ export class ObjectCacheService {
* @return Observable<T> * @return Observable<T>
* An observable of the requested object * An observable of the requested object
*/ */
getByUUID<T extends NormalizedObject>(uuid: string): Observable<T> { getByUUID<T extends CacheableObject>(uuid: string): Observable<NormalizedObject<T>> {
return this.store.pipe( return this.store.pipe(
select(selfLinkFromUuidSelector(uuid)), select(selfLinkFromUuidSelector(uuid)),
mergeMap((selfLink: string) => this.getBySelfLink(selfLink) mergeMap((selfLink: string) => this.getBySelfLink(selfLink)
@@ -86,7 +86,7 @@ export class ObjectCacheService {
) )
} }
getBySelfLink<T extends NormalizedObject>(selfLink: string): Observable<T> { getBySelfLink<T extends CacheableObject>(selfLink: string): Observable<NormalizedObject<T>> {
return this.getEntry(selfLink).pipe( return this.getEntry(selfLink).pipe(
map((entry: ObjectCacheEntry) => { map((entry: ObjectCacheEntry) => {
if (isNotEmpty(entry.patches)) { if (isNotEmpty(entry.patches)) {
@@ -99,8 +99,8 @@ export class ObjectCacheService {
} }
), ),
map((entry: ObjectCacheEntry) => { map((entry: ObjectCacheEntry) => {
const type: GenericConstructor<NormalizedObject> = NormalizedObjectFactory.getConstructor(entry.data.type); const type: GenericConstructor<NormalizedObject<T>> = NormalizedObjectFactory.getConstructor(entry.data.type);
return Object.assign(new type(), entry.data) as T return Object.assign(new type(), entry.data) as NormalizedObject<T>
}) })
); );
} }
@@ -145,7 +145,7 @@ export class ObjectCacheService {
* The type of the objects to get * The type of the objects to get
* @return Observable<Array<T>> * @return Observable<Array<T>>
*/ */
getList<T extends NormalizedObject>(selfLinks: string[]): Observable<T[]> { getList<T extends CacheableObject>(selfLinks: string[]): Observable<Array<NormalizedObject<T>>> {
return observableCombineLatest( return observableCombineLatest(
selfLinks.map((selfLink: string) => this.getBySelfLink<T>(selfLink)) selfLinks.map((selfLink: string) => this.getBySelfLink<T>(selfLink))
); );

View File

@@ -1,11 +1,12 @@
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
import { Operation } from 'fast-json-patch/lib/core'; import { Operation } from 'fast-json-patch/lib/core';
import { CacheableObject } from '../cache/object-cache.reducer';
/** /**
* An interface to determine what differs between two * An interface to determine what differs between two
* NormalizedObjects * NormalizedObjects
*/ */
export interface ChangeAnalyzer<TNormalized extends NormalizedObject> { export interface ChangeAnalyzer<T extends CacheableObject> {
/** /**
* Compare two objects and return their differences as a * Compare two objects and return their differences as a
@@ -16,5 +17,5 @@ export interface ChangeAnalyzer<TNormalized extends NormalizedObject> {
* @param {NormalizedObject} object2 * @param {NormalizedObject} object2
* The second object to compare * The second object to compare
*/ */
diff(object1: TNormalized, object2: TNormalized): Operation[]; diff(object1: T | NormalizedObject<T>, object2: T | NormalizedObject<T>): Operation[];
} }

View File

@@ -15,7 +15,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
@Injectable() @Injectable()
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> { export class CollectionDataService extends ComColDataService<Collection> {
protected linkPath = 'collections'; protected linkPath = 'collections';
constructor( constructor(
@@ -28,7 +28,7 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer protected comparator: DSOChangeAnalyzer<Collection>
) { ) {
super(); super();
} }

View File

@@ -18,14 +18,16 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { Item } from '../shared/item.model';
import { Community } from '../shared/community.model';
const LINK_NAME = 'test'; const LINK_NAME = 'test';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
class NormalizedTestObject extends NormalizedObject { class NormalizedTestObject extends NormalizedObject<Item> {
} }
class TestService extends ComColDataService<NormalizedTestObject, any> { class TestService extends ComColDataService<any> {
constructor( constructor(
protected requestService: RequestService, protected requestService: RequestService,
@@ -38,7 +40,7 @@ class TestService extends ComColDataService<NormalizedTestObject, any> {
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer, protected comparator: DSOChangeAnalyzer<Community>,
protected linkPath: string protected linkPath: string
) { ) {
super(); super();

View File

@@ -1,28 +1,17 @@
import { import { distinctUntilChanged, filter, map, mergeMap, share, take, tap } from 'rxjs/operators';
distinctUntilChanged,
filter,
first,
map,
mergeMap,
share,
take,
tap
} from 'rxjs/operators';
import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs'; import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs';
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { NormalizedCommunity } from '../cache/models/normalized-community.model'; import { NormalizedCommunity } from '../cache/models/normalized-community.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CommunityDataService } from './community-data.service'; import { CommunityDataService } from './community-data.service';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { FindAllOptions, FindByIDRequest } from './request.models'; import { FindAllOptions, FindByIDRequest } from './request.models';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RequestEntry } from './request.reducer';
import { getResponseFromEntry } from '../shared/operators'; import { getResponseFromEntry } from '../shared/operators';
import { CacheableObject } from '../cache/object-cache.reducer'; import { CacheableObject } from '../cache/object-cache.reducer';
export abstract class ComColDataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> extends DataService<TNormalized, TDomain> { export abstract class ComColDataService<T extends CacheableObject> extends DataService<T> {
protected abstract cds: CommunityDataService; protected abstract cds: CommunityDataService;
protected abstract objectCache: ObjectCacheService; protected abstract objectCache: ObjectCacheService;
protected abstract halService: HALEndpointService; protected abstract halService: HALEndpointService;

View File

@@ -21,7 +21,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
@Injectable() @Injectable()
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> { export class CommunityDataService extends ComColDataService<Community> {
protected linkPath = 'communities'; protected linkPath = 'communities';
protected topLinkPath = 'communities/search/top'; protected topLinkPath = 'communities/search/top';
protected cds = this; protected cds = this;
@@ -35,7 +35,7 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer protected comparator: DSOChangeAnalyzer<Community>
) { ) {
super(); super();
} }
@@ -54,6 +54,6 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
this.requestService.configure(request); this.requestService.configure(request);
}); });
return this.rdbService.buildList<NormalizedCommunity, Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>; return this.rdbService.buildList<Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
} }
} }

View File

@@ -16,14 +16,15 @@ import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { compare } from 'fast-json-patch'; import { compare } from 'fast-json-patch';
import { Item } from '../shared/item.model';
const endpoint = 'https://rest.api/core'; const endpoint = 'https://rest.api/core';
// tslint:disable:max-classes-per-file // tslint:disable:max-classes-per-file
class NormalizedTestObject extends NormalizedObject { class NormalizedTestObject extends NormalizedObject<Item> {
} }
class TestService extends DataService<NormalizedTestObject, any> { class TestService extends DataService<any> {
constructor( constructor(
protected requestService: RequestService, protected requestService: RequestService,
protected rdbService: RemoteDataBuildService, protected rdbService: RemoteDataBuildService,

View File

@@ -42,7 +42,7 @@ import { RequestEntry } from './request.reducer';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
export abstract class DataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> { export abstract class DataService<T extends CacheableObject> {
protected abstract requestService: RequestService; protected abstract requestService: RequestService;
protected abstract rdbService: RemoteDataBuildService; protected abstract rdbService: RemoteDataBuildService;
protected abstract dataBuildService: NormalizedObjectBuildService; protected abstract dataBuildService: NormalizedObjectBuildService;
@@ -52,7 +52,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
protected abstract objectCache: ObjectCacheService; protected abstract objectCache: ObjectCacheService;
protected abstract notificationsService: NotificationsService; protected abstract notificationsService: NotificationsService;
protected abstract http: HttpClient; protected abstract http: HttpClient;
protected abstract comparator: ChangeAnalyzer<TNormalized>; protected abstract comparator: ChangeAnalyzer<T>;
public abstract getBrowseEndpoint(options: FindAllOptions, linkPath?: string): Observable<string> public abstract getBrowseEndpoint(options: FindAllOptions, linkPath?: string): Observable<string>
@@ -81,7 +81,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
} }
} }
findAll(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<TDomain>>> { findAll(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<T>>> {
const hrefObs = this.getFindAllHref(options); const hrefObs = this.getFindAllHref(options);
hrefObs.pipe( hrefObs.pipe(
@@ -92,7 +92,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
this.requestService.configure(request); this.requestService.configure(request);
}); });
return this.rdbService.buildList<TNormalized, TDomain>(hrefObs) as Observable<RemoteData<PaginatedList<TDomain>>>; return this.rdbService.buildList<T>(hrefObs) as Observable<RemoteData<PaginatedList<T>>>;
} }
/** /**
@@ -104,7 +104,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
return `${endpoint}/${resourceID}`; return `${endpoint}/${resourceID}`;
} }
findById(id: string): Observable<RemoteData<TDomain>> { findById(id: string): Observable<RemoteData<T>> {
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe( const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, id))); map((endpoint: string) => this.getIDHref(endpoint, id)));
@@ -115,12 +115,12 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
this.requestService.configure(request); this.requestService.configure(request);
}); });
return this.rdbService.buildSingle<TNormalized, TDomain>(hrefObs); return this.rdbService.buildSingle<T>(hrefObs);
} }
findByHref(href: string): Observable<RemoteData<TDomain>> { findByHref(href: string): Observable<RemoteData<T>> {
this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href)); this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href));
return this.rdbService.buildSingle<TNormalized, TDomain>(href); return this.rdbService.buildSingle<T>(href);
} }
/** /**
@@ -137,11 +137,10 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
* The patch is derived from the differences between the given object and its version in the object cache * The patch is derived from the differences between the given object and its version in the object cache
* @param {DSpaceObject} object The given object * @param {DSpaceObject} object The given object
*/ */
update(object: TDomain): Observable<RemoteData<TDomain>> { update(object: T): Observable<RemoteData<T>> {
const oldVersion$ = this.objectCache.getBySelfLink(object.self); const oldVersion$ = this.objectCache.getBySelfLink(object.self);
return oldVersion$.pipe(take(1), mergeMap((oldVersion: TNormalized) => { return oldVersion$.pipe(take(1), mergeMap((oldVersion: T) => {
const newVersion = this.dataBuildService.normalize<TDomain, TNormalized>(object); const operations = this.comparator.diff(oldVersion, object);
const operations = this.comparator.diff(oldVersion, newVersion);
if (isNotEmpty(operations)) { if (isNotEmpty(operations)) {
this.objectCache.addPatch(object.self, operations); this.objectCache.addPatch(object.self, operations);
} }
@@ -160,7 +159,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
* @param {string} parentUUID * @param {string} parentUUID
* The UUID of the parent to create the new object under * The UUID of the parent to create the new object under
*/ */
create(dso: TDomain, parentUUID: string): Observable<RemoteData<TDomain>> { create(dso: T, parentUUID: string): Observable<RemoteData<T>> {
const requestId = this.requestService.generateRequestId(); const requestId = this.requestService.generateRequestId();
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe( const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
@@ -168,7 +167,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
map((endpoint: string) => parentUUID ? `${endpoint}?parentCommunity=${parentUUID}` : endpoint) map((endpoint: string) => parentUUID ? `${endpoint}?parentCommunity=${parentUUID}` : endpoint)
); );
const normalizedObject: TNormalized = this.dataBuildService.normalize<TDomain, TNormalized>(dso); const normalizedObject: NormalizedObject<T> = this.dataBuildService.normalize<T>(dso);
const serializedDso = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(dso.type)).serialize(normalizedObject); const serializedDso = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(dso.type)).serialize(normalizedObject);
const request$ = endpoint$.pipe( const request$ = endpoint$.pipe(
@@ -209,7 +208,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
* @param dso The DSpace Object to be removed * @param dso The DSpace Object to be removed
* Return an observable that emits true when the deletion was successful, false when it failed * Return an observable that emits true when the deletion was successful, false when it failed
*/ */
delete(dso: TDomain): Observable<boolean> { delete(dso: T): Observable<boolean> {
const requestId = this.requestService.generateRequestId(); const requestId = this.requestService.generateRequestId();
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe( const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(

View File

@@ -3,13 +3,14 @@ import { compare } from 'fast-json-patch';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model'; import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DSpaceObject } from '../shared/dspace-object.model';
/** /**
* A class to determine what differs between two * A class to determine what differs between two
* DSpaceObjects * DSpaceObjects
*/ */
@Injectable() @Injectable()
export class DSOChangeAnalyzer implements ChangeAnalyzer<NormalizedDSpaceObject> { export class DSOChangeAnalyzer<T extends DSpaceObject> implements ChangeAnalyzer<T> {
/** /**
* Compare the metadata of two DSpaceObjects and return the differences as * Compare the metadata of two DSpaceObjects and return the differences as
@@ -20,7 +21,7 @@ export class DSOChangeAnalyzer implements ChangeAnalyzer<NormalizedDSpaceObject>
* @param {NormalizedDSpaceObject} object2 * @param {NormalizedDSpaceObject} object2
* The second object to compare * The second object to compare
*/ */
diff(object1: NormalizedDSpaceObject, object2: NormalizedDSpaceObject): Operation[] { diff(object1: T | NormalizedDSpaceObject<T>, object2: T | NormalizedDSpaceObject<T>): Operation[] {
return compare(object1.metadata, object2.metadata).map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path })); return compare(object1.metadata, object2.metadata).map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path }));
} }
} }

View File

@@ -13,6 +13,7 @@ import { RestRequest } from './request.models';
import { ResponseParsingService } from './parsing.service'; import { ResponseParsingService } from './parsing.service';
import { BaseResponseParsingService } from './base-response-parsing.service'; import { BaseResponseParsingService } from './base-response-parsing.service';
import { hasNoValue, hasValue } from '../../shared/empty.util'; import { hasNoValue, hasValue } from '../../shared/empty.util';
import { DSpaceObject } from '../shared/dspace-object.model';
@Injectable() @Injectable()
export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
@@ -28,7 +29,7 @@ export class DSOResponseParsingService extends BaseResponseParsingService implem
} }
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const processRequestDTO = this.process<NormalizedObject, ResourceType>(data.payload, request.uuid); const processRequestDTO = this.process<NormalizedObject<DSpaceObject>, ResourceType>(data.payload, request.uuid);
let objectList = processRequestDTO; let objectList = processRequestDTO;
if (hasNoValue(processRequestDTO)) { if (hasNoValue(processRequestDTO)) {

View File

@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core.reducers';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -17,7 +16,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> { class DataServiceImpl extends DataService<DSpaceObject> {
protected linkPath = 'dso'; protected linkPath = 'dso';
constructor( constructor(
@@ -29,7 +28,7 @@ class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject>
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer) { protected comparator: DSOChangeAnalyzer<DSpaceObject>) {
super(); super();
} }
@@ -55,7 +54,7 @@ export class DSpaceObjectDataService {
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer) { protected comparator: DSOChangeAnalyzer<DSpaceObject>) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator); this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
} }

View File

@@ -1,12 +1,10 @@
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
import {distinctUntilChanged, map, filter} from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { isNotEmpty } from '../../shared/empty.util'; import { isNotEmpty } from '../../shared/empty.util';
import { BrowseService } from '../browse/browse.service'; import { BrowseService } from '../browse/browse.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedItem } from '../cache/models/normalized-item.model';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core.reducers';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { URLCombiner } from '../url-combiner/url-combiner'; import { URLCombiner } from '../url-combiner/url-combiner';
@@ -24,7 +22,7 @@ import { configureRequest, getRequestFromRequestHref } from '../shared/operators
import { RequestEntry } from './request.reducer'; import { RequestEntry } from './request.reducer';
@Injectable() @Injectable()
export class ItemDataService extends DataService<NormalizedItem, Item> { export class ItemDataService extends DataService<Item> {
protected linkPath = 'items'; protected linkPath = 'items';
constructor( constructor(
@@ -37,7 +35,7 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
protected http: HttpClient, protected http: HttpClient,
protected comparator: DSOChangeAnalyzer) { protected comparator: DSOChangeAnalyzer<Item>) {
super(); super();
} }

View File

@@ -8,17 +8,16 @@ import { CoreState } from '../core.reducers';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { FindAllOptions, GetRequest, RestRequest } from './request.models'; import { FindAllOptions } from './request.models';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { MetadataSchema } from '../metadata/metadataschema.model'; import { MetadataSchema } from '../metadata/metadataschema.model';
import { NormalizedMetadataSchema } from '../metadata/normalized-metadata-schema.model';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
@Injectable() @Injectable()
export class MetadataSchemaDataService extends DataService<NormalizedMetadataSchema, MetadataSchema> { export class MetadataSchemaDataService extends DataService<MetadataSchema> {
protected linkPath = 'metadataschemas'; protected linkPath = 'metadataschemas';
constructor( constructor(
@@ -28,7 +27,7 @@ export class MetadataSchemaDataService extends DataService<NormalizedMetadataSch
private bs: BrowseService, private bs: BrowseService,
protected halService: HALEndpointService, protected halService: HALEndpointService,
protected objectCache: ObjectCacheService, protected objectCache: ObjectCacheService,
protected comparator: ChangeAnalyzer<NormalizedMetadataSchema>, protected comparator: ChangeAnalyzer<MetadataSchema>,
protected dataBuildService: NormalizedObjectBuildService, protected dataBuildService: NormalizedObjectBuildService,
protected http: HttpClient, protected http: HttpClient,
protected notificationsService: NotificationsService) { protected notificationsService: NotificationsService) {
@@ -45,5 +44,4 @@ export class MetadataSchemaDataService extends DataService<NormalizedMetadataSch
return null; return null;
} }
} }

View File

@@ -8,68 +8,92 @@ export const ObjectUpdatesActionTypes = {
DISCARD: type('dspace/core/object-updates/DISCARD'), DISCARD: type('dspace/core/object-updates/DISCARD'),
REINSTATE: type('dspace/core/object-updates/REINSTATE'), REINSTATE: type('dspace/core/object-updates/REINSTATE'),
REMOVE: type('dspace/core/object-updates/REMOVE'), REMOVE: type('dspace/core/object-updates/REMOVE'),
REMOVE_SINGLE: type('dspace/core/object-updates/REMOVE_SINGLE') REMOVE_SINGLE: type('dspace/core/object-updates/REMOVE_SINGLE'),
REPLACE: type('dspace/core/object-updates/REPLACE')
}; };
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
export class AddToObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.ADD; export class ReplaceObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.REPLACE;
payload: { payload: {
url: string, url: string,
operation: Operation, operations: Operation[],
fieldID: string lastModified: number
}; };
constructor( constructor(
url: string, url: string,
operation: Operation, operations: Operation[],
fieldID: string lastModified: number
) { ) {
this.payload = { url, operation, fieldID }; this.payload = { url, operations, lastModified };
}
}
export class AddToObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.ADD;
payload: {
url: string,
operation: Operation
};
constructor(
url: string,
operation: Operation) {
this.payload = { url, operation };
} }
} }
export class ApplyObjectUpdatesAction implements Action { export class ApplyObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.APPLY; type = ObjectUpdatesActionTypes.APPLY;
payload: string; payload: {
url: string
};
constructor( constructor(
url: string url: string
) { ) {
this.payload = url; this.payload.url = url;
} }
} }
export class DiscardObjectUpdatesAction implements Action { export class DiscardObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.DISCARD; type = ObjectUpdatesActionTypes.DISCARD;
payload: string; payload: {
url: string
};
constructor( constructor(
url: string url: string
) { ) {
this.payload = url; this.payload.url = url;
} }
} }
export class ReinstateObjectUpdatesAction implements Action { export class ReinstateObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.REINSTATE; type = ObjectUpdatesActionTypes.REINSTATE;
payload: string; payload: {
url: string
};
constructor( constructor(
url: string url: string
) { ) {
this.payload = url; this.payload.url = url;
} }
} }
export class RemoveObjectUpdatesAction implements Action { export class RemoveObjectUpdatesAction implements Action {
type = ObjectUpdatesActionTypes.REMOVE; type = ObjectUpdatesActionTypes.REMOVE;
payload: string; payload: {
url: string
};
constructor( constructor(
url: string url: string
) { ) {
this.payload = url; this.payload.url = url;
} }
} }
@@ -87,6 +111,7 @@ export class RemoveSingleObjectUpdateAction implements Action {
this.payload = { url, fieldID }; this.payload = { url, fieldID };
} }
} }
/* tslint:enable:max-classes-per-file */ /* tslint:enable:max-classes-per-file */
/** /**
@@ -98,4 +123,5 @@ export type ObjectUpdatesAction
| DiscardObjectUpdatesAction | DiscardObjectUpdatesAction
| ReinstateObjectUpdatesAction | ReinstateObjectUpdatesAction
| RemoveObjectUpdatesAction | RemoveObjectUpdatesAction
| RemoveSingleObjectUpdateAction; | RemoveSingleObjectUpdateAction
| ReplaceObjectUpdatesAction;

View File

@@ -6,17 +6,13 @@ import {
ObjectUpdatesActionTypes, ObjectUpdatesActionTypes,
ReinstateObjectUpdatesAction, ReinstateObjectUpdatesAction,
RemoveObjectUpdatesAction, RemoveObjectUpdatesAction,
RemoveSingleObjectUpdateAction RemoveSingleObjectUpdateAction, ReplaceObjectUpdatesAction
} from './object-updates.actions'; } from './object-updates.actions';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { hasValue } from '../../../shared/empty.util'; import { hasValue } from '../../../shared/empty.util';
export interface ObjectUpdates {
[id: string]: Operation[]
}
export interface ObjectUpdatesEntry { export interface ObjectUpdatesEntry {
updates: ObjectUpdates; updates: Operation[];
lastServerUpdate: number; lastServerUpdate: number;
lastModified: number; lastModified: number;
discarded: boolean; discarded: boolean;
@@ -30,70 +26,96 @@ export interface ObjectUpdatesState {
const initialState = Object.create(null); const initialState = Object.create(null);
export function objectUpdatesReducer(state = initialState, action: ObjectUpdatesAction): ObjectUpdatesState { export function objectUpdatesReducer(state = initialState, action: ObjectUpdatesAction): ObjectUpdatesState {
let newState = state;
switch (action.type) { switch (action.type) {
case ObjectUpdatesActionTypes.REPLACE: {
newState = replaceObjectUpdates(state, action as ReplaceObjectUpdatesAction);
break;
}
case ObjectUpdatesActionTypes.ADD: { case ObjectUpdatesActionTypes.ADD: {
return addToObjectUpdates(state, action as AddToObjectUpdatesAction); newState = addToObjectUpdates(state, action as AddToObjectUpdatesAction);
break;
} }
case ObjectUpdatesActionTypes.APPLY: { case ObjectUpdatesActionTypes.APPLY: {
/* For now do nothing, handle in effect */ /* For now do nothing, handle in effect */
// return applyObjectUpdates(state, action as ApplyObjectUpdatesAction); // return applyObjectUpdates(state, action as ApplyObjectUpdatesAction);
return state; newState = state;
break;
} }
case ObjectUpdatesActionTypes.DISCARD: { case ObjectUpdatesActionTypes.DISCARD: {
return discardObjectUpdates(state, action as DiscardObjectUpdatesAction); newState = discardObjectUpdates(state, action as DiscardObjectUpdatesAction);
break;
} }
case ObjectUpdatesActionTypes.REINSTATE: { case ObjectUpdatesActionTypes.REINSTATE: {
return reinstateObjectUpdates(state, action as ReinstateObjectUpdatesAction); newState = reinstateObjectUpdates(state, action as ReinstateObjectUpdatesAction);
break;
} }
case ObjectUpdatesActionTypes.REMOVE: { case ObjectUpdatesActionTypes.REMOVE: {
return removeObjectUpdates(state, action as RemoveObjectUpdatesAction); newState = removeObjectUpdates(state, action as RemoveObjectUpdatesAction);
break;
} }
case ObjectUpdatesActionTypes.REMOVE_SINGLE: { case ObjectUpdatesActionTypes.REMOVE_SINGLE: {
return removeSingleObjectUpdates(state, action as RemoveSingleObjectUpdateAction); newState = removeSingleObjectUpdates(state, action as RemoveSingleObjectUpdateAction);
break;
}
default: {
return state;
} }
} }
return setLastModified(newState, action.payload.url);
}
function replaceObjectUpdates(state: any, action: ReplaceObjectUpdatesAction) {
const key: string = action.payload.url;
const operations: Operation[] = action.payload.operations;
const newUpdateEntry = Object.assign({}, state[key] || {}, { updates: operations });
return Object.assign({}, state, { [key]: newUpdateEntry });
} }
function addToObjectUpdates(state: any, action: AddToObjectUpdatesAction) { function addToObjectUpdates(state: any, action: AddToObjectUpdatesAction) {
const key: string = action.payload.url; const key: string = action.payload.url;
const operation: Operation = action.payload.operation;
const keyState = state[key] || { const keyState = state[key] || {
updates: {}, updates: {},
lastServerUpdate: 0, lastServerUpdate: 0,
lastModified: new Date(),
discarded: false discarded: false
}; };
const objectUpdates: Operation[] = keyState.updates[action.payload.fieldID] || []; const objectUpdates: Operation[] = keyState.updates || [];
const newUpdates = [...objectUpdates, action.payload.operation]; const newUpdates = [...objectUpdates, operation];
const newKeyState = Object.assign(state[key], { updates: newUpdates }); const newKeyState = Object.assign({}, state[key], { updates: newUpdates });
return Object.assign(state, newKeyState); return Object.assign({}, state, newKeyState);
} }
function discardObjectUpdates(state: any, action: DiscardObjectUpdatesAction) { function discardObjectUpdates(state: any, action: DiscardObjectUpdatesAction) {
const key: string = action.payload; const key: string = action.payload.url;
const keyState = state[key]; const keyState = state[key];
if (hasValue(keyState)) { if (hasValue(keyState)) {
const newKeyState = Object.assign(keyState, { discarded: true }); const newKeyState = Object.assign({}, keyState, { discarded: true });
return Object.assign(state, newKeyState); return Object.assign({}, state, newKeyState);
} }
return state; return state;
} }
function reinstateObjectUpdates(state: any, action: ReinstateObjectUpdatesAction) { function reinstateObjectUpdates(state: any, action: ReinstateObjectUpdatesAction) {
const key: string = action.payload; const key: string = action.payload.url;
const keyState = state[key]; const keyState = state[key];
if (hasValue(keyState)) { if (hasValue(keyState)) {
const newKeyState = Object.assign(keyState, { discarded: false }); const newKeyState = Object.assign({}, keyState, { discarded: false });
return Object.assign(state, newKeyState); return Object.assign({}, state, newKeyState);
} }
return state; return state;
} }
function removeObjectUpdates(state: any, action: RemoveObjectUpdatesAction) { function removeObjectUpdates(state: any, action: RemoveObjectUpdatesAction) {
const key: string = action.payload; const key: string = action.payload.url;
const keyState = state[key]; return removeObjectUpdatesByURL(state, key);
const newState = Object.assign(state); }
function removeObjectUpdatesByURL(state: any, url: string) {
const keyState = state[url];
const newState = Object.assign({}, state);
if (hasValue(keyState)) { if (hasValue(keyState)) {
delete newState[key]; delete newState[url];
} }
return newState; return newState;
} }
@@ -102,11 +124,16 @@ function removeSingleObjectUpdates(state: any, action: RemoveSingleObjectUpdateA
const key: string = action.payload.url; const key: string = action.payload.url;
let newKeyState = state[key]; let newKeyState = state[key];
if (hasValue(newKeyState)) { if (hasValue(newKeyState)) {
const newUpdates: Operation[] = Object.assign(newKeyState.updates); const newUpdates: Operation[] = Object.assign({}, newKeyState.updates);
if (hasValue(newUpdates[action.payload.fieldID])) { if (hasValue(newUpdates[action.payload.fieldID])) {
delete newUpdates[action.payload.fieldID]; delete newUpdates[action.payload.fieldID];
} }
newKeyState = Object.assign(state[key], { updates: newUpdates }); newKeyState = Object.assign({}, state[key], { updates: newUpdates });
} }
return Object.assign(state, newKeyState); return Object.assign({}, state, newKeyState);
}
function setLastModified(state: any, url: string) {
const newKeyState = Object.assign({}, state[url] || {}, { lastModified: Date.now() });
return Object.assign({}, state, newKeyState);
} }

View File

@@ -19,4 +19,7 @@ export class EPerson extends DSpaceObject {
public selfRegistered: boolean; public selfRegistered: boolean;
get name(): string {
return this.findMetadata('eperson.firstname') + ' ' + this.findMetadata('eperson.lastname');
}
} }

View File

@@ -8,7 +8,7 @@ import { ResourceType } from '../../shared/resource-type';
@mapsTo(EPerson) @mapsTo(EPerson)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedEPerson extends NormalizedDSpaceObject implements CacheableObject, ListableObject { export class NormalizedEPerson extends NormalizedDSpaceObject<EPerson> implements CacheableObject, ListableObject {
@autoserialize @autoserialize
public handle: string; public handle: string;

View File

@@ -7,7 +7,7 @@ import { Group } from './group.model';
@mapsTo(Group) @mapsTo(Group)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedGroup extends NormalizedDSpaceObject implements CacheableObject, ListableObject { export class NormalizedGroup extends NormalizedDSpaceObject<Group> implements CacheableObject, ListableObject {
@autoserialize @autoserialize
public handle: string; public handle: string;

View File

@@ -6,7 +6,7 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-o
import { MetadataSchema } from './metadataschema.model'; import { MetadataSchema } from './metadataschema.model';
@mapsTo(MetadataSchema) @mapsTo(MetadataSchema)
export class NormalizedMetadataSchema extends NormalizedObject implements CacheableObject, ListableObject { export class NormalizedMetadataSchema extends NormalizedObject<MetadataSchema> implements ListableObject {
@autoserialize @autoserialize
id: number; id: number;

View File

@@ -14,7 +14,7 @@
<div ngbDropdown placement="bottom-right" class="d-inline-block" @fadeInOut> <div ngbDropdown placement="bottom-right" class="d-inline-block" @fadeInOut>
<a href="#" id="dropdownUser" (click)="$event.preventDefault()" class="px-1" ngbDropdownToggle><i class="fas fa-user-circle fa-lg fa-fw" [title]="'nav.logout' | translate"></i></a> <a href="#" id="dropdownUser" (click)="$event.preventDefault()" class="px-1" ngbDropdownToggle><i class="fas fa-user-circle fa-lg fa-fw" [title]="'nav.logout' | translate"></i></a>
<ul id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser"> <ul id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser">
<li class="dropdown-item">{{(user | async).name}}</li> <li class="dropdown-item">{{(user | async).name}} ({{(user | async).email}})</li>
<li class="dropdown-item"><ds-log-out></ds-log-out></li> <li class="dropdown-item"><ds-log-out></ds-log-out></li>
</ul> </ul>
</div> </div>

View File

@@ -11,13 +11,12 @@ import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
import { CreateComColPageComponent } from './create-comcol-page.component'; import { CreateComColPageComponent } from './create-comcol-page.component';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
describe('CreateComColPageComponent', () => { describe('CreateComColPageComponent', () => {
let comp: CreateComColPageComponent<DSpaceObject, NormalizedDSpaceObject>; let comp: CreateComColPageComponent<DSpaceObject>;
let fixture: ComponentFixture<CreateComColPageComponent<DSpaceObject, NormalizedDSpaceObject>>; let fixture: ComponentFixture<CreateComColPageComponent<DSpaceObject>>;
let communityDataService: CommunityDataService; let communityDataService: CommunityDataService;
let dsoDataService: CommunityDataService; let dsoDataService: CommunityDataService;
let routeService: RouteService; let routeService: RouteService;

View File

@@ -10,7 +10,6 @@ import { take } from 'rxjs/operators';
import { getSucceededRemoteData } from '../../../core/shared/operators'; import { getSucceededRemoteData } from '../../../core/shared/operators';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
/** /**
* Component representing the create page for communities and collections * Component representing the create page for communities and collections
@@ -19,7 +18,7 @@ import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-ds
selector: 'ds-create-comcol', selector: 'ds-create-comcol',
template: '' template: ''
}) })
export class CreateComColPageComponent<TDomain extends DSpaceObject, TNormalized extends NormalizedDSpaceObject> implements OnInit { export class CreateComColPageComponent<TDomain extends DSpaceObject> implements OnInit {
/** /**
* Frontend endpoint for this type of DSO * Frontend endpoint for this type of DSO
*/ */
@@ -36,7 +35,7 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject, TNormalized
public parentRD$: Observable<RemoteData<Community>>; public parentRD$: Observable<RemoteData<Community>>;
public constructor( public constructor(
protected dsoDataService: DataService<TNormalized, TDomain>, protected dsoDataService: DataService<TDomain>,
protected parentDataService: CommunityDataService, protected parentDataService: CommunityDataService,
protected routeService: RouteService, protected routeService: RouteService,
protected router: Router protected router: Router

View File

@@ -9,15 +9,14 @@ import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
import { DeleteComColPageComponent } from './delete-comcol-page.component'; import { DeleteComColPageComponent } from './delete-comcol-page.component';
import { NotificationsService } from '../../notifications/notifications.service'; import { NotificationsService } from '../../notifications/notifications.service';
import { NotificationsServiceStub } from '../../testing/notifications-service-stub'; import { NotificationsServiceStub } from '../../testing/notifications-service-stub';
describe('DeleteComColPageComponent', () => { describe('DeleteComColPageComponent', () => {
let comp: DeleteComColPageComponent<DSpaceObject, NormalizedDSpaceObject>; let comp: DeleteComColPageComponent<DSpaceObject>;
let fixture: ComponentFixture<DeleteComColPageComponent<DSpaceObject, NormalizedDSpaceObject>>; let fixture: ComponentFixture<DeleteComColPageComponent<DSpaceObject>>;
let dsoDataService: CommunityDataService; let dsoDataService: CommunityDataService;
let router: Router; let router: Router;

View File

@@ -1,13 +1,9 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RouteService } from '../../services/route.service';
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';
import { isNotUndefined } from '../../empty.util';
import { first, map } from 'rxjs/operators'; import { first, map } from 'rxjs/operators';
import { getSucceededRemoteData } from '../../../core/shared/operators';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NotificationsService } from '../../notifications/notifications.service'; import { NotificationsService } from '../../notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@@ -19,7 +15,7 @@ import { TranslateService } from '@ngx-translate/core';
selector: 'ds-delete-comcol', selector: 'ds-delete-comcol',
template: '' template: ''
}) })
export class DeleteComColPageComponent<TDomain extends DSpaceObject, TNormalized extends NormalizedDSpaceObject> implements OnInit { export class DeleteComColPageComponent<TDomain extends DSpaceObject> implements OnInit {
/** /**
* Frontend endpoint for this type of DSO * Frontend endpoint for this type of DSO
*/ */
@@ -30,7 +26,7 @@ export class DeleteComColPageComponent<TDomain extends DSpaceObject, TNormalized
public dsoRD$: Observable<RemoteData<TDomain>>; public dsoRD$: Observable<RemoteData<TDomain>>;
public constructor( public constructor(
protected dsoDataService: DataService<TNormalized, TDomain>, protected dsoDataService: DataService<TDomain>,
protected router: Router, protected router: Router,
protected route: ActivatedRoute, protected route: ActivatedRoute,
protected notifications: NotificationsService, protected notifications: NotificationsService,

View File

@@ -10,13 +10,12 @@ import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
import { EditComColPageComponent } from './edit-comcol-page.component'; import { EditComColPageComponent } from './edit-comcol-page.component';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
describe('EditComColPageComponent', () => { describe('EditComColPageComponent', () => {
let comp: EditComColPageComponent<DSpaceObject, NormalizedDSpaceObject>; let comp: EditComColPageComponent<DSpaceObject>;
let fixture: ComponentFixture<EditComColPageComponent<DSpaceObject, NormalizedDSpaceObject>>; let fixture: ComponentFixture<EditComColPageComponent<DSpaceObject>>;
let dsoDataService: CommunityDataService; let dsoDataService: CommunityDataService;
let router: Router; let router: Router;

View File

@@ -6,7 +6,6 @@ import { isNotUndefined } from '../../empty.util';
import { first, map } from 'rxjs/operators'; import { first, map } from 'rxjs/operators';
import { getSucceededRemoteData } from '../../../core/shared/operators'; import { getSucceededRemoteData } from '../../../core/shared/operators';
import { DataService } from '../../../core/data/data.service'; import { DataService } from '../../../core/data/data.service';
import { NormalizedDSpaceObject } from '../../../core/cache/models/normalized-dspace-object.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
/** /**
@@ -16,7 +15,7 @@ import { DSpaceObject } from '../../../core/shared/dspace-object.model';
selector: 'ds-edit-comcol', selector: 'ds-edit-comcol',
template: '' template: ''
}) })
export class EditComColPageComponent<TDomain extends DSpaceObject, TNormalized extends NormalizedDSpaceObject> implements OnInit { export class EditComColPageComponent<TDomain extends DSpaceObject> implements OnInit {
/** /**
* Frontend endpoint for this type of DSO * Frontend endpoint for this type of DSO
*/ */
@@ -27,7 +26,7 @@ export class EditComColPageComponent<TDomain extends DSpaceObject, TNormalized e
public dsoRD$: Observable<RemoteData<TDomain>>; public dsoRD$: Observable<RemoteData<TDomain>>;
public constructor( public constructor(
protected dsoDataService: DataService<TNormalized, TDomain>, protected dsoDataService: DataService<TDomain>,
protected router: Router, protected router: Router,
protected route: ActivatedRoute protected route: ActivatedRoute
) { ) {