mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 18:44:14 +00:00
got rid of TNormalized everywhere
This commit is contained in:
@@ -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(
|
||||||
|
@@ -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(
|
||||||
|
@@ -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(
|
||||||
|
@@ -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(
|
||||||
|
@@ -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(
|
||||||
|
@@ -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(
|
||||||
|
@@ -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>
|
||||||
|
@@ -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() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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'));
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
);
|
);
|
||||||
|
@@ -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) || [];
|
||||||
|
|
||||||
|
@@ -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) || [];
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
10
src/app/core/cache/object-cache.service.ts
vendored
10
src/app/core/cache/object-cache.service.ts
vendored
@@ -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))
|
||||||
);
|
);
|
||||||
|
@@ -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[];
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
|
@@ -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;
|
||||||
|
@@ -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>>>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
@@ -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(
|
||||||
|
@@ -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 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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)) {
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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
|
||||||
) {
|
) {
|
||||||
|
Reference in New Issue
Block a user