diff --git a/src/app/+admin/admin-registries/metadata-registry/metadata-registry.reducers.spec.ts b/src/app/+admin/admin-registries/metadata-registry/metadata-registry.reducers.spec.ts index f23c12c109..2f7d606c60 100644 --- a/src/app/+admin/admin-registries/metadata-registry/metadata-registry.reducers.spec.ts +++ b/src/app/+admin/admin-registries/metadata-registry/metadata-registry.reducers.spec.ts @@ -7,8 +7,8 @@ import { MetadataRegistrySelectSchemaAction } from './metadata-registry.actions'; import { metadataRegistryReducer, MetadataRegistryState } from './metadata-registry.reducers'; -import { MetadataSchema } from '../../../core/metadata/metadataschema.model'; -import { MetadataField } from '../../../core/metadata/metadatafield.model'; +import { MetadataSchema } from '../../../core/metadata/metadata-schema.model'; +import { MetadataField } from '../../../core/metadata/metadata-field.model'; class NullAction extends MetadataRegistryEditSchemaAction { type = null; diff --git a/src/app/+admin/admin-registries/metadata-registry/metadata-schema-form/metadata-schema-form.component.spec.ts b/src/app/+admin/admin-registries/metadata-registry/metadata-schema-form/metadata-schema-form.component.spec.ts index 42b6d1f133..fb76035d4b 100644 --- a/src/app/+admin/admin-registries/metadata-registry/metadata-schema-form/metadata-schema-form.component.spec.ts +++ b/src/app/+admin/admin-registries/metadata-registry/metadata-schema-form/metadata-schema-form.component.spec.ts @@ -10,7 +10,7 @@ import { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe'; import { RegistryService } from '../../../../core/registry/registry.service'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { MetadataSchema } from '../../../../core/metadata/metadataschema.model'; +import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model'; describe('MetadataSchemaFormComponent', () => { let component: MetadataSchemaFormComponent; diff --git a/src/app/+admin/admin-registries/metadata-schema/metadata-field-form/metadata-field-form.component.spec.ts b/src/app/+admin/admin-registries/metadata-schema/metadata-field-form/metadata-field-form.component.spec.ts index 4364b0234a..45df65ebe5 100644 --- a/src/app/+admin/admin-registries/metadata-schema/metadata-field-form/metadata-field-form.component.spec.ts +++ b/src/app/+admin/admin-registries/metadata-schema/metadata-field-form/metadata-field-form.component.spec.ts @@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing' import { MetadataFieldFormComponent } from './metadata-field-form.component'; import { RegistryService } from '../../../../core/registry/registry.service'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { MetadataField } from '../../../../core/metadata/metadatafield.model'; import { CommonModule } from '@angular/common'; import { RouterTestingModule } from '@angular/router/testing'; import { TranslateModule } from '@ngx-translate/core'; @@ -11,7 +10,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MetadataSchema } from '../../../../core/metadata/metadataschema.model'; +import { MetadataField } from '../../../../core/metadata/metadata-field.model'; +import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model'; describe('MetadataFieldFormComponent', () => { let component: MetadataFieldFormComponent; diff --git a/src/app/+admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts b/src/app/+admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts index 674798848b..9cec4475ea 100644 --- a/src/app/+admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts +++ b/src/app/+admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts @@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing' import { of as observableOf } from 'rxjs'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list'; -import { MetadataSchema } from '../../../core/metadata/metadataschema.model'; import { TranslateModule } from '@ngx-translate/core'; import { CommonModule } from '@angular/common'; import { ActivatedRoute, Router } from '@angular/router'; @@ -21,6 +20,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub'; import { RestResponse } from '../../../core/cache/response.models'; +import { MetadataSchema } from '../../../core/metadata/metadata-schema.model'; describe('MetadataSchemaComponent', () => { let comp: MetadataSchemaComponent; diff --git a/src/app/+browse-by/+browse-by-metadata-page/browse-by-metadata-page.component.spec.ts b/src/app/+browse-by/+browse-by-metadata-page/browse-by-metadata-page.component.spec.ts index 98d7299984..26a4ff8fd5 100644 --- a/src/app/+browse-by/+browse-by-metadata-page/browse-by-metadata-page.component.spec.ts +++ b/src/app/+browse-by/+browse-by-metadata-page/browse-by-metadata-page.component.spec.ts @@ -20,6 +20,7 @@ import { Item } from '../../core/shared/item.model'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { Community } from '../../core/shared/community.model'; import { MockRouter } from '../../shared/mocks/mock-router'; +import { ResourceType } from '../../core/shared/resource-type'; describe('BrowseByMetadataPageComponent', () => { let comp: BrowseByMetadataPageComponent; @@ -39,21 +40,21 @@ describe('BrowseByMetadataPageComponent', () => { const mockEntries = [ { - type: 'author', + type: ResourceType.BrowseEntry, authority: null, value: 'John Doe', language: 'en', count: 1 }, { - type: 'author', + type: ResourceType.BrowseEntry, authority: null, value: 'James Doe', language: 'en', count: 3 }, { - type: 'subject', + type: ResourceType.BrowseEntry, authority: null, value: 'Fake subject', language: 'en', @@ -68,7 +69,7 @@ describe('BrowseByMetadataPageComponent', () => { ]; const mockBrowseService = { - getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData(mockEntries.filter((entry) => entry.type === options.metadataDefinition)), + getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData(mockEntries), getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData(mockItems) }; @@ -105,12 +106,6 @@ describe('BrowseByMetadataPageComponent', () => { fixture.detectChanges(); }); - it('should fetch the correct entries depending on the metadata definition', () => { - comp.browseEntries$.subscribe((result) => { - expect(result.payload.page).toEqual(mockEntries.filter((entry) => entry.type === 'author')); - }); - }); - it('should not fetch any items when no value is provided', () => { expect(comp.items$).toBeUndefined(); }); diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts index 09363b9964..bd1a4e5545 100644 --- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts @@ -6,17 +6,17 @@ import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec import { of as observableOf } from 'rxjs'; import { RemoteData } from '../../../../core/data/remote-data'; import { PaginatedList } from '../../../../core/data/paginated-list'; -import { MetadataField } from '../../../../core/metadata/metadatafield.model'; import { By } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { SharedModule } from '../../../../shared/shared.module'; import { getTestScheduler } from 'jasmine-marbles'; import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { TestScheduler } from 'rxjs/testing'; -import { MetadataSchema } from '../../../../core/metadata/metadataschema.model'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { TranslateModule } from '@ngx-translate/core'; import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; +import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model'; +import { MetadataField } from '../../../../core/metadata/metadata-field.model'; let comp: EditInPlaceFieldComponent; let fixture: ComponentFixture; diff --git a/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts b/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts index f2cd74fc2f..90008f3d72 100644 --- a/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts @@ -24,9 +24,9 @@ import { RemoteData } from '../../../core/data/remote-data'; import { MetadatumViewModel } from '../../../core/shared/metadata.models'; import { RegistryService } from '../../../core/registry/registry.service'; import { PaginatedList } from '../../../core/data/paginated-list'; -import { MetadataSchema } from '../../../core/metadata/metadataschema.model'; -import { MetadataField } from '../../../core/metadata/metadatafield.model'; import { Metadata } from '../../../core/shared/metadata.utils'; +import { MetadataSchema } from '../../../core/metadata/metadata-schema.model'; +import { MetadataField } from '../../../core/metadata/metadata-field.model'; let comp: ItemMetadataComponent; let fixture: ComponentFixture; diff --git a/src/app/core/auth/auth.service.spec.ts b/src/app/core/auth/auth.service.spec.ts index ebb4026265..e766a45e48 100644 --- a/src/app/core/auth/auth.service.spec.ts +++ b/src/app/core/auth/auth.service.spec.ts @@ -43,7 +43,7 @@ describe('AuthService test', () => { pipe: observableOf(true) }); window = new NativeWindowRef(); - routerStub = new RouterStub() + routerStub = new RouterStub(); token = new AuthTokenInfo('test_token'); token.expires = Date.now() + (1000 * 60 * 60); authenticatedState = { diff --git a/src/app/core/auth/models/auth-status.model.ts b/src/app/core/auth/models/auth-status.model.ts index 40ca71aa1b..5349a574af 100644 --- a/src/app/core/auth/models/auth-status.model.ts +++ b/src/app/core/auth/models/auth-status.model.ts @@ -3,25 +3,56 @@ import { AuthTokenInfo } from './auth-token-info.model'; import { EPerson } from '../../eperson/models/eperson.model'; import { RemoteData } from '../../data/remote-data'; import { Observable } from 'rxjs'; -import { CacheableObject, TypedObject } from '../../cache/object-cache.reducer'; +import { CacheableObject } from '../../cache/object-cache.reducer'; import { ResourceType } from '../../shared/resource-type'; -export class AuthStatus implements CacheableObject, TypedObject { - +/** + * Object that represents the authenticated status of a user + */ +export class AuthStatus implements CacheableObject { + /** + * The unique identifier of this auth status + */ id: string; + /** + * The unique uuid of this auth status + */ + uuid: string; + + /** + * True if REST API is up and running, should never return false + */ okay: boolean; + /** + * If the auth status represents an authenticated state + */ authenticated: boolean; + /** + * Authentication error if there was one for this status + */ error?: AuthError; + /** + * The eperson of this auth status + */ eperson: Observable>; + /** + * True if the token is valid, false if there was no token or the token wasn't valid + */ token?: AuthTokenInfo; + /** + * The self link of this auth status' REST object + */ self: string; + /** + * The resource object of this auth status + */ type: ResourceType; } diff --git a/src/app/core/auth/models/normalized-auth-status.model.ts b/src/app/core/auth/models/normalized-auth-status.model.ts index 50956935ef..7693e330a2 100644 --- a/src/app/core/auth/models/normalized-auth-status.model.ts +++ b/src/app/core/auth/models/normalized-auth-status.model.ts @@ -10,9 +10,15 @@ import { resourceType } from '../../shared/resource-type.decorator'; @inheritSerialization(NormalizedObject) @resourceType(ResourceType.AuthStatus) export class NormalizedAuthStatus extends NormalizedObject { + /** + * The unique identifier of this auth status + */ @autoserialize id: string; + /** + * The unique generated uuid of this auth status + */ @autoserializeAs(new IDToUUIDSerializer('auth-status'), 'id') uuid: string; @@ -28,11 +34,16 @@ export class NormalizedAuthStatus extends NormalizedObject { @autoserialize authenticated: boolean; + /** + * The self link to the eperson of this auth status + */ @relationship(ResourceType.EPerson, false) @autoserialize eperson: string; - + /** + * The resource object of this auth status + */ @autoserialize type: ResourceType; } diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 18687e254d..6b8034bafd 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -29,7 +29,7 @@ export class RemoteDataBuildService { protected requestService: RequestService) { } - buildSingle(href$: string | Observable): Observable> { + buildSingle(href$: string | Observable): Observable> { if (typeof href$ === 'string') { href$ = observableOf(href$); } @@ -107,7 +107,7 @@ export class RemoteDataBuildService { ); } - buildList(href$: string | Observable): Observable>> { + buildList(href$: string | Observable): Observable>> { if (typeof href$ === 'string') { href$ = observableOf(href$); } @@ -149,7 +149,7 @@ export class RemoteDataBuildService { return this.toRemoteDataObservable(requestEntry$, payload$); } - build(normalized: NormalizedObject): T { + build(normalized: NormalizedObject): T { const links: any = {}; const relationships = getRelationships(normalized.constructor) || []; diff --git a/src/app/core/cache/models/normalized-object.model.ts b/src/app/core/cache/models/normalized-object.model.ts index a80da98cca..ee758d984d 100644 --- a/src/app/core/cache/models/normalized-object.model.ts +++ b/src/app/core/cache/models/normalized-object.model.ts @@ -4,7 +4,7 @@ import { ResourceType } from '../../shared/resource-type'; /** * An abstract model class for a NormalizedObject. */ -export abstract class NormalizedObject implements CacheableObject, TypedObject { +export abstract class NormalizedObject implements CacheableObject { /** * The link to the rest endpoint where this object can be found diff --git a/src/app/core/cache/object-cache.reducer.spec.ts b/src/app/core/cache/object-cache.reducer.spec.ts index efa28d7249..4d4f5c745b 100644 --- a/src/app/core/cache/object-cache.reducer.spec.ts +++ b/src/app/core/cache/object-cache.reducer.spec.ts @@ -9,6 +9,7 @@ import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; import { Operation } from 'fast-json-patch'; +import { ResourceType } from '../shared/resource-type'; class NullAction extends RemoveFromObjectCacheAction { type = null; @@ -28,6 +29,7 @@ describe('objectCacheReducer', () => { const testState = { [selfLink1]: { data: { + type: ResourceType.Item, self: selfLink1, foo: 'bar' }, @@ -39,6 +41,7 @@ describe('objectCacheReducer', () => { }, [selfLink2]: { data: { + type: ResourceType.Item, self: requestUUID2, foo: 'baz' }, @@ -67,7 +70,7 @@ describe('objectCacheReducer', () => { it('should add the payload to the cache in response to an ADD action', () => { const state = Object.create(null); - const objectToCache = { self: selfLink1 }; + const objectToCache = { self: selfLink1, type: ResourceType.Item }; const timeAdded = new Date().getTime(); const msToLive = 900000; const requestUUID = requestUUID1; @@ -80,7 +83,12 @@ describe('objectCacheReducer', () => { }); it('should overwrite an object in the cache in response to an ADD action if it already exists', () => { - const objectToCache = { self: selfLink1, foo: 'baz', somethingElse: true }; + const objectToCache = { + self: selfLink1, + foo: 'baz', + somethingElse: true, + type: ResourceType.Item + }; const timeAdded = new Date().getTime(); const msToLive = 900000; const requestUUID = requestUUID1; @@ -95,7 +103,7 @@ describe('objectCacheReducer', () => { it('should perform the ADD action without affecting the previous state', () => { const state = Object.create(null); - const objectToCache = { self: selfLink1 }; + const objectToCache = { self: selfLink1, type: ResourceType.Item }; const timeAdded = new Date().getTime(); const msToLive = 900000; const requestUUID = requestUUID1; diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index 97a48af1c1..9529fb2890 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -35,12 +35,13 @@ export interface Patch { export interface TypedObject { type: ResourceType; } + /** * An interface to represent objects that can be cached * * A cacheable object should have a self link */ -export interface CacheableObject { +export interface CacheableObject extends TypedObject { uuid?: string; self: string; // isNew: boolean; @@ -50,8 +51,6 @@ export interface CacheableObject { // save(): void; } -// export type TypedCacheableObject = TypedObject & CacheableObject; - /** * An entry in the ObjectCache */ diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 483de65b98..4b4eaca196 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -4,13 +4,12 @@ import { applyPatch, Operation } from 'fast-json-patch'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { distinctUntilChanged, filter, map, mergeMap, take, } from 'rxjs/operators'; -import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util'; +import { hasNoValue, isNotEmpty } from '../../shared/empty.util'; import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { RestRequestMethod } from '../data/rest-request-method'; import { selfLinkFromUuidSelector } from '../index/index.selectors'; import { GenericConstructor } from '../shared/generic-constructor'; -import { NormalizedObjectFactory } from './models/normalized-object-factory'; import { NormalizedObject } from './models/normalized-object.model'; import { AddPatchObjectCacheAction, @@ -21,6 +20,7 @@ import { import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer'; import { AddToSSBAction } from './server-sync-buffer.actions'; +import { getNormalizedConstructorByType } from '../shared/resource-type.decorator'; /** * The base selector function to select the object cache in the store @@ -109,7 +109,7 @@ export class ObjectCacheService { } ), map((entry: ObjectCacheEntry) => { - const type: GenericConstructor> = NormalizedObjectFactory.getConstructor(entry.data.type); + const type: GenericConstructor> = getNormalizedConstructorByType(entry.data.type); return Object.assign(new type(), entry.data) as NormalizedObject }) ); diff --git a/src/app/core/config/config-response-parsing.service.ts b/src/app/core/config/config-response-parsing.service.ts index de85b911bd..08fe581406 100644 --- a/src/app/core/config/config-response-parsing.service.ts +++ b/src/app/core/config/config-response-parsing.service.ts @@ -5,10 +5,8 @@ import { RestRequest } from '../data/request.models'; import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model'; import { ConfigSuccessResponse, ErrorResponse, RestResponse } from '../cache/response.models'; import { isNotEmpty } from '../../shared/empty.util'; -import { ConfigObjectFactory } from './models/config-object-factory'; import { ConfigObject } from './models/config.model'; -import { ConfigType } from './models/config-type'; import { BaseResponseParsingService } from '../data/base-response-parsing.service'; import { GLOBAL_CONFIG } from '../../../config'; import { GlobalConfig } from '../../../config/global-config.interface'; @@ -26,7 +24,7 @@ export class ConfigResponseParsingService extends BaseResponseParsingService imp parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 201 || data.statusCode === 200)) { - const configDefinition = this.process(data.payload, request.uuid); + const configDefinition = this.process(data.payload, request.uuid); return new ConfigSuccessResponse(configDefinition, data.statusCode, data.statusText, this.processPageInfo(data.payload)); } else { return new ErrorResponse( diff --git a/src/app/core/config/models/config.model.ts b/src/app/core/config/models/config.model.ts index 2a7c3da882..81f20a0b3c 100644 --- a/src/app/core/config/models/config.model.ts +++ b/src/app/core/config/models/config.model.ts @@ -1,7 +1,7 @@ -import { CacheableObject, TypedObject } from '../../cache/object-cache.reducer'; +import { CacheableObject } from '../../cache/object-cache.reducer'; import { ResourceType } from '../../shared/resource-type'; -export abstract class ConfigObject implements CacheableObject, TypedObject { +export abstract class ConfigObject implements CacheableObject { /** * The name for this configuration diff --git a/src/app/core/config/models/normalized-config.model.ts b/src/app/core/config/models/normalized-config.model.ts index c463cd8b08..d10be2d1c3 100644 --- a/src/app/core/config/models/normalized-config.model.ts +++ b/src/app/core/config/models/normalized-config.model.ts @@ -7,7 +7,7 @@ import { ResourceType } from '../../shared/resource-type'; * Normalized abstract class for a configuration object */ @inheritSerialization(NormalizedObject) -export abstract class NormalizedConfigObject implements CacheableObject, TypedObject { +export abstract class NormalizedConfigObject implements CacheableObject { /** * The name for this configuration diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 2ca5af0294..ef6f508226 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -1,14 +1,13 @@ -import { - ModuleWithProviders, - NgModule, - Optional, - SkipSelf -} from '@angular/core'; +import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { CommonModule } from '@angular/common'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; -import { DynamicFormLayoutService, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; +import { + DynamicFormLayoutService, + DynamicFormService, + DynamicFormValidationService +} from '@ng-dynamic-forms/core'; import { coreEffects } from './core.effects'; import { coreReducers } from './core.reducers'; @@ -80,6 +79,27 @@ import { DSOChangeAnalyzer } from './data/dso-change-analyzer.service'; import { ObjectUpdatesService } from './data/object-updates/object-updates.service'; import { DefaultChangeAnalyzer } from './data/default-change-analyzer.service'; import { SearchService } from '../+search-page/search-service/search.service'; +import { NormalizedCollection } from './cache/models/normalized-collection.model'; +import { NormalizedCommunity } from './cache/models/normalized-community.model'; +import { NormalizedDSpaceObject } from './cache/models/normalized-dspace-object.model'; +import { NormalizedBitstream } from './cache/models/normalized-bitstream.model'; +import { NormalizedBundle } from './cache/models/normalized-bundle.model'; +import { NormalizedBitstreamFormat } from './cache/models/normalized-bitstream-format.model'; +import { NormalizedItem } from './cache/models/normalized-item.model'; +import { NormalizedEPerson } from './eperson/models/normalized-eperson.model'; +import { NormalizedGroup } from './eperson/models/normalized-group.model'; +import { NormalizedResourcePolicy } from './cache/models/normalized-resource-policy.model'; +import { NormalizedMetadataSchema } from './metadata/normalized-metadata-schema.model'; +import { NormalizedMetadataField } from './metadata/normalized-metadata-field.model'; +import { NormalizedLicense } from './cache/models/normalized-license.model'; +import { NormalizedWorkflowItem } from './submission/models/normalized-workflowitem.model'; +import { NormalizedWorkspaceItem } from './submission/models/normalized-workspaceitem.model'; +import { NormalizedSubmissionDefinitionsModel } from './config/models/normalized-config-submission-definitions.model'; +import { NormalizedSubmissionFormsModel } from './config/models/normalized-config-submission-forms.model'; +import { NormalizedSubmissionSectionModel } from './config/models/normalized-config-submission-section.model'; +import { NormalizedAuthStatus } from './auth/models/normalized-auth-status.model'; +import { NormalizedAuthorityValue } from './integration/models/normalized-authority-value.model'; +import { BrowseEntry } from './shared/browse-entry.model'; const IMPORTS = [ CommonModule, @@ -87,13 +107,9 @@ const IMPORTS = [ EffectsModule.forFeature(coreEffects) ]; -const DECLARATIONS = [ +const DECLARATIONS = []; -]; - -const EXPORTS = [ - -]; +const EXPORTS = []; const PROVIDERS = [ ApiService, @@ -169,9 +185,37 @@ const PROVIDERS = [ multi: true }, NotificationsService, - { provide: NativeWindowService, useFactory: NativeWindowFactory } + { provide: NativeWindowService, useFactory: NativeWindowFactory }, ]; +/** + * Declaration needed to make sure all decorator functions are called in time + */ +export const normalizedModels = + [ + NormalizedDSpaceObject, + NormalizedBundle, + NormalizedBitstream, + NormalizedBitstreamFormat, + NormalizedItem, + NormalizedCollection, + NormalizedCommunity, + NormalizedEPerson, + NormalizedGroup, + NormalizedResourcePolicy, + NormalizedMetadataSchema, + NormalizedMetadataField, + NormalizedLicense, + NormalizedWorkflowItem, + NormalizedWorkspaceItem, + NormalizedSubmissionDefinitionsModel, + NormalizedSubmissionFormsModel, + NormalizedSubmissionSectionModel, + NormalizedAuthStatus, + NormalizedAuthorityValue, + BrowseEntry + ]; + @NgModule({ imports: [ ...IMPORTS @@ -186,8 +230,8 @@ const PROVIDERS = [ ...PROVIDERS ] }) -export class CoreModule { +export class CoreModule { static forRoot(): ModuleWithProviders { return { ngModule: CoreModule, @@ -197,10 +241,9 @@ export class CoreModule { }; } - constructor( @Optional() @SkipSelf() parentModule: CoreModule) { + constructor(@Optional() @SkipSelf() parentModule: CoreModule) { if (isNotEmpty(parentModule)) { throw new Error('CoreModule is already loaded. Import it in the AppModule only'); } } - } diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index fc4da69a5c..7176756ed9 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -31,12 +31,12 @@ import { configureRequest, getResponseFromEntry } from '../shared/operators'; import { ErrorResponse, RestResponse } from '../cache/response.models'; import { NotificationOptions } from '../../shared/notifications/models/notification-options.model'; import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; -import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory'; import { CacheableObject } from '../cache/object-cache.reducer'; import { RequestEntry } from './request.reducer'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { ChangeAnalyzer } from './change-analyzer'; import { RestRequestMethod } from './rest-request-method'; +import { getNormalizedConstructorByType } from '../shared/resource-type.decorator'; export abstract class DataService { protected abstract requestService: RequestService; @@ -243,7 +243,7 @@ export abstract class DataService { ); const normalizedObject: NormalizedObject = this.dataBuildService.normalize(dso); - const serializedDso = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(dso.type)).serialize(normalizedObject); + const serializedDso = new DSpaceRESTv2Serializer(getNormalizedConstructorByType(dso.type)).serialize(normalizedObject); const request$ = endpoint$.pipe( take(1), diff --git a/src/app/core/data/metadata-schema-data.service.ts b/src/app/core/data/metadata-schema-data.service.ts index 1d2bf3b221..33cf0f8c2e 100644 --- a/src/app/core/data/metadata-schema-data.service.ts +++ b/src/app/core/data/metadata-schema-data.service.ts @@ -9,11 +9,11 @@ import { RequestService } from './request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { FindAllOptions } from './request.models'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { MetadataSchema } from '../metadata/metadataschema.model'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { HttpClient } from '@angular/common/http'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; +import { MetadataSchema } from '../metadata/metadata-schema.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint diff --git a/src/app/core/data/metadataschema-parsing.service.ts b/src/app/core/data/metadataschema-parsing.service.ts index f76d6ed2e3..3e9fd257bb 100644 --- a/src/app/core/data/metadataschema-parsing.service.ts +++ b/src/app/core/data/metadataschema-parsing.service.ts @@ -1,10 +1,10 @@ -import { MetadataSchema } from '../metadata/metadataschema.model'; import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model'; import { RestRequest } from './request.models'; import { ResponseParsingService } from './parsing.service'; import { Injectable } from '@angular/core'; import { MetadataschemaSuccessResponse, RestResponse } from '../cache/response.models'; +import { MetadataSchema } from '../metadata/metadata-schema.model'; @Injectable() export class MetadataschemaParsingService implements ResponseParsingService { diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index 5e7bec698b..c85c9a9ff1 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -17,10 +17,10 @@ import { RequestError, RestRequest } from './request.models'; import { RequestEntry } from './request.reducer'; import { RequestService } from './request.service'; import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; -import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory'; import { catchError, filter, flatMap, map, take, tap } from 'rxjs/operators'; import { ErrorResponse, RestResponse } from '../cache/response.models'; import { StoreActionTypes } from '../../store.actions'; +import { getNormalizedConstructorByType } from '../shared/resource-type.decorator'; export const addToResponseCacheAndCompleteAction = (request: RestRequest, envConfig: GlobalConfig) => (source: Observable): Observable => @@ -45,7 +45,7 @@ export class RequestEffects { flatMap((request: RestRequest) => { let body; if (isNotEmpty(request.body)) { - const serializer = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(request.body.type)); + const serializer = new DSpaceRESTv2Serializer(getNormalizedConstructorByType(request.body.type)); body = serializer.serialize(request.body); } return this.restApi.request(request.method, request.href, body, request.options).pipe( diff --git a/src/app/core/metadata/metadata-field.model.ts b/src/app/core/metadata/metadata-field.model.ts index f773ff8b49..a79e63cd14 100644 --- a/src/app/core/metadata/metadata-field.model.ts +++ b/src/app/core/metadata/metadata-field.model.ts @@ -1,20 +1,52 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { isNotEmpty } from '../../shared/empty.util'; import { MetadataSchema } from './metadata-schema.model'; +import { ResourceType } from '../shared/resource-type'; +/** + * Class the represents a metadata field + */ export class MetadataField implements ListableObject { + + /** + * The identifier of this metadata field + */ id: number; + /** + * The self link of this metadata field + */ self: string; + /** + * The element of this metadata field + */ element: string; + /** + * The qualifier of this metadata field + */ qualifier: string; + /** + * The scope note of this metadata field + */ scopeNote: string; + /** + * The metadata schema object of this metadata field + */ schema: MetadataSchema; + /** + * The resource type of this metadata field + */ + type: ResourceType; + + /** + * Method to print this metadata field as a string + * @param separator The separator between the schema, element and qualifier in the string + */ toString(separator: string = '.'): string { let key = this.schema.prefix + separator + this.element; if (isNotEmpty(this.qualifier)) { diff --git a/src/app/core/metadata/metadata-schema.model.ts b/src/app/core/metadata/metadata-schema.model.ts index d141f56e2c..5d3ce4988b 100644 --- a/src/app/core/metadata/metadata-schema.model.ts +++ b/src/app/core/metadata/metadata-schema.model.ts @@ -1,11 +1,32 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; +import { ResourceType } from '../shared/resource-type'; +/** + * Class that represents a metadata schema + */ export class MetadataSchema implements ListableObject { + /** + * The unique identifier for this metadata schema + */ id: number; + /** + * The REST link to itself + */ self: string; + /** + * A unique prefix that defines this schema + */ prefix: string; + /** + * The namespace of this metadata schema + */ namespace: string; + + /** + * The resource type of this metadata schema + */ + type: ResourceType; } diff --git a/src/app/core/metadata/normalized-metadata-field.model.ts b/src/app/core/metadata/normalized-metadata-field.model.ts index 29a3376532..ba9e5b3b2a 100644 --- a/src/app/core/metadata/normalized-metadata-field.model.ts +++ b/src/app/core/metadata/normalized-metadata-field.model.ts @@ -6,25 +6,53 @@ import { MetadataField } from './metadata-field.model'; import { NormalizedObject } from '../cache/models/normalized-object.model'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; +/** + * Class the represents a normalized metadata field + */ @mapsTo(MetadataField) @resourceType(ResourceType.MetadataField) export class NormalizedMetadataField extends NormalizedObject implements ListableObject { + + /** + * The identifier of this normalized metadata field + */ @autoserialize id: number; + /** + * The self link of this normalized metadata field + */ @autoserialize self: string; + /** + * The element of this normalized metadata field + */ @autoserialize element: string; + /** + * The qualifier of this normalized metadata field + */ @autoserialize qualifier: string; + /** + * The scope note of this normalized metadata field + */ @autoserialize scopeNote: string; + /** + * The link to the metadata schema of this normalized metadata field + */ @deserialize @relationship(ResourceType.MetadataSchema) schema: string; + + /** + * The resource type of this normalized metadata field + */ + @autoserialize + type: ResourceType; } diff --git a/src/app/core/metadata/normalized-metadata-schema.model.ts b/src/app/core/metadata/normalized-metadata-schema.model.ts index aa6eb6a50a..b1ea78b225 100644 --- a/src/app/core/metadata/normalized-metadata-schema.model.ts +++ b/src/app/core/metadata/normalized-metadata-schema.model.ts @@ -35,4 +35,10 @@ export class NormalizedMetadataSchema extends NormalizedObject i */ @autoserialize namespace: string; + + /** + * The resource type of this metadata schema + */ + @autoserialize + type: ResourceType; } diff --git a/src/app/core/registry/registry-metadatafields-response.model.ts b/src/app/core/registry/registry-metadatafields-response.model.ts index 19ec537dfb..f4b6f46d17 100644 --- a/src/app/core/registry/registry-metadatafields-response.model.ts +++ b/src/app/core/registry/registry-metadatafields-response.model.ts @@ -1,14 +1,26 @@ import { PageInfo } from '../shared/page-info.model'; import { autoserialize, autoserializeAs } from 'cerialize'; -import { MetadataField } from '../metadata/metadatafield.model'; +import { MetadataField } from '../metadata/metadata-field.model'; +/** + * Class that represents a response with a registry's metadata fields + */ export class RegistryMetadatafieldsResponse { + /** + * List of metadata fields in the response + */ @autoserializeAs(MetadataField) metadatafields: MetadataField[]; + /** + * Page info of this response + */ @autoserialize page: PageInfo; + /** + * The REST link to this response + */ @autoserialize self: string; } diff --git a/src/app/core/registry/registry.service.spec.ts b/src/app/core/registry/registry.service.spec.ts index 8274ceef60..5517b41ed0 100644 --- a/src/app/core/registry/registry.service.spec.ts +++ b/src/app/core/registry/registry.service.spec.ts @@ -39,8 +39,9 @@ import { MetadataRegistrySelectFieldAction, MetadataRegistrySelectSchemaAction } from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions'; -import { MetadataSchema } from '../metadata/metadataschema.model'; -import { MetadataField } from '../metadata/metadatafield.model'; +import { ResourceType } from '../shared/resource-type'; +import { MetadataSchema } from '../metadata/metadata-schema.model'; +import { MetadataField } from '../metadata/metadata-field.model'; @Component({ template: '' }) class DummyComponent { @@ -59,13 +60,15 @@ describe('RegistryService', () => { id: 1, self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1', prefix: 'dc', - namespace: 'http://dublincore.org/documents/dcmi-terms/' - }, + namespace: 'http://dublincore.org/documents/dcmi-terms/', + type: ResourceType.MetadataSchema +}, { id: 2, self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2', prefix: 'mock', - namespace: 'http://dspace.org/mockschema' + namespace: 'http://dspace.org/mockschema', + type: ResourceType.MetadataSchema } ]; const mockFieldsList = [ @@ -75,7 +78,8 @@ describe('RegistryService', () => { element: 'contributor', qualifier: 'advisor', scopeNote: null, - schema: mockSchemasList[0] + schema: mockSchemasList[0], + type: ResourceType.MetadataField }, { id: 2, @@ -83,7 +87,8 @@ describe('RegistryService', () => { element: 'contributor', qualifier: 'author', scopeNote: null, - schema: mockSchemasList[0] + schema: mockSchemasList[0], + type: ResourceType.MetadataField }, { id: 3, @@ -91,7 +96,8 @@ describe('RegistryService', () => { element: 'contributor', qualifier: 'editor', scopeNote: 'test scope note', - schema: mockSchemasList[1] + schema: mockSchemasList[1], + type: ResourceType.MetadataField }, { id: 4, @@ -99,7 +105,8 @@ describe('RegistryService', () => { element: 'contributor', qualifier: 'illustrator', scopeNote: null, - schema: mockSchemasList[1] + schema: mockSchemasList[1], + type: ResourceType.MetadataField } ]; diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index 137b4c3a87..eb556f1db3 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -3,8 +3,6 @@ import { Injectable } from '@angular/core'; import { RemoteData } from '../data/remote-data'; import { PaginatedList } from '../data/paginated-list'; import { PageInfo } from '../shared/page-info.model'; -import { MetadataSchema } from '../metadata/metadataschema.model'; -import { MetadataField } from '../metadata/metadatafield.model'; import { BitstreamFormat } from './mock-bitstream-format.model'; import { CreateMetadataFieldRequest, @@ -56,7 +54,6 @@ import { } from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions'; import { distinctUntilChanged, flatMap, map, switchMap, take, tap } from 'rxjs/operators'; import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; -import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory'; import { ResourceType } from '../shared/resource-type'; import { NormalizedMetadataSchema } from '../metadata/normalized-metadata-schema.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -64,6 +61,9 @@ import { NotificationOptions } from '../../shared/notifications/models/notificat import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service'; import { HttpHeaders } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; +import { MetadataSchema } from '../metadata/metadata-schema.model'; +import { MetadataField } from '../metadata/metadata-field.model'; +import { getNormalizedConstructorByType } from '../shared/resource-type.decorator'; const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); @@ -71,6 +71,9 @@ const selectedMetadataSchemasSelector = createSelector(metadataRegistryStateSele const editMetadataFieldSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editField); const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedFields); +/** + * Service for registry related CRUD actions such as metadata schema, metadata field and bitstream format + */ @Injectable() export class RegistryService { @@ -87,6 +90,10 @@ export class RegistryService { } + /** + * Retrieves all metadata schemas + * @param pagination The pagination info used to retrieve the schemas + */ public getMetadataSchemas(pagination: PaginationComponentOptions): Observable>> { const requestObs = this.getMetadataSchemasRequestObs(pagination); @@ -117,6 +124,10 @@ export class RegistryService { return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs); } + /** + * Retrieves a metadata schema by its name + * @param schemaName The name of the schema to find + */ public getMetadataSchemaByName(schemaName: string): Observable> { // Temporary pagination to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema const pagination: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), { @@ -142,6 +153,11 @@ export class RegistryService { return this.rdb.toRemoteDataObservable(requestEntryObs, metadataschemaObs); } + /** + * retrieves all metadata fields that belong to a certain metadata schema + * @param schema The schema to filter by + * @param pagination The pagination info used to retrieve the fields + */ public getMetadataFieldsBySchema(schema: MetadataSchema, pagination: PaginationComponentOptions): Observable>> { const requestObs = this.getMetadataFieldsBySchemaRequestObs(pagination, schema); @@ -215,6 +231,10 @@ export class RegistryService { return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs); } + /** + * Retrieves all bitstream formats + * @param pagination The pagination info used to retrieve the bitstream formats + */ public getBitstreamFormats(pagination: PaginationComponentOptions): Observable>> { const requestObs = this.getBitstreamFormatsRequestObs(pagination); @@ -245,7 +265,7 @@ export class RegistryService { return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs); } - public getMetadataSchemasRequestObs(pagination: PaginationComponentOptions): Observable { + private getMetadataSchemasRequestObs(pagination: PaginationComponentOptions): Observable { return this.halService.getEndpoint(this.metadataSchemasPath).pipe( map((url: string) => { const args: string[] = []; @@ -327,58 +347,101 @@ export class RegistryService { ); } + /** + * Method to start editing a metadata schema, dispatches an edit schema action + * @param schema The schema that's being edited + */ public editMetadataSchema(schema: MetadataSchema) { this.store.dispatch(new MetadataRegistryEditSchemaAction(schema)); } + /** + * Method to cancel editing a metadata schema, dispatches a cancel schema action + */ public cancelEditMetadataSchema() { this.store.dispatch(new MetadataRegistryCancelSchemaAction()); } + /** + * Method to retrieve the metadata schema that are currently being edited + */ public getActiveMetadataSchema(): Observable { return this.store.pipe(select(editMetadataSchemaSelector)); } + /** + * Method to select a metadata schema, dispatches a select schema action + * @param schema The schema that's being selected + */ public selectMetadataSchema(schema: MetadataSchema) { this.store.dispatch(new MetadataRegistrySelectSchemaAction(schema)) } + /** + * Method to deselect a metadata schema, dispatches a deselect schema action + * @param schema The schema that's it being deselected + */ public deselectMetadataSchema(schema: MetadataSchema) { this.store.dispatch(new MetadataRegistryDeselectSchemaAction(schema)) } + /** + * Method to deselect all currently selected metadata schema, dispatches a deselect all schema action + */ public deselectAllMetadataSchema() { this.store.dispatch(new MetadataRegistryDeselectAllSchemaAction()) } + /** + * Method to retrieve the metadata schemas that are currently selected + */ public getSelectedMetadataSchemas(): Observable { return this.store.pipe(select(selectedMetadataSchemasSelector)); } - + /** + * Method to start editing a metadata field, dispatches an edit field action + * @param field The field that's being edited + */ public editMetadataField(field: MetadataField) { this.store.dispatch(new MetadataRegistryEditFieldAction(field)); } + /** + * Method to cancel editing a metadata field, dispatches a cancel field action + */ public cancelEditMetadataField() { this.store.dispatch(new MetadataRegistryCancelFieldAction()); } - + /** + * Method to retrieve the metadata field that are currently being edited + */ public getActiveMetadataField(): Observable { return this.store.pipe(select(editMetadataFieldSelector)); } - + /** + * Method to select a metadata field, dispatches a select field action + * @param field The field that's being selected + */ public selectMetadataField(field: MetadataField) { this.store.dispatch(new MetadataRegistrySelectFieldAction(field)) } - + /** + * Method to deselect a metadata field, dispatches a deselect field action + * @param field The field that's it being deselected + */ public deselectMetadataField(field: MetadataField) { this.store.dispatch(new MetadataRegistryDeselectFieldAction(field)) } - + /** + * Method to deselect all currently selected metadata fields, dispatches a deselect all field action + */ public deselectAllMetadataField() { this.store.dispatch(new MetadataRegistryDeselectAllFieldAction()) } + /** + * Method to retrieve the metadata fields that are currently selected + */ public getSelectedMetadataFields(): Observable { return this.store.pipe(select(selectedMetadataFieldsSelector)); } @@ -400,7 +463,7 @@ export class RegistryService { distinctUntilChanged() ); - const serializedSchema = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(ResourceType.MetadataSchema)).serialize(schema as NormalizedMetadataSchema); + const serializedSchema = new DSpaceRESTv2Serializer(getNormalizedConstructorByType(ResourceType.MetadataSchema)).serialize(schema as NormalizedMetadataSchema); const request$ = endpoint$.pipe( take(1), @@ -444,10 +507,17 @@ export class RegistryService { ); } + /** + * Method to delete a metadata schema + * @param id The id of the metadata schema to delete + */ public deleteMetadataSchema(id: number): Observable { return this.delete(this.metadataSchemasPath, id); } + /** + * Method that clears a cached metadata schema request and returns its REST url + */ public clearMetadataSchemaRequests(): Observable { return this.halService.getEndpoint(this.metadataSchemasPath).pipe( tap((href: string) => this.requestService.removeByHrefSubstring(href)) @@ -514,10 +584,16 @@ export class RegistryService { ); } + /** + * Method to delete a metadata field + * @param id The id of the metadata field to delete + */ public deleteMetadataField(id: number): Observable { return this.delete(this.metadataFieldsPath, id); } - + /** + * Method that clears a cached metadata field request and returns its REST url + */ public clearMetadataFieldRequests(): Observable { return this.halService.getEndpoint(this.metadataFieldsPath).pipe( tap((href: string) => this.requestService.removeByHrefSubstring(href)) diff --git a/src/app/core/shared/bitstream-format.model.ts b/src/app/core/shared/bitstream-format.model.ts index c46df1724d..a532ea9e75 100644 --- a/src/app/core/shared/bitstream-format.model.ts +++ b/src/app/core/shared/bitstream-format.model.ts @@ -5,7 +5,7 @@ import { ResourceType } from './resource-type'; /** * Model class for a Bitstream Format */ -export class BitstreamFormat implements CacheableObject, TypedObject { +export class BitstreamFormat implements CacheableObject { /** * Short description of this Bitstream Format diff --git a/src/app/core/shared/browse-entry.model.ts b/src/app/core/shared/browse-entry.model.ts index 6f018cedde..3dbba0cdb8 100644 --- a/src/app/core/shared/browse-entry.model.ts +++ b/src/app/core/shared/browse-entry.model.ts @@ -2,24 +2,41 @@ import { autoserialize, autoserializeAs } from 'cerialize'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { ResourceType } from './resource-type'; import { resourceType } from './resource-type.decorator'; -import { CacheableObject, TypedObject } from '../cache/object-cache.reducer'; +import { TypedObject } from '../cache/object-cache.reducer'; +/** + * Class object representing a browse entry + * This class is not normalized because browse entries do not have self links + */ @resourceType(ResourceType.BrowseEntry) export class BrowseEntry implements ListableObject, TypedObject { - + /** + * The resource type of this browse entry + */ @autoserialize type: ResourceType; + /** + * The authority string of this browse entry + */ @autoserialize authority: string; + /** + * The value of this browse entry + */ @autoserialize value: string; + /** + * The language of the value of this browse entry + */ @autoserializeAs('valueLang') language: string; + /** + * The count of this browse entry + */ @autoserialize count: number; - } diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 422e215c90..4aa0ba9695 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -11,7 +11,7 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-o /** * An abstract model class for a DSpaceObject. */ -export class DSpaceObject implements CacheableObject, ListableObject, TypedObject { +export class DSpaceObject implements CacheableObject, ListableObject { private _name: string; diff --git a/src/app/core/shared/resource-policy.model.ts b/src/app/core/shared/resource-policy.model.ts index 21dcd44b01..950d7b92d7 100644 --- a/src/app/core/shared/resource-policy.model.ts +++ b/src/app/core/shared/resource-policy.model.ts @@ -1,12 +1,11 @@ -import { CacheableObject, TypedObject } from '../cache/object-cache.reducer'; +import { CacheableObject } from '../cache/object-cache.reducer'; import { ResourceType } from './resource-type'; -import { Group } from '../eperson/models/group.model'; import { ActionType } from '../cache/models/action-type.model'; /** * Model class for a Resource Policy */ -export class ResourcePolicy implements CacheableObject, TypedObject { +export class ResourcePolicy implements CacheableObject { /** * The action that is allowed by this Resource Policy */ diff --git a/src/app/core/shared/resource-type.decorator.ts b/src/app/core/shared/resource-type.decorator.ts index 28b2c7cefe..76c7f34057 100644 --- a/src/app/core/shared/resource-type.decorator.ts +++ b/src/app/core/shared/resource-type.decorator.ts @@ -1,19 +1,27 @@ -import { CacheableObject, TypedObject } from '../cache/object-cache.reducer'; +import { TypedObject } from '../cache/object-cache.reducer'; import { GenericConstructor } from './generic-constructor'; import { ResourceType } from './resource-type'; const resourceTypeForObjectMap = new Map(); -export function resourceType(...resourceType: ResourceType[]) { +/** + * Decorator function to map resource types to their matching normalized model class constructor + * @param type The resource type used as a key in the map + */ +export function resourceType(...type: ResourceType[]) { return function decorator(objectConstructor: GenericConstructor) { if (!objectConstructor) { return; } - resourceType.forEach((rt: string) => resourceTypeForObjectMap.set(rt, objectConstructor) + type.forEach((rt: string) => resourceTypeForObjectMap.set(rt, objectConstructor) ) }; } -export function getNormalizedConstructorByType(resourceType: ResourceType) { - return resourceTypeForObjectMap.get(resourceType); +/** + * Method to retrieve the normalized model class constructor based on a resource type + * @param type The resource type to look for + */ +export function getNormalizedConstructorByType(type: ResourceType) { + return resourceTypeForObjectMap.get(type); } diff --git a/src/app/core/submission/submission-response-parsing.service.ts b/src/app/core/submission/submission-response-parsing.service.ts index 494e4db46b..deb8a814ce 100644 --- a/src/app/core/submission/submission-response-parsing.service.ts +++ b/src/app/core/submission/submission-response-parsing.service.ts @@ -10,7 +10,6 @@ import { BaseResponseParsingService } from '../data/base-response-parsing.servic import { GLOBAL_CONFIG } from '../../../config'; import { GlobalConfig } from '../../../config/global-config.interface'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { SubmissionResourceType } from './submission-resource-type'; import { NormalizedWorkspaceItem } from './models/normalized-workspaceitem.model'; import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model'; import { FormFieldMetadataValueObject } from '../../shared/form/builder/models/form-field-metadata-value.model'; diff --git a/src/app/core/submission/workspaceitem-data.service.ts b/src/app/core/submission/workspaceitem-data.service.ts index 3bb3eb1ee8..de671d57c7 100644 --- a/src/app/core/submission/workspaceitem-data.service.ts +++ b/src/app/core/submission/workspaceitem-data.service.ts @@ -6,24 +6,24 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv import { CoreState } from '../core.reducers'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; -import { Workspaceitem } from './models/workspaceitem.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { FindAllOptions } from '../data/request.models'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; +import { WorkspaceItem } from './models/workspaceitem.model'; /** * A service that provides methods to make REST requests with workspaceitems endpoint. */ @Injectable() -export class WorkspaceitemDataService extends DataService { +export class WorkspaceitemDataService extends DataService { protected linkPath = 'workspaceitems'; protected forceBypassCache = true; constructor( - protected comparator: DSOChangeAnalyzer, + protected comparator: DSOChangeAnalyzer, protected dataBuildService: NormalizedObjectBuildService, protected halService: HALEndpointService, protected http: HttpClient, diff --git a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts index be3e6b5c8c..dfa1c58f9b 100644 --- a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts +++ b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts @@ -6,13 +6,13 @@ import { first } from 'rxjs/operators'; import { SectionsService } from '../../sections/sections.service'; import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util'; -import { Workspaceitem } from '../../../core/submission/models/workspaceitem.model'; import { normalizeSectionData } from '../../../core/submission/submission-response-parsing.service'; import { SubmissionService } from '../../submission.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { UploaderOptions } from '../../../shared/uploader/uploader-options.model'; import parseSectionErrors from '../../utils/parseSectionErrors'; import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; +import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; /** * This component represents the drop zone that provides to add files to the submission. @@ -119,7 +119,7 @@ export class SubmissionUploadFilesComponent implements OnChanges { * @param workspaceitem * The submission object retrieved from REST */ - public onCompleteItem(workspaceitem: Workspaceitem) { + public onCompleteItem(workspaceitem: WorkspaceItem) { // Checks if upload section is enabled so do upload this.subs.push( this.uploadEnabled diff --git a/src/modules/app/browser-app.module.ts b/src/modules/app/browser-app.module.ts index b20894880b..ee826c680d 100644 --- a/src/modules/app/browser-app.module.ts +++ b/src/modules/app/browser-app.module.ts @@ -20,7 +20,6 @@ import { CookieService } from '../../app/shared/services/cookie.service'; import { AuthService } from '../../app/core/auth/auth.service'; import { Angulartics2Module } from 'angulartics2'; import { Angulartics2GoogleAnalytics } from 'angulartics2/ga'; -import { ServerSubmissionService } from '../../app/submission/server-submission.service'; import { SubmissionService } from '../../app/submission/submission.service'; export const REQ_KEY = makeStateKey('req');