From 066bba28afe85b47fc32114a6dadcf01e01f10c1 Mon Sep 17 00:00:00 2001 From: William Welling Date: Thu, 13 Jul 2017 11:19:02 -0500 Subject: [PATCH] fixed lint errors --- src/app/app.component.spec.ts | 20 +-- src/app/app.component.ts | 16 +-- src/app/app.effects.ts | 11 +- src/app/app.module.ts | 6 +- src/app/app.reducer.ts | 16 ++- .../collection-page.component.ts | 39 +++--- .../collection-page/collection-page.module.ts | 2 +- .../community-page.component.ts | 25 ++-- .../community-page/community-page.module.ts | 4 +- ...nity-page-sub-collection-list.component.ts | 14 +- .../core/cache/builders/build-decorators.ts | 27 ++-- .../builders/remote-data-build.service.ts | 122 ++++++++-------- src/app/core/cache/cache.reducers.ts | 7 +- .../normalized-bitstream-format.model.ts | 8 +- .../models/normalized-bitstream.model.ts | 14 +- .../cache/models/normalized-bundle.model.ts | 16 ++- .../models/normalized-collection.model.ts | 15 +- .../models/normalized-community.model.ts | 15 +- .../models/normalized-dspace-object.model.ts | 14 +- .../cache/models/normalized-item.model.ts | 16 ++- .../cache/models/normalized-object-factory.ts | 20 +-- .../cache/models/normalized-object.model.ts | 4 +- src/app/core/cache/models/self-link.model.ts | 3 +- .../core/cache/models/sort-options.model.ts | 2 +- src/app/core/cache/object-cache.actions.ts | 9 +- .../core/cache/object-cache.reducer.spec.ts | 51 +++---- src/app/core/cache/object-cache.reducer.ts | 21 ++- .../core/cache/object-cache.service.spec.ts | 63 +++++---- src/app/core/cache/object-cache.service.ts | 29 ++-- src/app/core/cache/response-cache.actions.ts | 9 +- src/app/core/cache/response-cache.models.ts | 8 +- .../core/cache/response-cache.reducer.spec.ts | 110 +++++++-------- src/app/core/cache/response-cache.reducer.ts | 23 ++- .../core/cache/response-cache.service.spec.ts | 79 +++++------ src/app/core/cache/response-cache.service.ts | 28 ++-- src/app/core/core.effects.ts | 11 +- src/app/core/core.module.ts | 38 ++--- src/app/core/core.reducers.ts | 9 +- src/app/core/data/collection-data.service.ts | 23 +-- src/app/core/data/community-data.service.ts | 24 ++-- src/app/core/data/data.reducers.ts | 5 +- src/app/core/data/data.service.ts | 39 +++--- src/app/core/data/item-data.service.ts | 24 ++-- src/app/core/data/object-cache.effects.ts | 17 ++- src/app/core/data/remote-data.ts | 48 +++---- src/app/core/data/request-cache.effects.ts | 18 +-- src/app/core/data/request.actions.ts | 10 +- src/app/core/data/request.effects.ts | 132 +++++++++--------- src/app/core/data/request.models.ts | 8 +- src/app/core/data/request.reducer.ts | 13 +- src/app/core/data/request.service.ts | 40 +++--- .../dspace-rest-v2.serializer.spec.ts | 92 ++++++------ .../dspace-rest-v2.serializer.ts | 36 ++--- .../dspace-rest-v2/dspace-rest-v2.service.ts | 10 +- .../dspace-rest-v2.validator.ts | 10 +- src/app/core/footer/footer.component.spec.ts | 14 +- src/app/core/footer/footer.component.ts | 10 +- src/app/core/index/href-index.actions.ts | 12 +- src/app/core/index/href-index.effects.ts | 20 +-- src/app/core/index/href-index.reducer.ts | 15 +- src/app/core/index/index.reducers.ts | 5 +- src/app/core/serializer.ts | 4 +- src/app/core/shared/bitstream.model.ts | 6 +- src/app/core/shared/bundle.model.ts | 8 +- src/app/core/shared/collection.model.ts | 18 +-- src/app/core/shared/community.model.ts | 16 +-- src/app/core/shared/dspace-object.model.ts | 33 ++--- src/app/core/shared/generic-constructor.ts | 4 +- src/app/core/shared/item.model.spec.ts | 71 +++++----- src/app/core/shared/item.model.ts | 49 ++++--- src/app/core/shared/metadatum.model.ts | 4 +- src/app/core/shared/page-info.model.ts | 3 +- src/app/core/shared/resource-type.ts | 12 +- .../core/url-combiner/rest-url-combiner.ts | 4 +- src/app/core/url-combiner/ui-url-combiner.ts | 6 +- .../core/url-combiner/url-combiner.spec.ts | 14 +- src/app/core/url-combiner/url-combiner.ts | 9 +- src/app/header/header.actions.ts | 27 ++-- src/app/header/header.component.spec.ts | 30 ++-- src/app/header/header.component.ts | 13 +- src/app/header/header.effects.spec.ts | 15 +- src/app/header/header.effects.ts | 18 +-- src/app/header/header.reducer.spec.ts | 28 ++-- src/app/header/header.reducer.ts | 2 +- src/app/home/home-news/home-news.component.ts | 13 +- src/app/home/home.component.ts | 13 +- src/app/home/home.module.ts | 12 +- .../top-level-community-list.component.ts | 17 +-- .../collections/collections.component.ts | 28 ++-- .../metadata-field-wrapper.component.ts | 10 -- .../metadata-uri-values.component.ts | 4 +- .../metadata-values.component.ts | 10 -- .../full-file-section.component.ts | 24 ++-- .../full/full-item-page.component.ts | 23 ++- src/app/item-page/item-page.module.ts | 9 +- .../file-section/file-section.component.ts | 19 +-- .../item-page-abstract-field.component.ts | 13 +- .../item-page-author-field.component.ts | 17 +-- .../date/item-page-date-field.component.ts | 13 +- .../item-page-specific-field.component.ts | 16 +-- .../title/item-page-title-field.component.ts | 11 +- .../uri/item-page-uri-field.component.ts | 13 +- .../item-page/simple/item-page.component.ts | 26 ++-- .../collection-list-element.component.ts | 11 +- .../community-list-element.component.ts | 11 +- .../item-list-element.component.ts | 11 +- .../object-list-element.component.ts | 12 +- .../pagenotfound/pagenotfound.component.ts | 8 -- src/app/server-app.module.ts | 2 +- src/app/shared/api.service.ts | 11 +- .../comcol-page-content.component.ts | 12 -- .../comcol-page-header.component.ts | 3 +- .../comcol-page-logo.component.ts | 7 +- src/app/shared/empty.util.spec.ts | 126 ++++++++--------- src/app/shared/empty.util.ts | 87 ++++++------ src/app/shared/host-window.actions.ts | 5 +- src/app/shared/host-window.reducer.spec.ts | 16 +-- src/app/shared/host-window.reducer.ts | 2 +- src/app/shared/host-window.service.spec.ts | 82 +++++------ src/app/shared/host-window.service.ts | 25 ++-- src/app/shared/ngrx/type.ts | 8 +- .../object-list/object-list.component.ts | 25 ++-- .../shared/pagination/pagination.component.ts | 4 +- 123 files changed, 1295 insertions(+), 1407 deletions(-) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 86065b4070..96037effc1 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -9,21 +9,21 @@ import { import { CUSTOM_ELEMENTS_SCHEMA, DebugElement -} from "@angular/core"; +} from '@angular/core'; import { CommonModule } from '@angular/common'; import { By } from '@angular/platform-browser'; -import { TranslateModule, TranslateLoader } from "@ngx-translate/core"; -import { Store, StoreModule } from "@ngrx/store"; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { Store, StoreModule } from '@ngrx/store'; // Load the implementations that should be tested import { AppComponent } from './app.component'; -import { HostWindowState } from "./shared/host-window.reducer"; -import { HostWindowResizeAction } from "./shared/host-window.actions"; -import { MockTranslateLoader } from "./shared/testing/mock-translate-loader"; +import { HostWindowState } from './shared/host-window.reducer'; +import { HostWindowResizeAction } from './shared/host-window.actions'; +import { MockTranslateLoader } from './shared/testing/mock-translate-loader'; import { BrowserCookiesModule } from '../modules/cookies/browser-cookies.module'; import { BrowserDataLoaderModule } from '../modules/data-loader/browser-data-loader.module'; @@ -31,7 +31,7 @@ import { BrowserTransferStateModule } from '../modules/transfer-state/browser-tr import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module'; import { GLOBAL_CONFIG, ENV_CONFIG } from '../config'; -import { NativeWindowRef, NativeWindowService } from "./shared/window.service"; +import { NativeWindowRef, NativeWindowService } from './shared/window.service'; let comp: AppComponent; let fixture: ComponentFixture; @@ -73,7 +73,7 @@ describe('App component', () => { comp = fixture.componentInstance; // component test instance - // query for the
by CSS element selector + // query for the
by CSS element selector de = fixture.debugElement.query(By.css('div.outer-wrapper')); el = de.nativeElement; }); @@ -83,7 +83,7 @@ describe('App component', () => { expect(app).toBeTruthy(); })); - describe("when the window is resized", () => { + describe('when the window is resized', () => { let width: number; let height: number; let store: Store; @@ -97,7 +97,7 @@ describe('App component', () => { height = window.innerHeight; }); - it("should dispatch a HostWindowResizeAction with the width and height of the window as its payload", () => { + it('should dispatch a HostWindowResizeAction with the width and height of the window as its payload', () => { expect(store.dispatch).toHaveBeenCalledWith(new HostWindowResizeAction(width, height)); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index e1fdbf6edb..8309a518de 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,19 +5,19 @@ import { ViewEncapsulation, OnInit, HostListener -} from "@angular/core"; +} from '@angular/core'; -import { TranslateService } from "@ngx-translate/core"; +import { TranslateService } from '@ngx-translate/core'; -import { Store } from "@ngrx/store"; +import { Store } from '@ngrx/store'; import { TransferState } from '../modules/transfer-state/transfer-state'; -import { HostWindowState } from "./shared/host-window.reducer"; +import { HostWindowState } from './shared/host-window.reducer'; -import { HostWindowResizeAction } from "./shared/host-window.actions"; +import { HostWindowResizeAction } from './shared/host-window.actions'; -import { NativeWindowRef, NativeWindowService } from "./shared/window.service"; +import { NativeWindowRef, NativeWindowService } from './shared/window.service'; import { GLOBAL_CONFIG, GlobalConfig } from '../config'; @@ -54,8 +54,8 @@ export class AppComponent implements OnInit { } ngOnInit() { - const env: string = this.config.production ? "Production" : "Development"; - const color: string = this.config.production ? "red" : "green"; + const env: string = this.config.production ? 'Production' : 'Development'; + const color: string = this.config.production ? 'red' : 'green'; console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`); } diff --git a/src/app/app.effects.ts b/src/app/app.effects.ts index b8199a1a2f..1bc2129ce1 100644 --- a/src/app/app.effects.ts +++ b/src/app/app.effects.ts @@ -1,10 +1,11 @@ -import { EffectsModule } from "@ngrx/effects"; -import { HeaderEffects } from "./header/header.effects"; -import { StoreEffects } from "./store.effects"; -import { coreEffects } from "./core/core.effects"; +import { EffectsModule } from '@ngrx/effects'; + +import { HeaderEffects } from './header/header.effects'; +import { StoreEffects } from './store.effects'; +import { coreEffects } from './core/core.effects'; export const effects = [ - ...coreEffects, //TODO should probably be imported in coreModule + ...coreEffects, // TODO: should probably be imported in coreModule EffectsModule.run(StoreEffects), EffectsModule.run(HeaderEffects) ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 759a2fe7ac..241f9da835 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,9 +2,9 @@ import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; import { FormsModule } from '@angular/forms'; -import { StoreModule, Store } from "@ngrx/store"; -import { RouterStoreModule } from "@ngrx/router-store"; -import { StoreDevtoolsModule } from "@ngrx/store-devtools"; +import { StoreModule, Store } from '@ngrx/store'; +import { RouterStoreModule } from '@ngrx/router-store'; +import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { rootReducer, AppState } from './app.reducer'; import { effects } from './app.effects'; diff --git a/src/app/app.reducer.ts b/src/app/app.reducer.ts index 7e789f5373..463fa0c05d 100644 --- a/src/app/app.reducer.ts +++ b/src/app/app.reducer.ts @@ -1,11 +1,13 @@ -import { combineReducers, ActionReducer } from "@ngrx/store"; -import { routerReducer, RouterState } from "@ngrx/router-store"; -import { headerReducer, HeaderState } from './header/header.reducer'; -import { hostWindowReducer, HostWindowState } from "./shared/host-window.reducer"; -import { CoreState, coreReducer } from "./core/core.reducers"; +import { combineReducers, ActionReducer } from '@ngrx/store'; +import { routerReducer, RouterState } from '@ngrx/router-store'; import { storeFreeze } from 'ngrx-store-freeze'; -import { compose } from "@ngrx/core"; -import { StoreActionTypes } from "./store.actions"; +import { compose } from '@ngrx/core'; + +import { headerReducer, HeaderState } from './header/header.reducer'; +import { hostWindowReducer, HostWindowState } from './shared/host-window.reducer'; +import { CoreState, coreReducer } from './core/core.reducers'; + +import { StoreActionTypes } from './store.actions'; import { ENV_CONFIG } from '../config'; diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts index 2e65e7c9f9..1f30912d47 100644 --- a/src/app/collection-page/collection-page.component.ts +++ b/src/app/collection-page/collection-page.component.ts @@ -4,17 +4,18 @@ import { } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; -import { Collection } from "../core/shared/collection.model"; -import { Bitstream } from "../core/shared/bitstream.model"; -import { RemoteData } from "../core/data/remote-data"; -import { CollectionDataService } from "../core/data/collection-data.service"; -import { Subscription } from "rxjs/Subscription"; -import { ItemDataService } from "../core/data/item-data.service"; -import { Item } from "../core/shared/item.model"; -import { SortOptions, SortDirection } from "../core/cache/models/sort-options.model"; -import { PaginationComponentOptions } from "../shared/pagination/pagination-component-options.model"; -import { Observable } from "rxjs/Observable"; -import { hasValue } from "../shared/empty.util"; +import { Observable } from 'rxjs/Observable'; +import { Subscription } from 'rxjs/Subscription'; + +import { Collection } from '../core/shared/collection.model'; +import { Bitstream } from '../core/shared/bitstream.model'; +import { RemoteData } from '../core/data/remote-data'; +import { CollectionDataService } from '../core/data/collection-data.service'; +import { ItemDataService } from '../core/data/item-data.service'; +import { Item } from '../core/shared/item.model'; +import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model'; +import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; +import { hasValue } from '../shared/empty.util'; @Component({ selector: 'ds-collection-page', @@ -37,19 +38,18 @@ export class CollectionPageComponent implements OnInit, OnDestroy { private ref: ChangeDetectorRef, private route: ActivatedRoute ) { - this.universalInit(); + } ngOnInit(): void { - this.subs.push(this.route.params.map((params: Params) => params['id']) + this.subs.push(this.route.params.map((params: Params) => params.id) .subscribe((id: string) => { this.collectionId = id; this.collectionData = this.collectionDataService.findById(this.collectionId); - this.subs.push(this.collectionData.payload - .subscribe(collection => this.logoData = collection.logo)); + this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo)); this.config = new PaginationComponentOptions(); - this.config.id = "collection-browse"; + this.config.id = 'collection-browse'; this.config.pageSizeOptions = [4]; this.config.pageSize = 4; this.sortConfig = new SortOptions(); @@ -60,12 +60,7 @@ export class CollectionPageComponent implements OnInit, OnDestroy { } ngOnDestroy(): void { - this.subs - .filter(sub => hasValue(sub)) - .forEach(sub => sub.unsubscribe()); - } - - universalInit() { + this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe()); } onPageChange(currentPage: number): void { diff --git a/src/app/collection-page/collection-page.module.ts b/src/app/collection-page/collection-page.module.ts index 95e4a52540..5ec618b9e5 100644 --- a/src/app/collection-page/collection-page.module.ts +++ b/src/app/collection-page/collection-page.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { TranslateModule } from "@ngx-translate/core"; +import { TranslateModule } from '@ngx-translate/core'; import { SharedModule } from '../shared/shared.module'; diff --git a/src/app/community-page/community-page.component.ts b/src/app/community-page/community-page.component.ts index 1c6702b6f4..2bd19b0f06 100644 --- a/src/app/community-page/community-page.component.ts +++ b/src/app/community-page/community-page.component.ts @@ -1,12 +1,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; -import { Community } from "../core/shared/community.model"; -import { Bitstream } from "../core/shared/bitstream.model"; -import { RemoteData } from "../core/data/remote-data"; -import { CommunityDataService } from "../core/data/community-data.service"; -import { Subscription } from "rxjs/Subscription"; -import { hasValue } from "../shared/empty.util"; +import { Subscription } from 'rxjs/Subscription'; + +import { Community } from '../core/shared/community.model'; +import { Bitstream } from '../core/shared/bitstream.model'; +import { RemoteData } from '../core/data/remote-data'; +import { CommunityDataService } from '../core/data/community-data.service'; +import { hasValue } from '../shared/empty.util'; @Component({ selector: 'ds-community-page', @@ -22,23 +23,21 @@ export class CommunityPageComponent implements OnInit, OnDestroy { private communityDataService: CommunityDataService, private route: ActivatedRoute ) { - this.universalInit(); + } ngOnInit(): void { this.route.params.subscribe((params: Params) => { - this.communityData = this.communityDataService.findById(params['id']); + this.communityData = this.communityDataService.findById(params.id); this.subs.push(this.communityData.payload - .subscribe(community => this.logoData = community.logo)); + .subscribe((community) => this.logoData = community.logo)); }); } ngOnDestroy(): void { this.subs - .filter(sub => hasValue(sub)) - .forEach(sub => sub.unsubscribe()); + .filter((sub) => hasValue(sub)) + .forEach((sub) => sub.unsubscribe()); } - universalInit() { - } } diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts index 1410e786b7..647aa6f681 100644 --- a/src/app/community-page/community-page.module.ts +++ b/src/app/community-page/community-page.module.ts @@ -1,8 +1,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { RouterModule } from "@angular/router"; +import { RouterModule } from '@angular/router'; -import { TranslateModule } from "@ngx-translate/core"; +import { TranslateModule } from '@ngx-translate/core'; import { SharedModule } from '../shared/shared.module'; import { CommunityPageComponent } from './community-page.component'; diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts index b541b86bc9..caa764c39f 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; -import { CollectionDataService } from "../../core/data/collection-data.service"; -import { RemoteData } from "../../core/data/remote-data"; -import { Collection } from "../../core/shared/collection.model"; +import { CollectionDataService } from '../../core/data/collection-data.service'; +import { RemoteData } from '../../core/data/remote-data'; +import { Collection } from '../../core/shared/collection.model'; @Component({ selector: 'ds-community-page-sub-collection-list', @@ -12,13 +12,7 @@ import { Collection } from "../../core/shared/collection.model"; export class CommunityPageSubCollectionListComponent implements OnInit { subCollections: RemoteData; - constructor( - private cds: CollectionDataService - ) { - this.universalInit(); - } - - universalInit() { + constructor(private cds: CollectionDataService) { } diff --git a/src/app/core/cache/builders/build-decorators.ts b/src/app/core/cache/builders/build-decorators.ts index 55dadf60a1..937fb37cd3 100644 --- a/src/app/core/cache/builders/build-decorators.ts +++ b/src/app/core/cache/builders/build-decorators.ts @@ -1,28 +1,29 @@ -import "reflect-metadata"; -import { GenericConstructor } from "../../shared/generic-constructor"; -import { CacheableObject } from "../object-cache.reducer"; -import { ResourceType } from "../../shared/resource-type"; +import 'reflect-metadata'; -const mapsToMetadataKey = Symbol("mapsTo"); -const relationshipKey = Symbol("relationship"); +import { GenericConstructor } from '../../shared/generic-constructor'; +import { CacheableObject } from '../object-cache.reducer'; +import { ResourceType } from '../../shared/resource-type'; + +const mapsToMetadataKey = Symbol('mapsTo'); +const relationshipKey = Symbol('relationship'); const relationshipMap = new Map(); export function mapsTo(value: GenericConstructor) { return Reflect.metadata(mapsToMetadataKey, value); -}; +} export function getMapsTo(target: any) { return Reflect.getOwnMetadata(mapsToMetadataKey, target); -}; +} export function relationship(value: ResourceType, isList: boolean = false): any { - return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { + return function r(target: any, propertyKey: string, descriptor: PropertyDescriptor) { if (!target || !propertyKey) { return; } - let metaDataList: Array = relationshipMap.get(target.constructor) || []; + const metaDataList: string[] = relationshipMap.get(target.constructor) || []; if (metaDataList.indexOf(propertyKey) === -1) { metaDataList.push(propertyKey); } @@ -30,12 +31,12 @@ export function relationship(value: ResourceType, isList: boolean = false): any return Reflect.metadata(relationshipKey, { resourceType: value, isList }).apply(this, arguments); }; -}; +} export function getRelationMetadata(target: any, propertyKey: string) { return Reflect.getMetadata(relationshipKey, target, propertyKey); -}; +} export function getRelationships(target: any) { return relationshipMap.get(target); -}; +} 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 0f5d59f2e2..be7f4c8085 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -1,20 +1,21 @@ -import { Injectable } from "@angular/core"; -import { CacheableObject } from "../object-cache.reducer"; -import { ObjectCacheService } from "../object-cache.service"; -import { RequestService } from "../../data/request.service"; -import { ResponseCacheService } from "../response-cache.service"; -import { Store } from "@ngrx/store"; -import { CoreState } from "../../core.reducers"; -import { RequestEntry } from "../../data/request.reducer"; -import { hasValue, isNotEmpty } from "../../../shared/empty.util"; -import { ResponseCacheEntry } from "../response-cache.reducer"; -import { ErrorResponse, SuccessResponse } from "../response-cache.models"; -import { Observable } from "rxjs/Observable"; -import { RemoteData } from "../../data/remote-data"; -import { GenericConstructor } from "../../shared/generic-constructor"; -import { getMapsTo, getRelationMetadata, getRelationships } from "./build-decorators"; -import { NormalizedObjectFactory } from "../models/normalized-object-factory"; -import { Request } from "../../data/request.models"; +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; + +import { CacheableObject } from '../object-cache.reducer'; +import { ObjectCacheService } from '../object-cache.service'; +import { RequestService } from '../../data/request.service'; +import { ResponseCacheService } from '../response-cache.service'; +import { CoreState } from '../../core.reducers'; +import { RequestEntry } from '../../data/request.reducer'; +import { hasValue, isNotEmpty } from '../../../shared/empty.util'; +import { ResponseCacheEntry } from '../response-cache.reducer'; +import { ErrorResponse, SuccessResponse } from '../response-cache.models'; +import { RemoteData } from '../../data/remote-data'; +import { GenericConstructor } from '../../shared/generic-constructor'; +import { getMapsTo, getRelationMetadata, getRelationships } from './build-decorators'; +import { NormalizedObjectFactory } from '../models/normalized-object-factory'; +import { Request } from '../../data/request.models'; @Injectable() export class RemoteDataBuildService { @@ -33,14 +34,14 @@ export class RemoteDataBuildService { const requestHrefObs = this.objectCache.getRequestHrefBySelfLink(href); const requestObs = Observable.race( - this.store.select('core', 'data', 'request', href).filter(entry => hasValue(entry)), - requestHrefObs.flatMap(requestHref => - this.store.select('core', 'data', 'request', requestHref)).filter(entry => hasValue(entry)) + this.store.select('core', 'data', 'request', href).filter((entry) => hasValue(entry)), + requestHrefObs.flatMap((requestHref) => + this.store.select('core', 'data', 'request', requestHref)).filter((entry) => hasValue(entry)) ); const responseCacheObs = Observable.race( - this.responseCache.get(href).filter(entry => hasValue(entry)), - requestHrefObs.flatMap(requestHref => this.responseCache.get(requestHref)).filter(entry => hasValue(entry)) + this.responseCache.get(href).filter((entry) => hasValue(entry)), + requestHrefObs.flatMap((requestHref) => this.responseCache.get(requestHref)).filter((entry) => hasValue(entry)) ); const requestPending = requestObs.map((entry: RequestEntry) => entry.requestPending).distinctUntilChanged(); @@ -52,30 +53,31 @@ export class RemoteDataBuildService { const errorMessage = responseCacheObs .filter((entry: ResponseCacheEntry) => !entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => (entry.response).errorMessage) + .map((entry: ResponseCacheEntry) => (entry.response as ErrorResponse).errorMessage) .distinctUntilChanged(); const statusCode = responseCacheObs .map((entry: ResponseCacheEntry) => entry.response.statusCode) .distinctUntilChanged(); + /* tslint:disable:no-string-literal */ const pageInfo = responseCacheObs .filter((entry: ResponseCacheEntry) => hasValue(entry.response) && hasValue(entry.response['pageInfo'])) - .map((entry: ResponseCacheEntry) => (entry.response).pageInfo) + .map((entry: ResponseCacheEntry) => (entry.response as SuccessResponse).pageInfo) .distinctUntilChanged(); + /* tslint:enable:no-string-literal */ - //always use self link if that is cached, only if it isn't, get it via the response. + // always use self link if that is cached, only if it isn't, get it via the response. const payload = Observable.combineLatest( this.objectCache.getBySelfLink(href, normalizedType).startWith(undefined), responseCacheObs .filter((entry: ResponseCacheEntry) => entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => (entry.response).resourceUUIDs) - .flatMap((resourceUUIDs: Array) => { + .map((entry: ResponseCacheEntry) => (entry.response as SuccessResponse).resourceUUIDs) + .flatMap((resourceUUIDs: string[]) => { if (isNotEmpty(resourceUUIDs)) { return this.objectCache.get(resourceUUIDs[0], normalizedType); - } - else { + } else { return Observable.of(undefined); } }) @@ -84,17 +86,15 @@ export class RemoteDataBuildService { (fromSelfLink, fromResponse) => { if (hasValue(fromSelfLink)) { return fromSelfLink; - } - else { + } else { return fromResponse; } } - ).filter(normalized => hasValue(normalized)) + ).filter((normalized) => hasValue(normalized)) .map((normalized: TNormalized) => { return this.build(normalized); }); - return new RemoteData( href, requestPending, @@ -112,8 +112,8 @@ export class RemoteDataBuildService { normalizedType: GenericConstructor ): RemoteData { const requestObs = this.store.select('core', 'data', 'request', href) - .filter(entry => hasValue(entry)); - const responseCacheObs = this.responseCache.get(href).filter(entry => hasValue(entry)); + .filter((entry) => hasValue(entry)); + const responseCacheObs = this.responseCache.get(href).filter((entry) => hasValue(entry)); const requestPending = requestObs.map((entry: RequestEntry) => entry.requestPending).distinctUntilChanged(); @@ -124,22 +124,24 @@ export class RemoteDataBuildService { const errorMessage = responseCacheObs .filter((entry: ResponseCacheEntry) => !entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => (entry.response).errorMessage) + .map((entry: ResponseCacheEntry) => (entry.response as ErrorResponse).errorMessage) .distinctUntilChanged(); const statusCode = responseCacheObs .map((entry: ResponseCacheEntry) => entry.response.statusCode) .distinctUntilChanged(); + /* tslint:disable:no-string-literal */ const pageInfo = responseCacheObs .filter((entry: ResponseCacheEntry) => hasValue(entry.response) && hasValue(entry.response['pageInfo'])) - .map((entry: ResponseCacheEntry) => (entry.response).pageInfo) + .map((entry: ResponseCacheEntry) => (entry.response as SuccessResponse).pageInfo) .distinctUntilChanged(); + /* tslint:enable:no-string-literal */ const payload = responseCacheObs .filter((entry: ResponseCacheEntry) => entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => (entry.response).resourceUUIDs) - .flatMap((resourceUUIDs: Array) => { + .map((entry: ResponseCacheEntry) => (entry.response as SuccessResponse).resourceUUIDs) + .flatMap((resourceUUIDs: string[]) => { return this.objectCache.getList(resourceUUIDs, normalizedType) .map((normList: TNormalized[]) => { return normList.map((normalized: TNormalized) => { @@ -161,9 +163,8 @@ export class RemoteDataBuildService { ); } - build(normalized: TNormalized): TDomain { - let links: any = {}; + const links: any = {}; const relationships = getRelationships(normalized.constructor) || []; @@ -180,19 +181,17 @@ export class RemoteDataBuildService { }); }, 0); - let rdArr = []; + const rdArr = []; normalized[relationship].forEach((href: string) => { rdArr.push(this.buildSingle(href, resourceConstructor)); }); if (rdArr.length === 1) { links[relationship] = rdArr[0]; - } - else { + } else { links[relationship] = this.aggregate(rdArr); } - } - else { + } else { // without the setTimeout, the actions inside requestService.configure // are dispatched, but sometimes don't arrive. I'm unsure why atm. setTimeout(() => { @@ -215,51 +214,49 @@ export class RemoteDataBuildService { return Object.assign(new domainModel(), normalized, links); } - aggregate(input: RemoteData[]): RemoteData { + aggregate(input: Array>): RemoteData { const requestPending = Observable.combineLatest( - ...input.map(rd => rd.isRequestPending), - ).map((...pendingArray) => pendingArray.every(e => e === true)) + ...input.map((rd) => rd.isRequestPending), + ).map((...pendingArray) => pendingArray.every((e) => e === true)) .distinctUntilChanged(); const responsePending = Observable.combineLatest( - ...input.map(rd => rd.isResponsePending), - ).map((...pendingArray) => pendingArray.every(e => e === true)) + ...input.map((rd) => rd.isResponsePending), + ).map((...pendingArray) => pendingArray.every((e) => e === true)) .distinctUntilChanged(); const isSuccessFul = Observable.combineLatest( - ...input.map(rd => rd.hasSucceeded), - ).map((...successArray) => successArray.every(e => e === true)) + ...input.map((rd) => rd.hasSucceeded), + ).map((...successArray) => successArray.every((e) => e === true)) .distinctUntilChanged(); const errorMessage = Observable.combineLatest( - ...input.map(rd => rd.errorMessage), + ...input.map((rd) => rd.errorMessage), ).map((...errors) => errors .map((e, idx) => { if (hasValue(e)) { return `[${idx}]: ${e}`; } }) - .filter(e => hasValue(e)) - .join(", ") + .filter((e) => hasValue(e)) + .join(', ') ); const statusCode = Observable.combineLatest( - ...input.map(rd => rd.statusCode), + ...input.map((rd) => rd.statusCode), ).map((...statusCodes) => statusCodes .map((code, idx) => { if (hasValue(code)) { return `[${idx}]: ${code}`; } }) - .filter(c => hasValue(c)) - .join(", ") + .filter((c) => hasValue(c)) + .join(', ') ); const pageInfo = Observable.of(undefined); - const payload = >Observable.combineLatest( - ...input.map(rd => rd.payload) - ); + const payload = Observable.combineLatest(...input.map((rd) => rd.payload)) as Observable; return new RemoteData( // This is an aggregated object, it doesn't necessarily correspond @@ -275,4 +272,5 @@ export class RemoteDataBuildService { payload ); } + } diff --git a/src/app/core/cache/cache.reducers.ts b/src/app/core/cache/cache.reducers.ts index b5cd5c7b41..a2bce403d3 100644 --- a/src/app/core/cache/cache.reducers.ts +++ b/src/app/core/cache/cache.reducers.ts @@ -1,6 +1,7 @@ -import { combineReducers } from "@ngrx/store"; -import { ResponseCacheState, responseCacheReducer } from "./response-cache.reducer"; -import { ObjectCacheState, objectCacheReducer } from "./object-cache.reducer"; +import { combineReducers } from '@ngrx/store'; + +import { ResponseCacheState, responseCacheReducer } from './response-cache.reducer'; +import { ObjectCacheState, objectCacheReducer } from './object-cache.reducer'; export interface CacheState { response: ResponseCacheState, diff --git a/src/app/core/cache/models/normalized-bitstream-format.model.ts b/src/app/core/cache/models/normalized-bitstream-format.model.ts index 188bd3d185..2813794011 100644 --- a/src/app/core/cache/models/normalized-bitstream-format.model.ts +++ b/src/app/core/cache/models/normalized-bitstream-format.model.ts @@ -1,11 +1,13 @@ -import { NormalizedObject } from "./normalized-object.model"; -import { inheritSerialization } from "cerialize"; +import { inheritSerialization } from 'cerialize'; + +import { NormalizedObject } from './normalized-object.model'; @inheritSerialization(NormalizedObject) export class NormalizedBitstreamFormat extends NormalizedObject { - //TODO this class was created as a placeholder when we connected to the live rest api + // TODO: this class was created as a placeholder when we connected to the live rest api get uuid(): string { return this.self; } + } diff --git a/src/app/core/cache/models/normalized-bitstream.model.ts b/src/app/core/cache/models/normalized-bitstream.model.ts index 3b5c4fdc85..4ac2718056 100644 --- a/src/app/core/cache/models/normalized-bitstream.model.ts +++ b/src/app/core/cache/models/normalized-bitstream.model.ts @@ -1,8 +1,9 @@ -import { inheritSerialization, autoserialize } from "cerialize"; -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { Bitstream } from "../../shared/bitstream.model"; -import { mapsTo, relationship } from "../builders/build-decorators"; -import { ResourceType } from "../../shared/resource-type"; +import { inheritSerialization, autoserialize } from 'cerialize'; + +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { Bitstream } from '../../shared/bitstream.model'; +import { mapsTo, relationship } from '../builders/build-decorators'; +import { ResourceType } from '../../shared/resource-type'; @mapsTo(Bitstream) @inheritSerialization(NormalizedDSpaceObject) @@ -43,7 +44,7 @@ export class NormalizedBitstream extends NormalizedDSpaceObject { */ @autoserialize @relationship(ResourceType.Item, true) - parents: Array; + parents: string[]; /** * The Bundle that owns this Bitstream @@ -57,4 +58,5 @@ export class NormalizedBitstream extends NormalizedDSpaceObject { */ @autoserialize bundleName: string; + } diff --git a/src/app/core/cache/models/normalized-bundle.model.ts b/src/app/core/cache/models/normalized-bundle.model.ts index 839f09b247..3b594dd308 100644 --- a/src/app/core/cache/models/normalized-bundle.model.ts +++ b/src/app/core/cache/models/normalized-bundle.model.ts @@ -1,8 +1,9 @@ -import { autoserialize, inheritSerialization } from "cerialize"; -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { Bundle } from "../../shared/bundle.model"; -import { mapsTo, relationship } from "../builders/build-decorators"; -import { ResourceType } from "../../shared/resource-type"; +import { autoserialize, inheritSerialization } from 'cerialize'; + +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { Bundle } from '../../shared/bundle.model'; +import { mapsTo, relationship } from '../builders/build-decorators'; +import { ResourceType } from '../../shared/resource-type'; @mapsTo(Bundle) @inheritSerialization(NormalizedDSpaceObject) @@ -17,7 +18,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject { /** * An array of Items that are direct parents of this Bundle */ - parents: Array; + parents: string[]; /** * The Item that owns this Bundle @@ -26,5 +27,6 @@ export class NormalizedBundle extends NormalizedDSpaceObject { @autoserialize @relationship(ResourceType.Bitstream, true) - bitstreams: Array; + bitstreams: string[]; + } diff --git a/src/app/core/cache/models/normalized-collection.model.ts b/src/app/core/cache/models/normalized-collection.model.ts index 669c02e383..22e0d20eaa 100644 --- a/src/app/core/cache/models/normalized-collection.model.ts +++ b/src/app/core/cache/models/normalized-collection.model.ts @@ -1,8 +1,9 @@ -import { autoserialize, inheritSerialization, autoserializeAs } from "cerialize"; -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { Collection } from "../../shared/collection.model"; -import { mapsTo, relationship } from "../builders/build-decorators"; -import { ResourceType } from "../../shared/resource-type"; +import { autoserialize, inheritSerialization, autoserializeAs } from 'cerialize'; + +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { Collection } from '../../shared/collection.model'; +import { mapsTo, relationship } from '../builders/build-decorators'; +import { ResourceType } from '../../shared/resource-type'; @mapsTo(Collection) @inheritSerialization(NormalizedDSpaceObject) @@ -26,7 +27,7 @@ export class NormalizedCollection extends NormalizedDSpaceObject { */ @autoserialize @relationship(ResourceType.Community, true) - parents: Array; + parents: string[]; /** * The Community that owns this Collection @@ -37,6 +38,6 @@ export class NormalizedCollection extends NormalizedDSpaceObject { @autoserialize @relationship(ResourceType.Item, true) - items: Array; + items: string[]; } diff --git a/src/app/core/cache/models/normalized-community.model.ts b/src/app/core/cache/models/normalized-community.model.ts index 1a6b0fea9e..03784e414b 100644 --- a/src/app/core/cache/models/normalized-community.model.ts +++ b/src/app/core/cache/models/normalized-community.model.ts @@ -1,8 +1,9 @@ -import { autoserialize, inheritSerialization, autoserializeAs } from "cerialize"; -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { Community } from "../../shared/community.model"; -import { mapsTo, relationship } from "../builders/build-decorators"; -import { ResourceType } from "../../shared/resource-type"; +import { autoserialize, inheritSerialization, autoserializeAs } from 'cerialize'; + +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { Community } from '../../shared/community.model'; +import { mapsTo, relationship } from '../builders/build-decorators'; +import { ResourceType } from '../../shared/resource-type'; @mapsTo(Community) @inheritSerialization(NormalizedDSpaceObject) @@ -26,7 +27,7 @@ export class NormalizedCommunity extends NormalizedDSpaceObject { */ @autoserialize @relationship(ResourceType.Community, true) - parents: Array; + parents: string[]; /** * The Community that owns this Community @@ -37,6 +38,6 @@ export class NormalizedCommunity extends NormalizedDSpaceObject { @autoserialize @relationship(ResourceType.Collection, true) - collections: Array; + collections: string[]; } diff --git a/src/app/core/cache/models/normalized-dspace-object.model.ts b/src/app/core/cache/models/normalized-dspace-object.model.ts index bfd6b56671..3c6ca663c6 100644 --- a/src/app/core/cache/models/normalized-dspace-object.model.ts +++ b/src/app/core/cache/models/normalized-dspace-object.model.ts @@ -1,7 +1,8 @@ -import { autoserialize, autoserializeAs, inheritSerialization } from "cerialize"; -import { Metadatum } from "../../shared/metadatum.model"; -import { ResourceType } from "../../shared/resource-type"; -import { NormalizedObject } from "./normalized-object.model"; +import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; + +import { Metadatum } from '../../shared/metadatum.model'; +import { ResourceType } from '../../shared/resource-type'; +import { NormalizedObject } from './normalized-object.model'; /** * An abstract model class for a DSpaceObject. @@ -51,17 +52,18 @@ export abstract class NormalizedDSpaceObject extends NormalizedObject { * An array containing all metadata of this DSpaceObject */ @autoserializeAs(Metadatum) - metadata: Array; + metadata: Metadatum[]; /** * An array of DSpaceObjects that are direct parents of this DSpaceObject */ @autoserialize - parents: Array; + parents: string[]; /** * The DSpaceObject that owns this DSpaceObject */ @autoserialize owner: string; + } diff --git a/src/app/core/cache/models/normalized-item.model.ts b/src/app/core/cache/models/normalized-item.model.ts index a4e52110ff..a4a14e424c 100644 --- a/src/app/core/cache/models/normalized-item.model.ts +++ b/src/app/core/cache/models/normalized-item.model.ts @@ -1,8 +1,9 @@ -import { inheritSerialization, autoserialize, autoserializeAs } from "cerialize"; -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { Item } from "../../shared/item.model"; -import { mapsTo, relationship } from "../builders/build-decorators"; -import { ResourceType } from "../../shared/resource-type"; +import { inheritSerialization, autoserialize, autoserializeAs } from 'cerialize'; + +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { Item } from '../../shared/item.model'; +import { mapsTo, relationship } from '../builders/build-decorators'; +import { ResourceType } from '../../shared/resource-type'; @mapsTo(Item) @inheritSerialization(NormalizedDSpaceObject) @@ -43,7 +44,7 @@ export class NormalizedItem extends NormalizedDSpaceObject { */ @autoserialize @relationship(ResourceType.Collection, true) - parents: Array; + parents: string[]; /** * The Collection that owns this Item @@ -53,5 +54,6 @@ export class NormalizedItem extends NormalizedDSpaceObject { @autoserialize @relationship(ResourceType.Bitstream, true) - bitstreams: Array; + bitstreams: string[]; + } diff --git a/src/app/core/cache/models/normalized-object-factory.ts b/src/app/core/cache/models/normalized-object-factory.ts index 84bd2061cb..e9f3b1c9e6 100644 --- a/src/app/core/cache/models/normalized-object-factory.ts +++ b/src/app/core/cache/models/normalized-object-factory.ts @@ -1,13 +1,13 @@ -import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; -import { NormalizedBitstream } from "./normalized-bitstream.model"; -import { NormalizedBundle } from "./normalized-bundle.model"; -import { NormalizedItem } from "./normalized-item.model"; -import { NormalizedCollection } from "./normalized-collection.model"; -import { GenericConstructor } from "../../shared/generic-constructor"; -import { NormalizedCommunity } from "./normalized-community.model"; -import { ResourceType } from "../../shared/resource-type"; -import { NormalizedObject } from "./normalized-object.model"; -import { NormalizedBitstreamFormat } from "./normalized-bitstream-format.model"; +import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; +import { NormalizedBitstream } from './normalized-bitstream.model'; +import { NormalizedBundle } from './normalized-bundle.model'; +import { NormalizedItem } from './normalized-item.model'; +import { NormalizedCollection } from './normalized-collection.model'; +import { GenericConstructor } from '../../shared/generic-constructor'; +import { NormalizedCommunity } from './normalized-community.model'; +import { ResourceType } from '../../shared/resource-type'; +import { NormalizedObject } from './normalized-object.model'; +import { NormalizedBitstreamFormat } from './normalized-bitstream-format.model'; export class NormalizedObjectFactory { public static getConstructor(type: ResourceType): GenericConstructor { diff --git a/src/app/core/cache/models/normalized-object.model.ts b/src/app/core/cache/models/normalized-object.model.ts index 055996ab47..7c4154eae9 100644 --- a/src/app/core/cache/models/normalized-object.model.ts +++ b/src/app/core/cache/models/normalized-object.model.ts @@ -1,5 +1,5 @@ -import { CacheableObject } from "../object-cache.reducer"; -import { autoserialize } from "cerialize"; +import { CacheableObject } from '../object-cache.reducer'; +import { autoserialize } from 'cerialize'; /** * An abstract model class for a NormalizedObject. */ diff --git a/src/app/core/cache/models/self-link.model.ts b/src/app/core/cache/models/self-link.model.ts index 5adc78062a..a87acdd506 100644 --- a/src/app/core/cache/models/self-link.model.ts +++ b/src/app/core/cache/models/self-link.model.ts @@ -1,4 +1,4 @@ -import { autoserialize } from "cerialize"; +import { autoserialize } from 'cerialize'; export class SelfLink { @@ -7,4 +7,5 @@ export class SelfLink { @autoserialize uuid: string; + } diff --git a/src/app/core/cache/models/sort-options.model.ts b/src/app/core/cache/models/sort-options.model.ts index 6c24166d1a..ad639bf853 100644 --- a/src/app/core/cache/models/sort-options.model.ts +++ b/src/app/core/cache/models/sort-options.model.ts @@ -5,7 +5,7 @@ export enum SortDirection { export class SortOptions { - constructor(public field: string = "name", public direction: SortDirection = SortDirection.Ascending) { + constructor(public field: string = 'name', public direction: SortDirection = SortDirection.Ascending) { } } diff --git a/src/app/core/cache/object-cache.actions.ts b/src/app/core/cache/object-cache.actions.ts index 9d34c01219..a136b04248 100644 --- a/src/app/core/cache/object-cache.actions.ts +++ b/src/app/core/cache/object-cache.actions.ts @@ -1,6 +1,7 @@ -import { Action } from "@ngrx/store"; -import { type } from "../../shared/ngrx/type"; -import { CacheableObject } from "./object-cache.reducer"; +import { Action } from '@ngrx/store'; + +import { type } from '../../shared/ngrx/type'; +import { CacheableObject } from './object-cache.reducer'; /** * The list of ObjectCacheAction type definitions @@ -11,6 +12,7 @@ export const ObjectCacheActionTypes = { RESET_TIMESTAMPS: type('dspace/core/cache/object/RESET_TIMESTAMPS') }; +/* tslint:disable:max-classes-per-file */ /** * An ngrx action to add an object to the cache */ @@ -77,6 +79,7 @@ export class ResetObjectCacheTimestampsAction implements Action { this.payload = newTimestamp; } } +/* tslint:enable:max-classes-per-file */ /** * A type to encompass all ObjectCacheActions diff --git a/src/app/core/cache/object-cache.reducer.spec.ts b/src/app/core/cache/object-cache.reducer.spec.ts index 7049ea2cb8..d02e1faab7 100644 --- a/src/app/core/cache/object-cache.reducer.spec.ts +++ b/src/app/core/cache/object-cache.reducer.spec.ts @@ -1,9 +1,10 @@ -import * as deepFreeze from "deep-freeze"; -import { objectCacheReducer } from "./object-cache.reducer"; +import * as deepFreeze from 'deep-freeze'; + +import { objectCacheReducer } from './object-cache.reducer'; import { AddToObjectCacheAction, RemoveFromObjectCacheAction, ResetObjectCacheTimestampsAction -} from "./object-cache.actions"; +} from './object-cache.actions'; class NullAction extends RemoveFromObjectCacheAction { type = null; @@ -14,51 +15,51 @@ class NullAction extends RemoveFromObjectCacheAction { } } -describe("objectCacheReducer", () => { +describe('objectCacheReducer', () => { const uuid1 = '1698f1d3-be98-4c51-9fd8-6bfedcbd59b7'; const uuid2 = '28b04544-1766-4e82-9728-c4e93544ecd3'; const testState = { [uuid1]: { data: { uuid: uuid1, - foo: "bar" + foo: 'bar' }, timeAdded: new Date().getTime(), msToLive: 900000, - requestHref: "https://rest.api/endpoint/uuid1" + requestHref: 'https://rest.api/endpoint/uuid1' }, [uuid2]: { data: { uuid: uuid2, - foo: "baz" + foo: 'baz' }, timeAdded: new Date().getTime(), msToLive: 900000, - requestHref: "https://rest.api/endpoint/uuid2" + requestHref: 'https://rest.api/endpoint/uuid2' } }; deepFreeze(testState); - it("should return the current state when no valid actions have been made", () => { + it('should return the current state when no valid actions have been made', () => { const action = new NullAction(); const newState = objectCacheReducer(testState, action); expect(newState).toEqual(testState); }); - it("should start with an empty cache", () => { + it('should start with an empty cache', () => { const action = new NullAction(); const initialState = objectCacheReducer(undefined, action); expect(initialState).toEqual(Object.create(null)); }); - it("should add the payload to the cache in response to an ADD action", () => { + it('should add the payload to the cache in response to an ADD action', () => { const state = Object.create(null); const objectToCache = { uuid: uuid1 }; const timeAdded = new Date().getTime(); const msToLive = 900000; - const requestHref = "https://rest.api/endpoint/uuid1"; + const requestHref = 'https://rest.api/endpoint/uuid1'; const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); const newState = objectCacheReducer(state, action); @@ -67,31 +68,33 @@ describe("objectCacheReducer", () => { expect(newState[uuid1].msToLive).toEqual(msToLive); }); - it("should overwrite an object in the cache in response to an ADD action if it already exists", () => { - const objectToCache = { uuid: uuid1, foo: "baz", somethingElse: true }; + it('should overwrite an object in the cache in response to an ADD action if it already exists', () => { + const objectToCache = { uuid: uuid1, foo: 'baz', somethingElse: true }; const timeAdded = new Date().getTime(); const msToLive = 900000; - const requestHref = "https://rest.api/endpoint/uuid1"; + const requestHref = 'https://rest.api/endpoint/uuid1'; const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); const newState = objectCacheReducer(testState, action); - expect(newState[uuid1].data['foo']).toBe("baz"); + /* tslint:disable:no-string-literal */ + expect(newState[uuid1].data['foo']).toBe('baz'); expect(newState[uuid1].data['somethingElse']).toBe(true); + /* tslint:enable:no-string-literal */ }); - it("should perform the ADD action without affecting the previous state", () => { + it('should perform the ADD action without affecting the previous state', () => { const state = Object.create(null); const objectToCache = { uuid: uuid1 }; const timeAdded = new Date().getTime(); const msToLive = 900000; - const requestHref = "https://rest.api/endpoint/uuid1"; + const requestHref = 'https://rest.api/endpoint/uuid1'; const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); deepFreeze(state); objectCacheReducer(state, action); }); - it("should remove the specified object from the cache in response to the REMOVE action", () => { + it('should remove the specified object from the cache in response to the REMOVE action', () => { const action = new RemoveFromObjectCacheAction(uuid1); const newState = objectCacheReducer(testState, action); @@ -108,13 +111,13 @@ describe("objectCacheReducer", () => { expect(newState).toEqual(testState); }); - it("should perform the REMOVE action without affecting the previous state", () => { + it('should perform the REMOVE action without affecting the previous state', () => { const action = new RemoveFromObjectCacheAction(uuid1); - //testState has already been frozen above + // testState has already been frozen above objectCacheReducer(testState, action); }); - it("should set the timestamp of all objects in the cache in response to a RESET_TIMESTAMPS action", () => { + it('should set the timestamp of all objects in the cache in response to a RESET_TIMESTAMPS action', () => { const newTimestamp = new Date().getTime(); const action = new ResetObjectCacheTimestampsAction(newTimestamp); const newState = objectCacheReducer(testState, action); @@ -123,9 +126,9 @@ describe("objectCacheReducer", () => { }); }); - it("should perform the RESET_TIMESTAMPS action without affecting the previous state", () => { + it('should perform the RESET_TIMESTAMPS action without affecting the previous state', () => { const action = new ResetObjectCacheTimestampsAction(new Date().getTime()); - //testState has already been frozen above + // testState has already been frozen above objectCacheReducer(testState, action); }); diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index 113a06cd06..e690efaccc 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -1,9 +1,9 @@ import { ObjectCacheAction, ObjectCacheActionTypes, AddToObjectCacheAction, RemoveFromObjectCacheAction, ResetObjectCacheTimestampsAction -} from "./object-cache.actions"; -import { hasValue } from "../../shared/empty.util"; -import { CacheEntry } from "./cache-entry"; +} from './object-cache.actions'; +import { hasValue } from '../../shared/empty.util'; +import { CacheEntry } from './cache-entry'; /** * An interface to represent objects that can be cached @@ -52,15 +52,15 @@ export const objectCacheReducer = (state = initialState, action: ObjectCacheActi switch (action.type) { case ObjectCacheActionTypes.ADD: { - return addToObjectCache(state, action); + return addToObjectCache(state, action as AddToObjectCacheAction); } case ObjectCacheActionTypes.REMOVE: { - return removeFromObjectCache(state, action) + return removeFromObjectCache(state, action as RemoveFromObjectCacheAction) } case ObjectCacheActionTypes.RESET_TIMESTAMPS: { - return resetObjectCacheTimestamps(state, action) + return resetObjectCacheTimestamps(state, action as ResetObjectCacheTimestampsAction) } default: { @@ -102,12 +102,11 @@ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheActio */ function removeFromObjectCache(state: ObjectCacheState, action: RemoveFromObjectCacheAction): ObjectCacheState { if (hasValue(state[action.payload])) { - let newObjectCache = Object.assign({}, state); + const newObjectCache = Object.assign({}, state); delete newObjectCache[action.payload]; return newObjectCache; - } - else { + } else { return state; } } @@ -123,8 +122,8 @@ function removeFromObjectCache(state: ObjectCacheState, action: RemoveFromObject * the new state, with all timeAdded timestamps set to the specified value */ function resetObjectCacheTimestamps(state: ObjectCacheState, action: ResetObjectCacheTimestampsAction): ObjectCacheState { - let newState = Object.create(null); - Object.keys(state).forEach(key => { + const newState = Object.create(null); + Object.keys(state).forEach((key) => { newState[key] = Object.assign({}, state[key], { timeAdded: action.payload }); diff --git a/src/app/core/cache/object-cache.service.spec.ts b/src/app/core/cache/object-cache.service.spec.ts index d05f9ea191..09d28605e2 100644 --- a/src/app/core/cache/object-cache.service.spec.ts +++ b/src/app/core/cache/object-cache.service.spec.ts @@ -1,9 +1,9 @@ -import { Store } from "@ngrx/store"; -import { Observable } from "rxjs"; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; -import { ObjectCacheService } from "./object-cache.service"; -import { ObjectCacheState, CacheableObject } from "./object-cache.reducer"; -import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from "./object-cache.actions"; +import { ObjectCacheService } from './object-cache.service'; +import { ObjectCacheState, CacheableObject } from './object-cache.reducer'; +import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from './object-cache.actions'; class TestClass implements CacheableObject { constructor( @@ -16,7 +16,7 @@ class TestClass implements CacheableObject { } } -describe("ObjectCacheService", () => { +describe('ObjectCacheService', () => { let service: ObjectCacheService; let store: Store; @@ -40,65 +40,65 @@ describe("ObjectCacheService", () => { spyOn(store, 'dispatch'); service = new ObjectCacheService(store); - spyOn(Date.prototype, 'getTime').and.callFake(function() { + spyOn(Date.prototype, 'getTime').and.callFake(() => { return timestamp; }); }); - describe("add", () => { - it("should dispatch an ADD action with the object to add, the time to live, and the current timestamp", () => { + describe('add', () => { + it('should dispatch an ADD action with the object to add, the time to live, and the current timestamp', () => { service.add(objectToCache, msToLive, requestHref); expect(store.dispatch).toHaveBeenCalledWith(new AddToObjectCacheAction(objectToCache, timestamp, msToLive, requestHref)); }); }); - describe("remove", () => { - it("should dispatch a REMOVE action with the UUID of the object to remove", () => { + describe('remove', () => { + it('should dispatch a REMOVE action with the UUID of the object to remove', () => { service.remove(uuid); expect(store.dispatch).toHaveBeenCalledWith(new RemoveFromObjectCacheAction(uuid)); }); }); - describe("get", () => { - it("should return an observable of the cached object with the specified UUID and type", () => { + describe('get', () => { + it('should return an observable of the cached object with the specified UUID and type', () => { spyOn(store, 'select').and.returnValue(Observable.of(cacheEntry)); let testObj: any; - //due to the implementation of spyOn above, this subscribe will be synchronous - service.get(uuid, TestClass).take(1).subscribe(o => testObj = o); + // due to the implementation of spyOn above, this subscribe will be synchronous + service.get(uuid, TestClass).take(1).subscribe((o) => testObj = o); expect(testObj.uuid).toBe(uuid); - expect(testObj.foo).toBe("bar"); + expect(testObj.foo).toBe('bar'); // this only works if testObj is an instance of TestClass - expect(testObj.test()).toBe("bar" + uuid); + expect(testObj.test()).toBe('bar' + uuid); }); - it("should not return a cached object that has exceeded its time to live", () => { + it('should not return a cached object that has exceeded its time to live', () => { spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry)); let getObsHasFired = false; - const subscription = service.get(uuid, TestClass).subscribe(o => getObsHasFired = true); + const subscription = service.get(uuid, TestClass).subscribe((o) => getObsHasFired = true); expect(getObsHasFired).toBe(false); subscription.unsubscribe(); }); }); - describe("getList", () => { - it("should return an observable of the array of cached objects with the specified UUID and type", () => { - spyOn(service, 'get').and.returnValue(Observable.of(new TestClass(uuid, "bar"))); + describe('getList', () => { + it('should return an observable of the array of cached objects with the specified UUID and type', () => { + spyOn(service, 'get').and.returnValue(Observable.of(new TestClass(uuid, 'bar'))); - let testObjs: Array; - service.getList([uuid, uuid], TestClass).take(1).subscribe(arr => testObjs = arr); + let testObjs: any[]; + service.getList([uuid, uuid], TestClass).take(1).subscribe((arr) => testObjs = arr); expect(testObjs[0].uuid).toBe(uuid); - expect(testObjs[0].foo).toBe("bar"); - expect(testObjs[0].test()).toBe("bar" + uuid); + expect(testObjs[0].foo).toBe('bar'); + expect(testObjs[0].test()).toBe('bar' + uuid); expect(testObjs[1].uuid).toBe(uuid); - expect(testObjs[1].foo).toBe("bar"); - expect(testObjs[1].test()).toBe("bar" + uuid); + expect(testObjs[1].foo).toBe('bar'); + expect(testObjs[1].test()).toBe('bar' + uuid); }); }); - describe("has", () => { - it("should return true if the object with the supplied UUID is cached and still valid", () => { + describe('has', () => { + it('should return true if the object with the supplied UUID is cached and still valid', () => { spyOn(store, 'select').and.returnValue(Observable.of(cacheEntry)); expect(service.has(uuid)).toBe(true); @@ -110,10 +110,11 @@ describe("ObjectCacheService", () => { expect(service.has(uuid)).toBe(false); }); - it("should return false if the object with the supplied UUID is cached but has exceeded its time to live", () => { + it('should return false if the object with the supplied UUID is cached but has exceeded its time to live', () => { spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry)); expect(service.has(uuid)).toBe(false); }); }); + }); diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 827f6198e5..7f4dbf9893 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -1,10 +1,12 @@ -import { Injectable } from "@angular/core"; -import { Store } from "@ngrx/store"; -import { ObjectCacheState, ObjectCacheEntry, CacheableObject } from "./object-cache.reducer"; -import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from "./object-cache.actions"; -import { Observable } from "rxjs"; -import { hasNoValue } from "../../shared/empty.util"; -import { GenericConstructor } from "../shared/generic-constructor"; +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; + +import { Observable } from 'rxjs/Observable'; + +import { ObjectCacheState, ObjectCacheEntry, CacheableObject } from './object-cache.reducer'; +import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from './object-cache.actions'; +import { hasNoValue } from '../../shared/empty.util'; +import { GenericConstructor } from '../shared/generic-constructor'; /** * A service to interact with the object cache @@ -59,7 +61,7 @@ export class ObjectCacheService { */ get(uuid: string, type: GenericConstructor): Observable { return this.getEntry(uuid) - .map((entry: ObjectCacheEntry) => Object.assign(new type(), entry.data)); + .map((entry: ObjectCacheEntry) => Object.assign(new type(), entry.data) as T); } getBySelfLink(href: string, type: GenericConstructor): Observable { @@ -69,7 +71,7 @@ export class ObjectCacheService { private getEntry(uuid: string): Observable { return this.store.select('core', 'cache', 'object', uuid) - .filter(entry => this.isValid(entry)) + .filter((entry) => this.isValid(entry)) .distinctUntilChanged(); } @@ -103,7 +105,7 @@ export class ObjectCacheService { * The type of the objects to get * @return Observable> */ - getList(uuids: Array, type: GenericConstructor): Observable> { + getList(uuids: string[], type: GenericConstructor): Observable { return Observable.combineLatest( uuids.map((id: string) => this.get(id, type)) ); @@ -123,7 +125,7 @@ export class ObjectCacheService { this.store.select('core', 'cache', 'object', uuid) .take(1) - .subscribe(entry => result = this.isValid(entry)); + .subscribe((entry) => result = this.isValid(entry)); return result; } @@ -138,7 +140,7 @@ export class ObjectCacheService { * false otherwise */ hasBySelfLink(href: string): boolean { - let result: boolean = false; + let result = false; this.store.select('core', 'index', 'href', href) .take(1) @@ -159,8 +161,7 @@ export class ObjectCacheService { private isValid(entry: ObjectCacheEntry): boolean { if (hasNoValue(entry)) { return false; - } - else { + } else { const timeOutdated = entry.timeAdded + entry.msToLive; const isOutDated = new Date().getTime() > timeOutdated; if (isOutDated) { diff --git a/src/app/core/cache/response-cache.actions.ts b/src/app/core/cache/response-cache.actions.ts index 45f78f10b7..426996b4ac 100644 --- a/src/app/core/cache/response-cache.actions.ts +++ b/src/app/core/cache/response-cache.actions.ts @@ -1,6 +1,7 @@ -import { Action } from "@ngrx/store"; -import { type } from "../../shared/ngrx/type"; -import { Response } from "./response-cache.models"; +import { Action } from '@ngrx/store'; + +import { type } from '../../shared/ngrx/type'; +import { Response } from './response-cache.models'; /** * The list of ResponseCacheAction type definitions @@ -11,6 +12,7 @@ export const ResponseCacheActionTypes = { RESET_TIMESTAMPS: type('dspace/core/cache/response/RESET_TIMESTAMPS') }; +/* tslint:disable:max-classes-per-file */ export class ResponseCacheAddAction implements Action { type = ResponseCacheActionTypes.ADD; payload: { @@ -59,6 +61,7 @@ export class ResetResponseCacheTimestampsAction implements Action { this.payload = newTimestamp; } } +/* tslint:enable:max-classes-per-file */ /** * A type to encompass all ResponseCacheActions diff --git a/src/app/core/cache/response-cache.models.ts b/src/app/core/cache/response-cache.models.ts index 45eb5d9ee9..ef1bfb0925 100644 --- a/src/app/core/cache/response-cache.models.ts +++ b/src/app/core/cache/response-cache.models.ts @@ -1,6 +1,7 @@ -import { RequestError } from "../data/request.models"; -import { PageInfo } from "../shared/page-info.model"; +import { RequestError } from '../data/request.models'; +import { PageInfo } from '../shared/page-info.model'; +/* tslint:disable:max-classes-per-file */ export class Response { constructor( public isSuccessful: boolean, @@ -10,7 +11,7 @@ export class Response { export class SuccessResponse extends Response { constructor( - public resourceUUIDs: Array, + public resourceUUIDs: string[], public statusCode: string, public pageInfo?: PageInfo ) { @@ -27,3 +28,4 @@ export class ErrorResponse extends Response { this.errorMessage = error.message; } } +/* tslint:enable:max-classes-per-file */ diff --git a/src/app/core/cache/response-cache.reducer.spec.ts b/src/app/core/cache/response-cache.reducer.spec.ts index 0007003917..613b62f30f 100644 --- a/src/app/core/cache/response-cache.reducer.spec.ts +++ b/src/app/core/cache/response-cache.reducer.spec.ts @@ -1,11 +1,11 @@ -import * as deepFreeze from "deep-freeze"; +import * as deepFreeze from 'deep-freeze'; -import { responseCacheReducer, ResponseCacheState } from "./response-cache.reducer"; +import { responseCacheReducer, ResponseCacheState } from './response-cache.reducer'; import { ResponseCacheRemoveAction, ResetResponseCacheTimestampsAction -} from "./response-cache.actions"; +} from './response-cache.actions'; class NullAction extends ResponseCacheRemoveAction { type = null; @@ -16,37 +16,37 @@ class NullAction extends ResponseCacheRemoveAction { } } -// describe("responseCacheReducer", () => { -// const keys = ["125c17f89046283c5f0640722aac9feb", "a06c3006a41caec5d635af099b0c780c"]; +// describe('responseCacheReducer', () => { +// const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; // const services = [new OpaqueToken('service1'), new OpaqueToken('service2')]; // const msToLive = 900000; // const uuids = [ -// "9e32a2e2-6b91-4236-a361-995ccdc14c60", -// "598ce822-c357-46f3-ab70-63724d02d6ad", -// "be8325f7-243b-49f4-8a4b-df2b793ff3b5" +// '9e32a2e2-6b91-4236-a361-995ccdc14c60', +// '598ce822-c357-46f3-ab70-63724d02d6ad', +// 'be8325f7-243b-49f4-8a4b-df2b793ff3b5' // ]; -// const resourceID = "9978"; -// const paginationOptions = { "resultsPerPage": 10, "currentPage": 1 }; -// const sortOptions = { "field": "id", "direction": 0 }; +// const resourceID = '9978'; +// const paginationOptions = { 'resultsPerPage': 10, 'currentPage': 1 }; +// const sortOptions = { 'field': 'id', 'direction': 0 }; // const testState = { // [keys[0]]: { -// "key": keys[0], -// "service": services[0], -// "resourceUUIDs": [uuids[0], uuids[1]], -// "isLoading": false, -// "paginationOptions": paginationOptions, -// "sortOptions": sortOptions, -// "timeAdded": new Date().getTime(), -// "msToLive": msToLive +// 'key': keys[0], +// 'service': services[0], +// 'resourceUUIDs': [uuids[0], uuids[1]], +// 'isLoading': false, +// 'paginationOptions': paginationOptions, +// 'sortOptions': sortOptions, +// 'timeAdded': new Date().getTime(), +// 'msToLive': msToLive // }, // [keys[1]]: { -// "key": keys[1], -// "service": services[1], -// "resourceID": resourceID, -// "resourceUUIDs": [uuids[2]], -// "isLoading": false, -// "timeAdded": new Date().getTime(), -// "msToLive": msToLive +// 'key': keys[1], +// 'service': services[1], +// 'resourceID': resourceID, +// 'resourceUUIDs': [uuids[2]], +// 'isLoading': false, +// 'timeAdded': new Date().getTime(), +// 'msToLive': msToLive // } // }; // deepFreeze(testState); @@ -59,29 +59,29 @@ class NullAction extends ResponseCacheRemoveAction { // deepFreeze(errorState); // // -// it("should return the current state when no valid actions have been made", () => { +// it('should return the current state when no valid actions have been made', () => { // const action = new NullAction(); // const newState = responseCacheReducer(testState, action); // // expect(newState).toEqual(testState); // }); // -// it("should start with an empty cache", () => { +// it('should start with an empty cache', () => { // const action = new NullAction(); // const initialState = responseCacheReducer(undefined, action); // // expect(initialState).toEqual(Object.create(null)); // }); // -// describe("FIND_BY_ID", () => { +// describe('FIND_BY_ID', () => { // const action = new ResponseCacheFindByIDAction(keys[0], services[0], resourceID); // -// it("should perform the action without affecting the previous state", () => { +// it('should perform the action without affecting the previous state', () => { // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should add the request to the cache", () => { +// it('should add the request to the cache', () => { // const state = Object.create(null); // const newState = responseCacheReducer(state, action); // expect(newState[keys[0]].key).toBe(keys[0]); @@ -89,28 +89,28 @@ class NullAction extends ResponseCacheRemoveAction { // expect(newState[keys[0]].resourceID).toBe(resourceID); // }); // -// it("should set responsePending to true", () => { +// it('should set responsePending to true', () => { // const state = Object.create(null); // const newState = responseCacheReducer(state, action); // expect(newState[keys[0]].responsePending).toBe(true); // }); // -// it("should remove any previous error message or resourceUUID for the request", () => { +// it('should remove any previous error message or resourceUUID for the request', () => { // const newState = responseCacheReducer(errorState, action); // expect(newState[keys[0]].resourceUUIDs.length).toBe(0); // expect(newState[keys[0]].errorMessage).toBeUndefined(); // }); // }); // -// describe("FIND_ALL", () => { +// describe('FIND_ALL', () => { // const action = new ResponseCacheFindAllAction(keys[0], services[0], resourceID, paginationOptions, sortOptions); // -// it("should perform the action without affecting the previous state", () => { +// it('should perform the action without affecting the previous state', () => { // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should add the request to the cache", () => { +// it('should add the request to the cache', () => { // const state = Object.create(null); // const newState = responseCacheReducer(state, action); // expect(newState[keys[0]].key).toBe(keys[0]); @@ -120,84 +120,84 @@ class NullAction extends ResponseCacheRemoveAction { // expect(newState[keys[0]].sortOptions).toEqual(sortOptions); // }); // -// it("should set responsePending to true", () => { +// it('should set responsePending to true', () => { // const state = Object.create(null); // const newState = responseCacheReducer(state, action); // expect(newState[keys[0]].responsePending).toBe(true); // }); // -// it("should remove any previous error message or resourceUUIDs for the request", () => { +// it('should remove any previous error message or resourceUUIDs for the request', () => { // const newState = responseCacheReducer(errorState, action); // expect(newState[keys[0]].resourceUUIDs.length).toBe(0); // expect(newState[keys[0]].errorMessage).toBeUndefined(); // }); // }); // -// describe("SUCCESS", () => { +// describe('SUCCESS', () => { // const successUUIDs = [uuids[0], uuids[2]]; // const successTimeAdded = new Date().getTime(); // const successMsToLive = 5; // const action = new ResponseCacheSuccessAction(keys[0], successUUIDs, successTimeAdded, successMsToLive); // -// it("should perform the action without affecting the previous state", () => { +// it('should perform the action without affecting the previous state', () => { // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should add the response to the cached request", () => { +// it('should add the response to the cached request', () => { // const newState = responseCacheReducer(testState, action); // expect(newState[keys[0]].resourceUUIDs).toBe(successUUIDs); // expect(newState[keys[0]].timeAdded).toBe(successTimeAdded); // expect(newState[keys[0]].msToLive).toBe(successMsToLive); // }); // -// it("should set responsePending to false", () => { +// it('should set responsePending to false', () => { // const newState = responseCacheReducer(testState, action); // expect(newState[keys[0]].responsePending).toBe(false); // }); // -// it("should remove any previous error message for the request", () => { +// it('should remove any previous error message for the request', () => { // const newState = responseCacheReducer(errorState, action); // expect(newState[keys[0]].errorMessage).toBeUndefined(); // }); // }); // -// describe("ERROR", () => { +// describe('ERROR', () => { // const errorMsg = 'errorMsg'; // const action = new ResponseCacheErrorAction(keys[0], errorMsg); // -// it("should perform the action without affecting the previous state", () => { +// it('should perform the action without affecting the previous state', () => { // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should set an error message for the request", () => { +// it('should set an error message for the request', () => { // const newState = responseCacheReducer(errorState, action); // expect(newState[keys[0]].errorMessage).toBe(errorMsg); // }); // -// it("should set responsePending to false", () => { +// it('should set responsePending to false', () => { // const newState = responseCacheReducer(testState, action); // expect(newState[keys[0]].responsePending).toBe(false); // }); // }); // -// describe("REMOVE", () => { -// it("should perform the action without affecting the previous state", () => { +// describe('REMOVE', () => { +// it('should perform the action without affecting the previous state', () => { // const action = new ResponseCacheRemoveAction(keys[0]); // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should remove the specified request from the cache", () => { +// it('should remove the specified request from the cache', () => { // const action = new ResponseCacheRemoveAction(keys[0]); // const newState = responseCacheReducer(testState, action); // expect(testState[keys[0]]).not.toBeUndefined(); // expect(newState[keys[0]]).toBeUndefined(); // }); // -// it("shouldn't do anything when the specified key isn't cached", () => { -// const wrongKey = "this isn't cached"; +// it('shouldn't do anything when the specified key isn't cached', () => { +// const wrongKey = 'this isn't cached'; // const action = new ResponseCacheRemoveAction(wrongKey); // const newState = responseCacheReducer(testState, action); // expect(testState[wrongKey]).toBeUndefined(); @@ -205,16 +205,16 @@ class NullAction extends ResponseCacheRemoveAction { // }); // }); // -// describe("RESET_TIMESTAMPS", () => { +// describe('RESET_TIMESTAMPS', () => { // const newTimeStamp = new Date().getTime(); // const action = new ResetResponseCacheTimestampsAction(newTimeStamp); // -// it("should perform the action without affecting the previous state", () => { +// it('should perform the action without affecting the previous state', () => { // //testState has already been frozen above // responseCacheReducer(testState, action); // }); // -// it("should set the timestamp of all requests in the cache", () => { +// it('should set the timestamp of all requests in the cache', () => { // const newState = responseCacheReducer(testState, action); // Object.keys(newState).forEach((key) => { // expect(newState[key].timeAdded).toEqual(newTimeStamp); diff --git a/src/app/core/cache/response-cache.reducer.ts b/src/app/core/cache/response-cache.reducer.ts index f1ef174dce..ab2c49dc14 100644 --- a/src/app/core/cache/response-cache.reducer.ts +++ b/src/app/core/cache/response-cache.reducer.ts @@ -2,10 +2,10 @@ import { ResponseCacheAction, ResponseCacheActionTypes, ResponseCacheRemoveAction, ResetResponseCacheTimestampsAction, ResponseCacheAddAction -} from "./response-cache.actions"; -import { CacheEntry } from "./cache-entry"; -import { hasValue } from "../../shared/empty.util"; -import { Response } from "./response-cache.models"; +} from './response-cache.actions'; +import { CacheEntry } from './cache-entry'; +import { hasValue } from '../../shared/empty.util'; +import { Response } from './response-cache.models'; /** * An entry in the ResponseCache @@ -41,15 +41,15 @@ export const responseCacheReducer = (state = initialState, action: ResponseCache switch (action.type) { case ResponseCacheActionTypes.ADD: { - return addToCache(state, action); + return addToCache(state, action as ResponseCacheAddAction); } case ResponseCacheActionTypes.REMOVE: { - return removeFromCache(state, action); + return removeFromCache(state, action as ResponseCacheRemoveAction); } case ResponseCacheActionTypes.RESET_TIMESTAMPS: { - return resetResponseCacheTimestamps(state, action) + return resetResponseCacheTimestamps(state, action as ResetResponseCacheTimestampsAction) } default: { @@ -81,12 +81,11 @@ function addToCache(state: ResponseCacheState, action: ResponseCacheAddAction): */ function removeFromCache(state: ResponseCacheState, action: ResponseCacheRemoveAction): ResponseCacheState { if (hasValue(state[action.payload])) { - let newCache = Object.assign({}, state); + const newCache = Object.assign({}, state); delete newCache[action.payload]; return newCache; - } - else { + } else { return state; } } @@ -102,8 +101,8 @@ function removeFromCache(state: ResponseCacheState, action: ResponseCacheRemoveA * the new state, with all timeAdded timestamps set to the specified value */ function resetResponseCacheTimestamps(state: ResponseCacheState, action: ResetResponseCacheTimestampsAction): ResponseCacheState { - let newState = Object.create(null); - Object.keys(state).forEach(key => { + const newState = Object.create(null); + Object.keys(state).forEach((key) => { newState[key] = Object.assign({}, state[key], { timeAdded: action.payload }); diff --git a/src/app/core/cache/response-cache.service.spec.ts b/src/app/core/cache/response-cache.service.spec.ts index ec9da670a1..71b1da789c 100644 --- a/src/app/core/cache/response-cache.service.spec.ts +++ b/src/app/core/cache/response-cache.service.spec.ts @@ -1,18 +1,19 @@ -import { ResponseCacheService } from "./response-cache.service"; -import { Store } from "@ngrx/store"; -import { ResponseCacheState, ResponseCacheEntry } from "./response-cache.reducer"; -import { OpaqueToken } from "@angular/core"; -import { Observable } from "rxjs"; +import { OpaqueToken } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Store } from '@ngrx/store'; -// describe("ResponseCacheService", () => { +import { ResponseCacheService } from './response-cache.service'; +import { ResponseCacheState, ResponseCacheEntry } from './response-cache.reducer'; + +// describe('ResponseCacheService', () => { // let service: ResponseCacheService; // let store: Store; // -// const keys = ["125c17f89046283c5f0640722aac9feb", "a06c3006a41caec5d635af099b0c780c"]; +// const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; // const serviceTokens = [new OpaqueToken('service1'), new OpaqueToken('service2')]; -// const resourceID = "9978"; -// const paginationOptions = { "resultsPerPage": 10, "currentPage": 1 }; -// const sortOptions = { "field": "id", "direction": 0 }; +// const resourceID = '9978'; +// const paginationOptions = { 'resultsPerPage': 10, 'currentPage': 1 }; +// const sortOptions = { 'field': 'id', 'direction': 0 }; // const timestamp = new Date().getTime(); // const validCacheEntry = (key) => { // return { @@ -36,33 +37,33 @@ import { Observable } from "rxjs"; // spyOn(window, 'Date').and.returnValue({ getTime: () => timestamp }); // }); // -// describe("findAll", () => { +// describe('findAll', () => { // beforeEach(() => { -// spyOn(service, "get").and.callFake((key) => Observable.of({key: key})); +// spyOn(service, 'get').and.callFake((key) => Observable.of({key: key})); // }); -// describe("if the key isn't cached", () => { +// describe('if the key isn't cached', () => { // beforeEach(() => { -// spyOn(service, "has").and.returnValue(false); +// spyOn(service, 'has').and.returnValue(false); // }); -// it("should dispatch a FIND_ALL action with the key, service, scopeID, paginationOptions and sortOptions", () => { +// it('should dispatch a FIND_ALL action with the key, service, scopeID, paginationOptions and sortOptions', () => { // service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions); // expect(store.dispatch).toHaveBeenCalledWith(new ResponseCacheFindAllAction(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions)) // }); -// it("should return an observable of the newly cached request with the specified key", () => { +// it('should return an observable of the newly cached request with the specified key', () => { // let result: ResponseCacheEntry; // service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions).take(1).subscribe(entry => result = entry); // expect(result.key).toEqual(keys[0]); // }); // }); -// describe("if the key is already cached", () => { +// describe('if the key is already cached', () => { // beforeEach(() => { -// spyOn(service, "has").and.returnValue(true); +// spyOn(service, 'has').and.returnValue(true); // }); -// it("shouldn't dispatch anything", () => { +// it('shouldn't dispatch anything', () => { // service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions); // expect(store.dispatch).not.toHaveBeenCalled(); // }); -// it("should return an observable of the existing cached request with the specified key", () => { +// it('should return an observable of the existing cached request with the specified key', () => { // let result: ResponseCacheEntry; // service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions).take(1).subscribe(entry => result = entry); // expect(result.key).toEqual(keys[0]); @@ -70,33 +71,33 @@ import { Observable } from "rxjs"; // }); // }); // -// describe("findById", () => { +// describe('findById', () => { // beforeEach(() => { -// spyOn(service, "get").and.callFake((key) => Observable.of({key: key})); +// spyOn(service, 'get').and.callFake((key) => Observable.of({key: key})); // }); -// describe("if the key isn't cached", () => { +// describe('if the key isn't cached', () => { // beforeEach(() => { -// spyOn(service, "has").and.returnValue(false); +// spyOn(service, 'has').and.returnValue(false); // }); -// it("should dispatch a FIND_BY_ID action with the key, service, and resourceID", () => { +// it('should dispatch a FIND_BY_ID action with the key, service, and resourceID', () => { // service.findById(keys[0], serviceTokens[0], resourceID); // expect(store.dispatch).toHaveBeenCalledWith(new ResponseCacheFindByIDAction(keys[0], serviceTokens[0], resourceID)) // }); -// it("should return an observable of the newly cached request with the specified key", () => { +// it('should return an observable of the newly cached request with the specified key', () => { // let result: ResponseCacheEntry; // service.findById(keys[0], serviceTokens[0], resourceID).take(1).subscribe(entry => result = entry); // expect(result.key).toEqual(keys[0]); // }); // }); -// describe("if the key is already cached", () => { +// describe('if the key is already cached', () => { // beforeEach(() => { -// spyOn(service, "has").and.returnValue(true); +// spyOn(service, 'has').and.returnValue(true); // }); -// it("shouldn't dispatch anything", () => { +// it('shouldn't dispatch anything', () => { // service.findById(keys[0], serviceTokens[0], resourceID); // expect(store.dispatch).not.toHaveBeenCalled(); // }); -// it("should return an observable of the existing cached request with the specified key", () => { +// it('should return an observable of the existing cached request with the specified key', () => { // let result: ResponseCacheEntry; // service.findById(keys[0], serviceTokens[0], resourceID).take(1).subscribe(entry => result = entry); // expect(result.key).toEqual(keys[0]); @@ -104,9 +105,9 @@ import { Observable } from "rxjs"; // }); // }); // -// describe("get", () => { -// it("should return an observable of the cached request with the specified key", () => { -// spyOn(store, "select").and.callFake((...args:Array) => { +// describe('get', () => { +// it('should return an observable of the cached request with the specified key', () => { +// spyOn(store, 'select').and.callFake((...args:Array) => { // return Observable.of(validCacheEntry(args[args.length - 1])); // }); // @@ -115,8 +116,8 @@ import { Observable } from "rxjs"; // expect(testObj.key).toEqual(keys[1]); // }); // -// it("should not return a cached request that has exceeded its time to live", () => { -// spyOn(store, "select").and.callFake((...args:Array) => { +// it('should not return a cached request that has exceeded its time to live', () => { +// spyOn(store, 'select').and.callFake((...args:Array) => { // return Observable.of(invalidCacheEntry(args[args.length - 1])); // }); // @@ -127,18 +128,18 @@ import { Observable } from "rxjs"; // }); // }); // -// describe("has", () => { -// it("should return true if the request with the supplied key is cached and still valid", () => { +// describe('has', () => { +// it('should return true if the request with the supplied key is cached and still valid', () => { // spyOn(store, 'select').and.returnValue(Observable.of(validCacheEntry(keys[1]))); // expect(service.has(keys[1])).toBe(true); // }); // -// it("should return false if the request with the supplied key isn't cached", () => { +// it('should return false if the request with the supplied key isn't cached', () => { // spyOn(store, 'select').and.returnValue(Observable.of(undefined)); // expect(service.has(keys[1])).toBe(false); // }); // -// it("should return false if the request with the supplied key is cached but has exceeded its time to live", () => { +// it('should return false if the request with the supplied key is cached but has exceeded its time to live', () => { // spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry(keys[1]))); // expect(service.has(keys[1])).toBe(false); // }); diff --git a/src/app/core/cache/response-cache.service.ts b/src/app/core/cache/response-cache.service.ts index b821a35f34..99e26b3c20 100644 --- a/src/app/core/cache/response-cache.service.ts +++ b/src/app/core/cache/response-cache.service.ts @@ -1,15 +1,12 @@ -import { Injectable } from "@angular/core"; -import { Store } from "@ngrx/store"; -import { - ResponseCacheState, ResponseCacheEntry -} from "./response-cache.reducer"; -import { Observable } from "rxjs"; -import { hasNoValue } from "../../shared/empty.util"; -import { - ResponseCacheRemoveAction, - ResponseCacheAddAction -} from "./response-cache.actions"; -import { Response } from "./response-cache.models"; +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; + +import { Observable } from 'rxjs/Observable'; + +import { ResponseCacheState, ResponseCacheEntry } from './response-cache.reducer'; +import { hasNoValue } from '../../shared/empty.util'; +import { ResponseCacheRemoveAction, ResponseCacheAddAction } from './response-cache.actions'; +import { Response } from './response-cache.models'; /** * A service to interact with the response cache @@ -38,7 +35,7 @@ export class ResponseCacheService { */ get(key: string): Observable { return this.store.select('core', 'cache', 'response', key) - .filter(entry => this.isValid(entry)) + .filter((entry) => this.isValid(entry)) .distinctUntilChanged() } @@ -56,7 +53,7 @@ export class ResponseCacheService { this.store.select('core', 'cache', 'response', key) .take(1) - .subscribe(entry => { + .subscribe((entry) => { result = this.isValid(entry); }); @@ -75,8 +72,7 @@ export class ResponseCacheService { private isValid(entry: ResponseCacheEntry): boolean { if (hasNoValue(entry)) { return false; - } - else { + } else { const timeOutdated = entry.timeAdded + entry.msToLive; const isOutDated = new Date().getTime() > timeOutdated; if (isOutDated) { diff --git a/src/app/core/core.effects.ts b/src/app/core/core.effects.ts index ef9da245df..d3a4aed7d7 100644 --- a/src/app/core/core.effects.ts +++ b/src/app/core/core.effects.ts @@ -1,8 +1,9 @@ -import { EffectsModule } from "@ngrx/effects"; -import { ObjectCacheEffects } from "./data/object-cache.effects"; -import { RequestCacheEffects } from "./data/request-cache.effects"; -import { HrefIndexEffects } from "./index/href-index.effects"; -import { RequestEffects } from "./data/request.effects"; +import { EffectsModule } from '@ngrx/effects'; + +import { ObjectCacheEffects } from './data/object-cache.effects'; +import { RequestCacheEffects } from './data/request-cache.effects'; +import { HrefIndexEffects } from './index/href-index.effects'; +import { RequestEffects } from './data/request.effects'; export const coreEffects = [ EffectsModule.run(RequestEffects), diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 9bc9ca406d..9414293d72 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -1,18 +1,19 @@ import { NgModule, Optional, SkipSelf, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { SharedModule } from "../shared/shared.module"; -import { isNotEmpty } from "../shared/empty.util"; -import { FooterComponent } from "./footer/footer.component"; -import { DSpaceRESTv2Service } from "./dspace-rest-v2/dspace-rest-v2.service"; -import { ObjectCacheService } from "./cache/object-cache.service"; -import { ResponseCacheService } from "./cache/response-cache.service"; -import { CollectionDataService } from "./data/collection-data.service"; -import { ItemDataService } from "./data/item-data.service"; -import { RequestService } from "./data/request.service"; -import { RemoteDataBuildService } from "./cache/builders/remote-data-build.service"; -import { CommunityDataService } from "./data/community-data.service"; -import { PaginationComponentOptions } from "../shared/pagination/pagination-component-options.model"; +import { SharedModule } from '../shared/shared.module'; + +import { isNotEmpty } from '../shared/empty.util'; +import { FooterComponent } from './footer/footer.component'; +import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service'; +import { ObjectCacheService } from './cache/object-cache.service'; +import { ResponseCacheService } from './cache/response-cache.service'; +import { CollectionDataService } from './data/collection-data.service'; +import { ItemDataService } from './data/item-data.service'; +import { RequestService } from './data/request.service'; +import { RemoteDataBuildService } from './cache/builders/remote-data-build.service'; +import { CommunityDataService } from './data/community-data.service'; +import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; const IMPORTS = [ CommonModule, @@ -46,12 +47,6 @@ const PROVIDERS = [ providers: [...PROVIDERS] }) export class CoreModule { - constructor( @Optional() @SkipSelf() parentModule: CoreModule) { - if (isNotEmpty(parentModule)) { - throw new Error( - 'CoreModule is already loaded. Import it in the AppModule only'); - } - } static forRoot(): ModuleWithProviders { return { @@ -61,4 +56,11 @@ export class 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/core.reducers.ts b/src/app/core/core.reducers.ts index 556866dbc4..cc16c6b49d 100644 --- a/src/app/core/core.reducers.ts +++ b/src/app/core/core.reducers.ts @@ -1,7 +1,8 @@ -import { combineReducers } from "@ngrx/store"; -import { CacheState, cacheReducer } from "./cache/cache.reducers"; -import { IndexState, indexReducer } from "./index/index.reducers"; -import { DataState, dataReducer } from "./data/data.reducers"; +import { combineReducers } from '@ngrx/store'; + +import { CacheState, cacheReducer } from './cache/cache.reducers'; +import { IndexState, indexReducer } from './index/index.reducers'; +import { DataState, dataReducer } from './data/data.reducers'; export interface CoreState { cache: CacheState, diff --git a/src/app/core/data/collection-data.service.ts b/src/app/core/data/collection-data.service.ts index 446772c1fc..8e69827184 100644 --- a/src/app/core/data/collection-data.service.ts +++ b/src/app/core/data/collection-data.service.ts @@ -1,14 +1,15 @@ -import { Inject, Injectable } from "@angular/core"; -import { DataService } from "./data.service"; -import { Collection } from "../shared/collection.model"; -import { ObjectCacheService } from "../cache/object-cache.service"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { Store } from "@ngrx/store"; -import { NormalizedCollection } from "../cache/models/normalized-collection.model"; -import { CoreState } from "../core.reducers"; -import { RequestService } from "./request.service"; -import { RemoteDataBuildService } from "../cache/builders/remote-data-build.service"; -import { GLOBAL_CONFIG, GlobalConfig } from "../../../config"; +import { Inject, Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; + +import { DataService } from './data.service'; +import { Collection } from '../shared/collection.model'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { NormalizedCollection } from '../cache/models/normalized-collection.model'; +import { CoreState } from '../core.reducers'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; @Injectable() export class CollectionDataService extends DataService { diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index 996b17eab5..d749171e1f 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -1,14 +1,16 @@ -import { Inject, Injectable } from "@angular/core"; -import { DataService } from "./data.service"; -import { Community } from "../shared/community.model"; -import { ObjectCacheService } from "../cache/object-cache.service"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { Store } from "@ngrx/store"; -import { NormalizedCommunity } from "../cache/models/normalized-community.model"; -import { CoreState } from "../core.reducers"; -import { RequestService } from "./request.service"; -import { RemoteDataBuildService } from "../cache/builders/remote-data-build.service"; -import { GLOBAL_CONFIG, GlobalConfig } from "../../../config"; +import { Inject, Injectable } from '@angular/core'; + +import { Store } from '@ngrx/store'; + +import { DataService } from './data.service'; +import { Community } from '../shared/community.model'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { NormalizedCommunity } from '../cache/models/normalized-community.model'; +import { CoreState } from '../core.reducers'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; @Injectable() export class CommunityDataService extends DataService { diff --git a/src/app/core/data/data.reducers.ts b/src/app/core/data/data.reducers.ts index af7d2697cc..df151154cd 100644 --- a/src/app/core/data/data.reducers.ts +++ b/src/app/core/data/data.reducers.ts @@ -1,5 +1,6 @@ -import { combineReducers } from "@ngrx/store"; -import { RequestState, requestReducer } from "./request.reducer"; +import { combineReducers } from '@ngrx/store'; + +import { RequestState, requestReducer } from './request.reducer'; export interface DataState { request: RequestState diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 05e7066290..56aac053b0 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -1,18 +1,18 @@ -import { ObjectCacheService } from "../cache/object-cache.service"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { CacheableObject } from "../cache/object-cache.reducer"; -import { hasValue, isNotEmpty } from "../../shared/empty.util"; -import { RemoteData } from "./remote-data"; -import { FindAllOptions, FindAllRequest, FindByIDRequest, Request } from "./request.models"; -import { Store } from "@ngrx/store"; -import { RequestConfigureAction, RequestExecuteAction } from "./request.actions"; -import { CoreState } from "../core.reducers"; -import { RequestService } from "./request.service"; -import { RemoteDataBuildService } from "../cache/builders/remote-data-build.service"; -import { GenericConstructor } from "../shared/generic-constructor"; -import { Inject } from "@angular/core"; -import { GLOBAL_CONFIG, GlobalConfig } from "../../../config"; -import { RESTURLCombiner } from "../url-combiner/rest-url-combiner"; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { CacheableObject } from '../cache/object-cache.reducer'; +import { hasValue, isNotEmpty } from '../../shared/empty.util'; +import { RemoteData } from './remote-data'; +import { FindAllOptions, FindAllRequest, FindByIDRequest, Request } from './request.models'; +import { Store } from '@ngrx/store'; +import { RequestConfigureAction, RequestExecuteAction } from './request.actions'; +import { CoreState } from '../core.reducers'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { Inject } from '@angular/core'; +import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; +import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; export abstract class DataService { protected abstract objectCache: ObjectCacheService; @@ -32,17 +32,16 @@ export abstract class DataService protected getFindAllHref(options: FindAllOptions = {}): string { let result; - let args = []; + const args = []; if (hasValue(options.scopeID)) { result = this.browseEndpoint; args.push(`scope=${options.scopeID}`); - } - else { + } else { result = this.resourceEndpoint; } - if (hasValue(options.currentPage) && typeof options.currentPage === "number") { + if (hasValue(options.currentPage) && typeof options.currentPage === 'number') { /* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */ args.push(`page=${options.currentPage - 1}`); } @@ -65,7 +64,7 @@ export abstract class DataService return new RESTURLCombiner(this.EnvConfig, result).toString(); } - findAll(options: FindAllOptions = {}): RemoteData> { + findAll(options: FindAllOptions = {}): RemoteData { const href = this.getFindAllHref(options); const request = new FindAllRequest(href, options); this.requestService.configure(request); diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 628841b32c..f362e7538a 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -1,14 +1,16 @@ -import { Inject, Injectable } from "@angular/core"; -import { DataService } from "./data.service"; -import { Item } from "../shared/item.model"; -import { ObjectCacheService } from "../cache/object-cache.service"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { Store } from "@ngrx/store"; -import { CoreState } from "../core.reducers"; -import { NormalizedItem } from "../cache/models/normalized-item.model"; -import { RequestService } from "./request.service"; -import { RemoteDataBuildService } from "../cache/builders/remote-data-build.service"; -import { GLOBAL_CONFIG, GlobalConfig } from "../../../config"; +import { Inject, Injectable } from '@angular/core'; + +import { Store } from '@ngrx/store'; + +import { DataService } from './data.service'; +import { Item } from '../shared/item.model'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { CoreState } from '../core.reducers'; +import { NormalizedItem } from '../cache/models/normalized-item.model'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; @Injectable() export class ItemDataService extends DataService { diff --git a/src/app/core/data/object-cache.effects.ts b/src/app/core/data/object-cache.effects.ts index af5a0658a3..a0018d2b58 100644 --- a/src/app/core/data/object-cache.effects.ts +++ b/src/app/core/data/object-cache.effects.ts @@ -1,18 +1,15 @@ -import { Injectable } from "@angular/core"; -import { Actions, Effect } from "@ngrx/effects"; -import { StoreActionTypes } from "../../store.actions"; -import { ResetObjectCacheTimestampsAction } from "../cache/object-cache.actions"; +import { Injectable } from '@angular/core'; +import { Actions, Effect } from '@ngrx/effects'; + +import { StoreActionTypes } from '../../store.actions'; +import { ResetObjectCacheTimestampsAction } from '../cache/object-cache.actions'; @Injectable() export class ObjectCacheEffects { - constructor( - private actions$: Actions - ) { } - /** * When the store is rehydrated in the browser, set all cache - * timestamps to "now", because the time zone of the server can + * timestamps to 'now', because the time zone of the server can * differ from the client. * * This assumes that the server cached everything a negligible @@ -22,4 +19,6 @@ export class ObjectCacheEffects { .ofType(StoreActionTypes.REHYDRATE) .map(() => new ResetObjectCacheTimestampsAction(new Date().getTime())); + constructor(private actions$: Actions) { } + } diff --git a/src/app/core/data/remote-data.ts b/src/app/core/data/remote-data.ts index b78fe1b9af..b5c53b19e4 100644 --- a/src/app/core/data/remote-data.ts +++ b/src/app/core/data/remote-data.ts @@ -1,11 +1,12 @@ -import { Observable } from "rxjs"; -import { PageInfo } from "../shared/page-info.model"; +import { Observable } from 'rxjs/Observable'; + +import { PageInfo } from '../shared/page-info.model'; export enum RemoteDataState { - RequestPending = "RequestPending", - ResponsePending = "ResponsePending", - Failed = "Failed", - Success = "Success" + RequestPending = 'RequestPending' as any, + ResponsePending = 'ResponsePending' as any, + Failed = 'Failed' as any, + Success = 'Success' as any } /** @@ -32,14 +33,11 @@ export class RemoteData { (requestPending, responsePending, isSuccessFul) => { if (requestPending) { return RemoteDataState.RequestPending - } - else if (responsePending) { + } else if (responsePending) { return RemoteDataState.ResponsePending - } - else if (!isSuccessFul) { + } else if (!isSuccessFul) { return RemoteDataState.Failed - } - else { + } else { return RemoteDataState.Success } } @@ -47,36 +45,26 @@ export class RemoteData { } get isRequestPending(): Observable { - return this.state - .map(state => state == RemoteDataState.RequestPending) - .distinctUntilChanged(); + return this.state.map((state) => state === RemoteDataState.RequestPending).distinctUntilChanged(); } get isResponsePending(): Observable { - return this.state - .map(state => state == RemoteDataState.ResponsePending) - .distinctUntilChanged(); + return this.state.map((state) => state === RemoteDataState.ResponsePending).distinctUntilChanged(); } get isLoading(): Observable { - return this.state - .map(state => { - return state == RemoteDataState.RequestPending - || state === RemoteDataState.ResponsePending - }) - .distinctUntilChanged(); + return this.state.map((state) => { + return state === RemoteDataState.RequestPending + || state === RemoteDataState.ResponsePending + }).distinctUntilChanged(); } get hasFailed(): Observable { - return this.state - .map(state => state == RemoteDataState.Failed) - .distinctUntilChanged(); + return this.state.map((state) => state === RemoteDataState.Failed).distinctUntilChanged(); } get hasSucceeded(): Observable { - return this.state - .map(state => state == RemoteDataState.Success) - .distinctUntilChanged(); + return this.state.map((state) => state === RemoteDataState.Success).distinctUntilChanged(); } } diff --git a/src/app/core/data/request-cache.effects.ts b/src/app/core/data/request-cache.effects.ts index 77472d76b9..8ff41fb9f9 100644 --- a/src/app/core/data/request-cache.effects.ts +++ b/src/app/core/data/request-cache.effects.ts @@ -1,18 +1,15 @@ -import { Injectable, Inject } from "@angular/core"; -import { Actions, Effect } from "@ngrx/effects"; -import { ObjectCacheActionTypes } from "../cache/object-cache.actions"; -import { ResetResponseCacheTimestampsAction } from "../cache/response-cache.actions"; +import { Injectable, Inject } from '@angular/core'; +import { Actions, Effect } from '@ngrx/effects'; + +import { ObjectCacheActionTypes } from '../cache/object-cache.actions'; +import { ResetResponseCacheTimestampsAction } from '../cache/response-cache.actions'; @Injectable() export class RequestCacheEffects { - constructor( - private actions$: Actions, - ) { } - /** * When the store is rehydrated in the browser, set all cache - * timestamps to "now", because the time zone of the server can + * timestamps to 'now', because the time zone of the server can * differ from the client. * * This assumes that the server cached everything a negligible @@ -29,4 +26,7 @@ export class RequestCacheEffects { @Effect() fixTimestampsOnRehydrate = this.actions$ .ofType(ObjectCacheActionTypes.RESET_TIMESTAMPS) .map(() => new ResetResponseCacheTimestampsAction(new Date().getTime())); + + constructor(private actions$: Actions, ) { } + } diff --git a/src/app/core/data/request.actions.ts b/src/app/core/data/request.actions.ts index 16ce1963bd..9747294c2d 100644 --- a/src/app/core/data/request.actions.ts +++ b/src/app/core/data/request.actions.ts @@ -1,7 +1,7 @@ -import { Action } from "@ngrx/store"; -import { type } from "../../shared/ngrx/type"; -import { CacheableObject } from "../cache/object-cache.reducer"; -import { Request } from "./request.models"; +import { Action } from '@ngrx/store'; +import { type } from '../../shared/ngrx/type'; +import { CacheableObject } from '../cache/object-cache.reducer'; +import { Request } from './request.models'; /** * The list of RequestAction type definitions @@ -12,6 +12,7 @@ export const RequestActionTypes = { COMPLETE: type('dspace/core/data/request/COMPLETE') }; +/* tslint:disable:max-classes-per-file */ export class RequestConfigureAction implements Action { type = RequestActionTypes.CONFIGURE; payload: Request; @@ -49,6 +50,7 @@ export class RequestCompleteAction implements Action { this.payload = key; } } +/* tslint:enable:max-classes-per-file */ /** * A type to encompass all RequestActions diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index d35ea17c2c..df4205bf32 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -1,26 +1,27 @@ -import { Injectable, Inject } from "@angular/core"; -import { Actions, Effect } from "@ngrx/effects"; -import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service"; -import { ObjectCacheService } from "../cache/object-cache.service"; -import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model"; -import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.serializer"; -import { CacheableObject } from "../cache/object-cache.reducer"; -import { Observable } from "rxjs"; -import { Response, SuccessResponse, ErrorResponse } from "../cache/response-cache.models"; -import { hasNoValue, hasValue, isEmpty, isNotEmpty } from "../../shared/empty.util"; -import { GlobalConfig, GLOBAL_CONFIG } from "../../../config"; -import { RequestEntry } from "./request.reducer"; -import { - RequestActionTypes, RequestExecuteAction, - RequestCompleteAction -} from "./request.actions"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { RequestService } from "./request.service"; -import { NormalizedObjectFactory } from "../cache/models/normalized-object-factory"; -import { ResourceType } from "../shared/resource-type"; -import { RequestError } from "./request.models"; -import { PageInfo } from "../shared/page-info.model"; -import { NormalizedObject } from "../cache/models/normalized-object.model"; +import { Injectable, Inject } from '@angular/core'; +import { Actions, Effect } from '@ngrx/effects'; + +// tslint:disable-next-line:import-blacklist +import { Observable } from 'rxjs'; + +import { DSpaceRESTv2Service } from '../dspace-rest-v2/dspace-rest-v2.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model'; +import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; +import { CacheableObject } from '../cache/object-cache.reducer'; +import { Response, SuccessResponse, ErrorResponse } from '../cache/response-cache.models'; +import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { RequestEntry } from './request.reducer'; +import { RequestActionTypes, RequestExecuteAction, RequestCompleteAction } from './request.actions'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { RequestService } from './request.service'; +import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory'; +import { ResourceType } from '../shared/resource-type'; +import { RequestError } from './request.models'; +import { PageInfo } from '../shared/page-info.model'; +import { NormalizedObject } from '../cache/models/normalized-object.model'; + +import { GlobalConfig, GLOBAL_CONFIG } from '../../../config'; function isObjectLevel(halObj: any) { return isNotEmpty(halObj._links) && hasValue(halObj._links.self); @@ -38,23 +39,14 @@ function flattenSingleKeyObject(obj: any): any { return obj[keys[0]]; } +/* tslint:disable:max-classes-per-file */ class ProcessRequestDTO { [key: string]: NormalizedObject[] } - @Injectable() export class RequestEffects { - constructor( - @Inject(GLOBAL_CONFIG) private config: GlobalConfig, - private actions$: Actions, - private restApi: DSpaceRESTv2Service, - private objectCache: ObjectCacheService, - private responseCache: ResponseCacheService, - protected requestService: RequestService - ) { } - @Effect() execute = this.actions$ .ofType(RequestActionTypes.EXECUTE) .flatMap((action: RequestExecuteAction) => { @@ -65,48 +57,52 @@ export class RequestEffects { return this.restApi.get(entry.request.href) .map((data: DSpaceRESTV2Response) => { const processRequestDTO = this.process(data.payload, entry.request.href); - const uuids = flattenSingleKeyObject(processRequestDTO).map(no => no.uuid); + const uuids = flattenSingleKeyObject(processRequestDTO).map((no) => no.uuid); return new SuccessResponse(uuids, data.statusCode, this.processPageInfo(data.payload.page)) - }).do((response: Response) => this.responseCache.add(entry.request.href, response, this.config.cache.msToLive)) + }).do((response: Response) => this.responseCache.add(entry.request.href, response, this.EnvConfig.cache.msToLive)) .map((response: Response) => new RequestCompleteAction(entry.request.href)) .catch((error: RequestError) => Observable.of(new ErrorResponse(error)) - .do((response: Response) => this.responseCache.add(entry.request.href, response, this.config.cache.msToLive)) + .do((response: Response) => this.responseCache.add(entry.request.href, response, this.EnvConfig.cache.msToLive)) .map((response: Response) => new RequestCompleteAction(entry.request.href))); }); + constructor( + @Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig, + private actions$: Actions, + private restApi: DSpaceRESTv2Service, + private objectCache: ObjectCacheService, + private responseCache: ResponseCacheService, + protected requestService: RequestService + ) { } + protected process(data: any, requestHref: string): ProcessRequestDTO { if (isNotEmpty(data)) { if (isPaginatedResponse(data)) { return this.process(data._embedded, requestHref); - } - else if (isObjectLevel(data)) { - return { "topLevel": this.deserializeAndCache(data, requestHref) }; - } - else { - let result = new ProcessRequestDTO(); + } else if (isObjectLevel(data)) { + return { topLevel: this.deserializeAndCache(data, requestHref) }; + } else { + const result = new ProcessRequestDTO(); if (Array.isArray(data)) { - result['topLevel'] = []; - data.forEach(datum => { + result.topLevel = []; + data.forEach((datum) => { if (isPaginatedResponse(datum)) { const obj = this.process(datum, requestHref); - result['topLevel'] = [...result['topLevel'], ...flattenSingleKeyObject(obj)]; - } - else { - result['topLevel'] = [...result['topLevel'], ...this.deserializeAndCache(datum, requestHref)]; + result.topLevel = [...result.topLevel, ...flattenSingleKeyObject(obj)]; + } else { + result.topLevel = [...result.topLevel, ...this.deserializeAndCache(datum, requestHref)]; } }); - } - else { + } else { Object.keys(data) - .filter(property => data.hasOwnProperty(property)) - .filter(property => hasValue(data[property])) - .forEach(property => { + .filter((property) => data.hasOwnProperty(property)) + .filter((property) => hasValue(data[property])) + .forEach((property) => { if (isPaginatedResponse(data[property])) { const obj = this.process(data[property], requestHref); result[property] = flattenSingleKeyObject(obj); - } - else { + } else { result[property] = this.deserializeAndCache(data[property], requestHref); } }); @@ -119,11 +115,11 @@ export class RequestEffects { protected deserializeAndCache(obj, requestHref: string): NormalizedObject[] { if (Array.isArray(obj)) { let result = []; - obj.forEach(o => result = [...result, ...this.deserializeAndCache(o, requestHref)]) + obj.forEach((o) => result = [...result, ...this.deserializeAndCache(o, requestHref)]) return result; } - let type: ResourceType = obj["type"]; + const type: ResourceType = obj.type; if (hasValue(type)) { const normObjConstructor = NormalizedObjectFactory.getConstructor(type); @@ -134,11 +130,11 @@ export class RequestEffects { if (isNotEmpty(obj._embedded)) { processed = this.process(obj._embedded, requestHref); } - let normalizedObj = serializer.deserialize(obj); + const normalizedObj = serializer.deserialize(obj); if (isNotEmpty(processed)) { - let linksOnly = {}; - Object.keys(processed).forEach(key => { + const linksOnly = {}; + Object.keys(processed).forEach((key) => { linksOnly[key] = processed[key].map((no: NormalizedObject) => no.self); }); Object.assign(normalizedObj, linksOnly); @@ -147,16 +143,14 @@ export class RequestEffects { this.addToObjectCache(normalizedObj, requestHref); return [normalizedObj]; - } - else { - //TODO move check to Validator? + } else { + // TODO: move check to Validator? // throw new Error(`The server returned an object with an unknown a known type: ${type}`); return []; } - } - else { - //TODO move check to Validator + } else { + // TODO: move check to Validator // throw new Error(`The server returned an object without a type: ${JSON.stringify(obj)}`); return []; } @@ -166,16 +160,16 @@ export class RequestEffects { if (hasNoValue(co) || hasNoValue(co.uuid)) { throw new Error('The server returned an invalid object'); } - this.objectCache.add(co, this.config.cache.msToLive, requestHref); + this.objectCache.add(co, this.EnvConfig.cache.msToLive, requestHref); } protected processPageInfo(pageObj: any): PageInfo { if (isNotEmpty(pageObj)) { return new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj); - } - else { + } else { return undefined; } } } +/* tslint:enable:max-classes-per-file */ diff --git a/src/app/core/data/request.models.ts b/src/app/core/data/request.models.ts index 8fef310fad..47888a5e61 100644 --- a/src/app/core/data/request.models.ts +++ b/src/app/core/data/request.models.ts @@ -1,7 +1,8 @@ -import { SortOptions } from "../cache/models/sort-options.model"; -import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; -import { GenericConstructor } from "../shared/generic-constructor"; +import { SortOptions } from '../cache/models/sort-options.model'; +import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; +import { GenericConstructor } from '../shared/generic-constructor'; +/* tslint:disable:max-classes-per-file */ export class Request { constructor( public href: string, @@ -36,3 +37,4 @@ export class FindAllRequest extends Request { export class RequestError extends Error { statusText: string; } +/* tslint:enable:max-classes-per-file */ diff --git a/src/app/core/data/request.reducer.ts b/src/app/core/data/request.reducer.ts index 9548fff2af..77278d9a67 100644 --- a/src/app/core/data/request.reducer.ts +++ b/src/app/core/data/request.reducer.ts @@ -1,9 +1,9 @@ -import { CacheableObject } from "../cache/object-cache.reducer"; +import { CacheableObject } from '../cache/object-cache.reducer'; import { RequestActionTypes, RequestAction, RequestConfigureAction, RequestExecuteAction, RequestCompleteAction -} from "./request.actions"; -import { Request } from "./request.models"; +} from './request.actions'; +import { Request } from './request.models'; export class RequestEntry { request: Request; @@ -12,7 +12,6 @@ export class RequestEntry { completed: boolean; } - export interface RequestState { [key: string]: RequestEntry } @@ -24,15 +23,15 @@ export const requestReducer = (state = initialState, action: RequestAction): Req switch (action.type) { case RequestActionTypes.CONFIGURE: { - return configureRequest(state, action); + return configureRequest(state, action as RequestConfigureAction); } case RequestActionTypes.EXECUTE: { - return executeRequest(state, action); + return executeRequest(state, action as RequestExecuteAction); } case RequestActionTypes.COMPLETE: { - return completeRequest(state, action); + return completeRequest(state, action as RequestCompleteAction); } default: { diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 799d6f7675..08e0e66b96 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -1,16 +1,20 @@ -import { Injectable } from "@angular/core"; -import { RequestEntry, RequestState } from "./request.reducer"; -import { Store } from "@ngrx/store"; -import { Request } from "./request.models"; -import { hasValue } from "../../shared/empty.util"; -import { Observable } from "rxjs/Observable"; -import { RequestConfigureAction, RequestExecuteAction } from "./request.actions"; -import { ResponseCacheService } from "../cache/response-cache.service"; -import { ObjectCacheService } from "../cache/object-cache.service"; -import { CacheableObject } from "../cache/object-cache.reducer"; -import { ResponseCacheEntry } from "../cache/response-cache.reducer"; -import { request } from "http"; -import { SuccessResponse } from "../cache/response-cache.models"; +import { Injectable } from '@angular/core'; + +import { Store } from '@ngrx/store'; + +import { request } from 'http'; + +import { Observable } from 'rxjs/Observable'; + +import { RequestEntry, RequestState } from './request.reducer'; +import { Request } from './request.models'; +import { hasValue } from '../../shared/empty.util'; +import { RequestConfigureAction, RequestExecuteAction } from './request.actions'; +import { ResponseCacheService } from '../cache/response-cache.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { CacheableObject } from '../cache/object-cache.reducer'; +import { ResponseCacheEntry } from '../cache/response-cache.reducer'; +import { SuccessResponse } from '../cache/response-cache.models'; @Injectable() export class RequestService { @@ -41,14 +45,14 @@ export class RequestService { let isCached = this.objectCache.hasBySelfLink(request.href); if (!isCached && this.responseCache.has(request.href)) { - //if it isn't cached it may be a list endpoint, if so verify - //every object included in the response is still cached + // if it isn't cached it may be a list endpoint, if so verify + // every object included in the response is still cached this.responseCache.get(request.href) .take(1) .filter((entry: ResponseCacheEntry) => entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => (entry.response).resourceUUIDs) - .map((resourceUUIDs: Array) => resourceUUIDs.every(uuid => this.objectCache.has(uuid))) - .subscribe(c => isCached = c); + .map((entry: ResponseCacheEntry) => (entry.response as SuccessResponse).resourceUUIDs) + .map((resourceUUIDs: string[]) => resourceUUIDs.every((uuid) => this.objectCache.has(uuid))) + .subscribe((c) => isCached = c); } const isPending = this.isPending(request.href); diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts index 097717b5e2..8431d6f8b3 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts @@ -1,5 +1,6 @@ -import { DSpaceRESTv2Serializer } from "./dspace-rest-v2.serializer"; -import { autoserialize, autoserializeAs } from "cerialize"; +import { autoserialize, autoserializeAs } from 'cerialize'; + +import { DSpaceRESTv2Serializer } from './dspace-rest-v2.serializer'; class TestModel { @autoserialize @@ -9,55 +10,54 @@ class TestModel { name: string; @autoserializeAs(TestModel) - parents?: Array; + parents?: TestModel[]; } const testModels = [ { - "id": "d4466d54-d73b-4d8f-b73f-c702020baa14", - "name": "Model 1", + id: 'd4466d54-d73b-4d8f-b73f-c702020baa14', + name: 'Model 1', }, { - "id": "752a1250-949a-46ad-9bea-fbc45f0b656d", - "name": "Model 2", + id: '752a1250-949a-46ad-9bea-fbc45f0b656d', + name: 'Model 2', } ]; const testResponses = [ { - "_links": { - "self": "/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60", - "parents": [ - { "href": "/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78" }, - { "href": "/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5" } + _links: { + self: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60', + parents: [ + { href: '/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78' }, + { href: '/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5' } ] }, - "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60", - "type": "testModels", - "name": "A Test Model" + id: '9e32a2e2-6b91-4236-a361-995ccdc14c60', + type: 'testModels', + name: 'A Test Model' }, { - "_links": { - "self": "/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad", - "parents": [ - { "href": "/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5" }, - { "href": "/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78" } + _links: { + self: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad', + parents: [ + { href: '/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5' }, + { href: '/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78' } ] }, - "id": "598ce822-c357-46f3-ab70-63724d02d6ad", - "type": "testModels", - "name": "Another Test Model" + id: '598ce822-c357-46f3-ab70-63724d02d6ad', + type: 'testModels', + name: 'Another Test Model' } ]; const parentHrefRegex = /^\/testmodels\/(.+)$/g; +describe('DSpaceRESTv2Serializer', () => { -describe("DSpaceRESTv2Serializer", () => { + describe('serialize', () => { - describe("serialize", () => { - - it("should turn a model in to a valid document", () => { + it('should turn a model in to a valid document', () => { const serializer = new DSpaceRESTv2Serializer(TestModel); const doc = serializer.serialize(testModels[0]); expect(testModels[0].id).toBe(doc.id); @@ -66,9 +66,9 @@ describe("DSpaceRESTv2Serializer", () => { }); - describe("serializeArray", () => { + describe('serializeArray', () => { - it("should turn an array of models in to a valid document", () => { + it('should turn an array of models in to a valid document', () => { const serializer = new DSpaceRESTv2Serializer(TestModel); const doc = serializer.serializeArray(testModels); @@ -80,9 +80,9 @@ describe("DSpaceRESTv2Serializer", () => { }); - describe("deserialize", () => { + describe('deserialize', () => { - it("should turn a valid document describing a single entity in to a valid model", () => { + it('should turn a valid document describing a single entity in to a valid model', () => { const serializer = new DSpaceRESTv2Serializer(TestModel); const model = serializer.deserialize(testResponses[0]); @@ -90,12 +90,12 @@ describe("DSpaceRESTv2Serializer", () => { expect(model.name).toBe(testResponses[0].name); }); - //TODO cant implement/test this yet - depends on how relationships + // TODO: cant implement/test this yet - depends on how relationships // will be handled in the rest api - // it("should retain relationship information", () => { + // it('should retain relationship information', () => { // const serializer = new DSpaceRESTv2Serializer(TestModel); // const doc = { - // "_embedded": testResponses[0], + // '_embedded': testResponses[0], // }; // // const model = serializer.deserialize(doc); @@ -112,7 +112,7 @@ describe("DSpaceRESTv2Serializer", () => { // }); // TODO enable once validation is enabled in the serializer - // it("should throw an error when dealing with an invalid document", () => { + // it('should throw an error when dealing with an invalid document', () => { // const serializer = new DSpaceRESTv2Serializer(TestModel); // const doc = testResponses[0]; // @@ -121,7 +121,7 @@ describe("DSpaceRESTv2Serializer", () => { // }).toThrow(); // }); - it("should throw an error when dealing with a document describing an array", () => { + it('should throw an error when dealing with a document describing an array', () => { const serializer = new DSpaceRESTv2Serializer(TestModel); expect(() => { serializer.deserialize(testResponses); @@ -130,13 +130,13 @@ describe("DSpaceRESTv2Serializer", () => { }); - describe("deserializeArray", () => { + describe('deserializeArray', () => { - //TODO rewrite to incorporate normalisation. - // it("should turn a valid document describing a collection of objects in to an array of valid models", () => { + // TODO: rewrite to incorporate normalisation. + // it('should turn a valid document describing a collection of objects in to an array of valid models', () => { // const serializer = new DSpaceRESTv2Serializer(TestModel); // const doc = { - // "_embedded": testResponses + // '_embedded': testResponses // }; // // const models = serializer.deserializeArray(doc); @@ -147,12 +147,12 @@ describe("DSpaceRESTv2Serializer", () => { // expect(models[1].name).toBe(doc._embedded[1].name); // }); - //TODO cant implement/test this yet - depends on how relationships + // TODO: cant implement/test this yet - depends on how relationships // will be handled in the rest api - // it("should retain relationship information", () => { + // it('should retain relationship information', () => { // const serializer = new DSpaceRESTv2Serializer(TestModel); // const doc = { - // "_embedded": testResponses, + // '_embedded': testResponses, // }; // // const models = serializer.deserializeArray(doc); @@ -169,7 +169,7 @@ describe("DSpaceRESTv2Serializer", () => { // }); // TODO enable once validation is enabled in the serializer - // it("should throw an error when dealing with an invalid document", () => { + // it('should throw an error when dealing with an invalid document', () => { // const serializer = new DSpaceRESTv2Serializer(TestModel); // const doc = testResponses[0]; // @@ -178,10 +178,10 @@ describe("DSpaceRESTv2Serializer", () => { // }).toThrow(); // }); - it("should throw an error when dealing with a document describing a single model", () => { + it('should throw an error when dealing with a document describing a single model', () => { const serializer = new DSpaceRESTv2Serializer(TestModel); const doc = { - "_embedded": testResponses[0] + _embedded: testResponses[0] }; expect(() => { diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts index c0ce16a867..258edb116d 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts @@ -1,9 +1,10 @@ -import { Serialize, Deserialize } from "cerialize"; -import { Serializer } from "../serializer"; -import { DSpaceRESTV2Response } from "./dspace-rest-v2-response.model"; -import { DSpaceRESTv2Validator } from "./dspace-rest-v2.validator"; -import { GenericConstructor } from "../shared/generic-constructor"; -import { hasNoValue, hasValue } from "../../shared/empty.util"; +import { Serialize, Deserialize } from 'cerialize'; + +import { Serializer } from '../serializer'; +import { DSpaceRESTV2Response } from './dspace-rest-v2-response.model'; +import { DSpaceRESTv2Validator } from './dspace-rest-v2.validator'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { hasNoValue, hasValue } from '../../shared/empty.util'; /** * This Serializer turns responses from v2 of DSpace's REST API @@ -36,7 +37,7 @@ export class DSpaceRESTv2Serializer implements Serializer { * @param models The array of models to serialize * @returns An object to send to the backend */ - serializeArray(models: Array): any { + serializeArray(models: T[]): any { return Serialize(models, this.modelType); } @@ -52,8 +53,8 @@ export class DSpaceRESTv2Serializer implements Serializer { if (Array.isArray(response)) { throw new Error('Expected a single model, use deserializeArray() instead'); } - let normalized = Object.assign({}, response, this.normalizeLinks(response._links)); - return Deserialize(normalized, this.modelType); + const normalized = Object.assign({}, response, this.normalizeLinks(response._links)); + return Deserialize(normalized, this.modelType) as T; } /** @@ -62,28 +63,27 @@ export class DSpaceRESTv2Serializer implements Serializer { * @param response An object returned by the backend * @returns an array of models of type T */ - deserializeArray(response: any): Array { - //TODO enable validation, once rest data stabilizes + deserializeArray(response: any): T[] { + // TODO: enable validation, once rest data stabilizes // new DSpaceRESTv2Validator(response).validate(); if (!Array.isArray(response)) { throw new Error('Expected an Array, use deserialize() instead'); } - let normalized = response.map((resource) => { + const normalized = response.map((resource) => { return Object.assign({}, resource, this.normalizeLinks(resource._links)); }); - return >Deserialize(normalized, this.modelType); + return Deserialize(normalized, this.modelType) as T[]; } private normalizeLinks(links: any): any { - let normalizedLinks = links; - for (let link in normalizedLinks) { + const normalizedLinks = links; + for (const link in normalizedLinks) { if (Array.isArray(normalizedLinks[link])) { - normalizedLinks[link] = normalizedLinks[link].map(linkedResource => { + normalizedLinks[link] = normalizedLinks[link].map((linkedResource) => { return linkedResource.href; }); - } - else { + } else { normalizedLinks[link] = normalizedLinks[link].href; } } diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts index 400a5c851e..6464268201 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts @@ -1,16 +1,18 @@ import { Inject, Injectable } from '@angular/core'; import { Http, RequestOptionsArgs } from '@angular/http'; import { Observable } from 'rxjs/Observable'; -import { RESTURLCombiner } from "../url-combiner/rest-url-combiner"; + +import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; +import { DSpaceRESTV2Response } from './dspace-rest-v2-response.model'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; -import { DSpaceRESTV2Response } from "./dspace-rest-v2-response.model"; /** * Service to access DSpace's REST API */ @Injectable() export class DSpaceRESTv2Service { + constructor(private http: Http, @Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig) { } @@ -27,8 +29,8 @@ export class DSpaceRESTv2Service { */ get(absoluteURL: string, options?: RequestOptionsArgs): Observable { return this.http.get(absoluteURL, options) - .map(res => ({ payload: res.json(), statusCode: res.statusText })) - .catch(err => { + .map((res) => ({ payload: res.json(), statusCode: res.statusText })) + .catch((err) => { console.log('Error: ', err); return Observable.throw(err); }); diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.validator.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.validator.ts index c7e802aa93..c176b1eee3 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.validator.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.validator.ts @@ -1,5 +1,6 @@ +import { Validator } from 'jsonschema'; + import schema from './dspace-rest-v2.schema.json' -import { Validator } from "jsonschema"; /** * Verifies a document is a valid response from @@ -22,11 +23,10 @@ export class DSpaceRESTv2Validator { if (result.errors && result.errors.length > 0) { const message = result.errors .map((error) => error.message) - .join("\n"); + .join('\n'); throw new Error(message); - } - else { - throw new Error("JSON API validation failed for an unknown reason"); + } else { + throw new Error('JSON API validation failed for an unknown reason'); } } } diff --git a/src/app/core/footer/footer.component.spec.ts b/src/app/core/footer/footer.component.spec.ts index 6015104003..13debf504b 100644 --- a/src/app/core/footer/footer.component.spec.ts +++ b/src/app/core/footer/footer.component.spec.ts @@ -5,19 +5,23 @@ import { inject, TestBed } from '@angular/core/testing'; + import { CUSTOM_ELEMENTS_SCHEMA, DebugElement -} from "@angular/core"; +} from '@angular/core'; + +import { CommonModule } from '@angular/common'; + import { By } from '@angular/platform-browser'; -import { TranslateModule, TranslateLoader } from "@ngx-translate/core"; -import { Store, StoreModule } from "@ngrx/store"; + +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { Store, StoreModule } from '@ngrx/store'; // Load the implementations that should be tested import { FooterComponent } from './footer.component'; -import { CommonModule } from '@angular/common'; -import { MockTranslateLoader } from "../../shared/testing/mock-translate-loader"; +import { MockTranslateLoader } from '../../shared/testing/mock-translate-loader'; let comp: FooterComponent; let fixture: ComponentFixture; diff --git a/src/app/core/footer/footer.component.ts b/src/app/core/footer/footer.component.ts index 5caf5a92c2..94b239d204 100644 --- a/src/app/core/footer/footer.component.ts +++ b/src/app/core/footer/footer.component.ts @@ -1,18 +1,12 @@ -import { Component, OnInit } from "@angular/core"; +import { Component } from '@angular/core'; @Component({ selector: 'ds-footer', styleUrls: ['footer.component.scss'], templateUrl: 'footer.component.html' }) -export class FooterComponent implements OnInit { +export class FooterComponent { dateObj: number = Date.now(); - constructor() { - } - - ngOnInit(): void { - } - } diff --git a/src/app/core/index/href-index.actions.ts b/src/app/core/index/href-index.actions.ts index 8c00f2d96c..bf854abff7 100644 --- a/src/app/core/index/href-index.actions.ts +++ b/src/app/core/index/href-index.actions.ts @@ -1,5 +1,6 @@ -import { Action } from "@ngrx/store"; -import { type } from "../../shared/ngrx/type"; +import { Action } from '@ngrx/store'; + +import { type } from '../../shared/ngrx/type'; /** * The list of HrefIndexAction type definitions @@ -9,6 +10,7 @@ export const HrefIndexActionTypes = { REMOVE_UUID: type('dspace/core/index/href/REMOVE_UUID') }; +/* tslint:disable:max-classes-per-file */ /** * An ngrx action to add an href to the index */ @@ -48,11 +50,11 @@ export class RemoveUUIDFromHrefIndexAction implements Action { constructor(uuid: string) { this.payload = uuid; } + } +/* tslint:enable:max-classes-per-file */ /** * A type to encompass all HrefIndexActions */ -export type HrefIndexAction - = AddToHrefIndexAction - | RemoveUUIDFromHrefIndexAction; +export type HrefIndexAction = AddToHrefIndexAction | RemoveUUIDFromHrefIndexAction; diff --git a/src/app/core/index/href-index.effects.ts b/src/app/core/index/href-index.effects.ts index 2e1c8ae8d1..f7a4ad5d91 100644 --- a/src/app/core/index/href-index.effects.ts +++ b/src/app/core/index/href-index.effects.ts @@ -1,19 +1,16 @@ -import { Injectable } from "@angular/core"; -import { Effect, Actions } from "@ngrx/effects"; +import { Injectable } from '@angular/core'; +import { Effect, Actions } from '@ngrx/effects'; + import { ObjectCacheActionTypes, AddToObjectCacheAction, RemoveFromObjectCacheAction -} from "../cache/object-cache.actions"; -import { AddToHrefIndexAction, RemoveUUIDFromHrefIndexAction } from "./href-index.actions"; -import { hasValue } from "../../shared/empty.util"; +} from '../cache/object-cache.actions'; +import { AddToHrefIndexAction, RemoveUUIDFromHrefIndexAction } from './href-index.actions'; +import { hasValue } from '../../shared/empty.util'; @Injectable() export class HrefIndexEffects { - constructor( - private actions$: Actions - ) { } - @Effect() add$ = this.actions$ .ofType(ObjectCacheActionTypes.ADD) .filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.self)) @@ -29,4 +26,9 @@ export class HrefIndexEffects { .map((action: RemoveFromObjectCacheAction) => { return new RemoveUUIDFromHrefIndexAction(action.payload); }); + + constructor(private actions$: Actions) { + + } + } diff --git a/src/app/core/index/href-index.reducer.ts b/src/app/core/index/href-index.reducer.ts index 8cb46566df..639163fab0 100644 --- a/src/app/core/index/href-index.reducer.ts +++ b/src/app/core/index/href-index.reducer.ts @@ -1,7 +1,10 @@ import { - HrefIndexAction, HrefIndexActionTypes, AddToHrefIndexAction, + HrefIndexAction, + HrefIndexActionTypes, + AddToHrefIndexAction, RemoveUUIDFromHrefIndexAction -} from "./href-index.actions"; +} from './href-index.actions'; + export interface HrefIndexState { [href: string]: string } @@ -13,11 +16,11 @@ export const hrefIndexReducer = (state = initialState, action: HrefIndexAction): switch (action.type) { case HrefIndexActionTypes.ADD: { - return addToHrefIndex(state, action); + return addToHrefIndex(state, action as AddToHrefIndexAction); } case HrefIndexActionTypes.REMOVE_UUID: { - return removeUUIDFromHrefIndex(state, action) + return removeUUIDFromHrefIndex(state, action as RemoveUUIDFromHrefIndexAction) } default: { @@ -33,8 +36,8 @@ function addToHrefIndex(state: HrefIndexState, action: AddToHrefIndexAction): Hr } function removeUUIDFromHrefIndex(state: HrefIndexState, action: RemoveUUIDFromHrefIndexAction): HrefIndexState { - let newState = Object.create(null); - for (let href in state) { + const newState = Object.create(null); + for (const href in state) { if (state[href] !== action.payload) { newState[href] = state[href]; } diff --git a/src/app/core/index/index.reducers.ts b/src/app/core/index/index.reducers.ts index e7e3d7218a..d8e9d9e17f 100644 --- a/src/app/core/index/index.reducers.ts +++ b/src/app/core/index/index.reducers.ts @@ -1,5 +1,6 @@ -import { combineReducers } from "@ngrx/store"; -import { HrefIndexState, hrefIndexReducer } from "./href-index.reducer"; +import { combineReducers } from '@ngrx/store'; + +import { HrefIndexState, hrefIndexReducer } from './href-index.reducer'; export interface IndexState { href: HrefIndexState diff --git a/src/app/core/serializer.ts b/src/app/core/serializer.ts index 27cdb38577..eb194685cd 100644 --- a/src/app/core/serializer.ts +++ b/src/app/core/serializer.ts @@ -18,7 +18,7 @@ export interface Serializer { * @param models The array of models to serialize * @returns An object to send to the backend */ - serializeArray(models: Array): any; + serializeArray(models: T[]): any; /** * Convert a response from the backend in to a model. @@ -34,5 +34,5 @@ export interface Serializer { * @param response An object returned by the backend * @returns an array of models of type T */ - deserializeArray(response: any): Array; + deserializeArray(response: any): T[]; } diff --git a/src/app/core/shared/bitstream.model.ts b/src/app/core/shared/bitstream.model.ts index 8e7f6204a3..b6453206f0 100644 --- a/src/app/core/shared/bitstream.model.ts +++ b/src/app/core/shared/bitstream.model.ts @@ -1,6 +1,6 @@ -import { DSpaceObject } from "./dspace-object.model"; -import { RemoteData } from "../data/remote-data"; -import { Item } from "./item.model"; +import { DSpaceObject } from './dspace-object.model'; +import { RemoteData } from '../data/remote-data'; +import { Item } from './item.model'; export class Bitstream extends DSpaceObject { diff --git a/src/app/core/shared/bundle.model.ts b/src/app/core/shared/bundle.model.ts index 9d8e3855b8..798b7c402c 100644 --- a/src/app/core/shared/bundle.model.ts +++ b/src/app/core/shared/bundle.model.ts @@ -1,7 +1,7 @@ -import { DSpaceObject } from "./dspace-object.model"; -import { Bitstream } from "./bitstream.model"; -import { Item } from "./item.model"; -import { RemoteData } from "../data/remote-data"; +import { DSpaceObject } from './dspace-object.model'; +import { Bitstream } from './bitstream.model'; +import { Item } from './item.model'; +import { RemoteData } from '../data/remote-data'; export class Bundle extends DSpaceObject { /** diff --git a/src/app/core/shared/collection.model.ts b/src/app/core/shared/collection.model.ts index 43d5ff523c..207837ef04 100644 --- a/src/app/core/shared/collection.model.ts +++ b/src/app/core/shared/collection.model.ts @@ -1,7 +1,7 @@ -import { DSpaceObject } from "./dspace-object.model"; -import { Bitstream } from "./bitstream.model"; -import { Item } from "./item.model"; -import { RemoteData } from "../data/remote-data"; +import { DSpaceObject } from './dspace-object.model'; +import { Bitstream } from './bitstream.model'; +import { Item } from './item.model'; +import { RemoteData } from '../data/remote-data'; export class Collection extends DSpaceObject { @@ -15,7 +15,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description */ get introductoryText(): string { - return this.findMetadata("dc.description"); + return this.findMetadata('dc.description'); } /** @@ -23,7 +23,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description.abstract */ get shortDescription(): string { - return this.findMetadata("dc.description.abstract"); + return this.findMetadata('dc.description.abstract'); } /** @@ -31,7 +31,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.rights */ get copyrightText(): string { - return this.findMetadata("dc.rights"); + return this.findMetadata('dc.rights'); } /** @@ -39,7 +39,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.rights.license */ get license(): string { - return this.findMetadata("dc.rights.license"); + return this.findMetadata('dc.rights.license'); } /** @@ -47,7 +47,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description.tableofcontents */ get sidebarText(): string { - return this.findMetadata("dc.description.tableofcontents"); + return this.findMetadata('dc.description.tableofcontents'); } /** diff --git a/src/app/core/shared/community.model.ts b/src/app/core/shared/community.model.ts index bd82c2e05f..afe9fd734e 100644 --- a/src/app/core/shared/community.model.ts +++ b/src/app/core/shared/community.model.ts @@ -1,7 +1,7 @@ -import { DSpaceObject } from "./dspace-object.model"; -import { Bitstream } from "./bitstream.model"; -import { Collection } from "./collection.model"; -import { RemoteData } from "../data/remote-data"; +import { DSpaceObject } from './dspace-object.model'; +import { Bitstream } from './bitstream.model'; +import { Collection } from './collection.model'; +import { RemoteData } from '../data/remote-data'; export class Community extends DSpaceObject { @@ -15,7 +15,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description */ get introductoryText(): string { - return this.findMetadata("dc.description"); + return this.findMetadata('dc.description'); } /** @@ -23,7 +23,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description.abstract */ get shortDescription(): string { - return this.findMetadata("dc.description.abstract"); + return this.findMetadata('dc.description.abstract'); } /** @@ -31,7 +31,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.rights */ get copyrightText(): string { - return this.findMetadata("dc.rights"); + return this.findMetadata('dc.rights'); } /** @@ -39,7 +39,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description.tableofcontents */ get sidebarText(): string { - return this.findMetadata("dc.description.tableofcontents"); + return this.findMetadata('dc.description.tableofcontents'); } /** diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 25fac17fa6..ad3c2dac8c 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -1,8 +1,8 @@ -import { Metadatum } from "./metadatum.model" -import { isEmpty, isNotEmpty } from "../../shared/empty.util"; -import { CacheableObject } from "../cache/object-cache.reducer"; -import { RemoteData } from "../data/remote-data"; -import { ResourceType } from "./resource-type"; +import { Metadatum } from './metadatum.model' +import { isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { CacheableObject } from '../cache/object-cache.reducer'; +import { RemoteData } from '../data/remote-data'; +import { ResourceType } from './resource-type'; /** * An abstract model class for a DSpaceObject. @@ -34,7 +34,7 @@ export abstract class DSpaceObject implements CacheableObject { /** * An array containing all metadata of this DSpaceObject */ - metadata: Array; + metadata: Metadatum[]; /** * An array of DSpaceObjects that are direct parents of this DSpaceObject @@ -58,15 +58,12 @@ export abstract class DSpaceObject implements CacheableObject { * @return string */ findMetadata(key: string, language?: string): string { - const metadatum = this.metadata - .find((metadatum: Metadatum) => { - return metadatum.key === key && - (isEmpty(language) || metadatum.language === language) - }); + const metadatum = this.metadata.find((m: Metadatum) => { + return m.key === key && (isEmpty(language) || m.language === language) + }); if (isNotEmpty(metadatum)) { return metadatum.value; - } - else { + } else { return undefined; } } @@ -81,10 +78,10 @@ export abstract class DSpaceObject implements CacheableObject { * @param key(s) * @return Array */ - filterMetadata(keys: string[]): Array { - return this.metadata - .filter((metadatum: Metadatum) => { - return keys.some(key => key === metadatum.key); - }); + filterMetadata(keys: string[]): Metadatum[] { + return this.metadata.filter((metadatum: Metadatum) => { + return keys.some((key) => key === metadatum.key); + }); } + } diff --git a/src/app/core/shared/generic-constructor.ts b/src/app/core/shared/generic-constructor.ts index e6124011aa..095fbfcb7a 100644 --- a/src/app/core/shared/generic-constructor.ts +++ b/src/app/core/shared/generic-constructor.ts @@ -3,4 +3,6 @@ * more details: * https://github.com/Microsoft/TypeScript/issues/204#issuecomment-257722306 */ -export type GenericConstructor = { new (...args: any[]): T }; +/* tslint:disable:interface-over-type-literal */ +export type GenericConstructor = { new(...args: any[]): T }; +/* tslint:enable:interface-over-type-literal */ diff --git a/src/app/core/shared/item.model.spec.ts b/src/app/core/shared/item.model.spec.ts index c16347ce39..610c3c812c 100644 --- a/src/app/core/shared/item.model.spec.ts +++ b/src/app/core/shared/item.model.spec.ts @@ -1,22 +1,21 @@ -import { Item } from "./item.model"; -import { Observable } from "rxjs"; -import { RemoteData } from "../data/remote-data"; -import { Bitstream } from "./bitstream.model"; -import { isEmpty } from "../../shared/empty.util"; -import { PageInfo } from "./page-info.model"; +import { Observable } from 'rxjs/Observable'; +import { Item } from './item.model'; +import { RemoteData } from '../data/remote-data'; +import { Bitstream } from './bitstream.model'; +import { isEmpty } from '../../shared/empty.util'; +import { PageInfo } from './page-info.model'; describe('Item', () => { - let item: Item; - const thumbnailBundleName = "THUMBNAIL"; - const originalBundleName = "ORIGINAL"; - const thumbnailPath = "thumbnail.jpg"; - const bitstream1Path = "document.pdf"; - const bitstream2Path = "otherfile.doc"; + const thumbnailBundleName = 'THUMBNAIL'; + const originalBundleName = 'ORIGINAL'; + const thumbnailPath = 'thumbnail.jpg'; + const bitstream1Path = 'document.pdf'; + const bitstream2Path = 'otherfile.doc'; - const nonExistingBundleName = "c1e568f7-d14e-496b-bdd7-07026998cc00"; + const nonExistingBundleName = 'c1e568f7-d14e-496b-bdd7-07026998cc00'; let bitstreams; let remoteDataThumbnail; let remoteDataFiles; @@ -30,14 +29,13 @@ describe('Item', () => { bitstreams = [{ retrieve: bitstream1Path }, { - retrieve: bitstream2Path - }]; + retrieve: bitstream2Path + }]; remoteDataThumbnail = createRemoteDataObject(thumbnail); remoteDataFiles = createRemoteDataObject(bitstreams); remoteDataAll = createRemoteDataObject([...bitstreams, thumbnail]); - // Create Bundles const bundles = @@ -52,51 +50,47 @@ describe('Item', () => { bitstreams: remoteDataFiles }]; - item = Object.assign(new Item(), { bitstreams: remoteDataAll }); }); - it('should return the bitstreams related to this item with the specified bundle name', () => { const bitObs: Observable = item.getBitstreamsByBundleName(thumbnailBundleName); - bitObs.take(1).subscribe(bs => - expect(bs.every(b => b.name === thumbnailBundleName)).toBeTruthy()); + bitObs.take(1).subscribe((bs) => + expect(bs.every((b) => b.name === thumbnailBundleName)).toBeTruthy()); }); it('should return an empty array when no bitstreams with this bundleName exist for this item', () => { - const bitstreams: Observable = item.getBitstreamsByBundleName(nonExistingBundleName); - bitstreams.take(1).subscribe(bs => expect(isEmpty(bs)).toBeTruthy()); + const bs: Observable = item.getBitstreamsByBundleName(nonExistingBundleName); + bs.take(1).subscribe((b) => expect(isEmpty(b)).toBeTruthy()); }); - - describe("get thumbnail", () => { + describe('get thumbnail', () => { beforeEach(() => { spyOn(item, 'getBitstreamsByBundleName').and.returnValue(Observable.of([remoteDataThumbnail])); }); it('should return the thumbnail of this item', () => { - let path: string = thumbnailPath; - let bitstream: Observable = item.getThumbnail(); - bitstream.map(b => expect(b.retrieve).toBe(path)); + const path: string = thumbnailPath; + const bitstream: Observable = item.getThumbnail(); + bitstream.map((b) => expect(b.retrieve).toBe(path)); }); }); - - describe("get files", () => { + describe('get files', () => { beforeEach(() => { spyOn(item, 'getBitstreamsByBundleName').and.returnValue(Observable.of(bitstreams)); }); - it('should return all bitstreams with "ORIGINAL" as bundleName', () => { - let paths = [bitstream1Path, bitstream2Path]; + it("should return all bitstreams with 'ORIGINAL' as bundleName", () => { + const paths = [bitstream1Path, bitstream2Path]; - let files: Observable = item.getFiles(); + const files: Observable = item.getFiles(); let index = 0; - files.map(f => expect(f.length).toBe(2)); + files.map((f) => expect(f.length).toBe(2)); files.subscribe( - array => array.forEach( - file => { + (array) => array.forEach( + (file) => { expect(file.retrieve).toBe(paths[index]); index++; } @@ -106,16 +100,15 @@ describe('Item', () => { }); - }); -function createRemoteDataObject(object: Object) { - const self = ""; +function createRemoteDataObject(object: any) { + const self = ''; const requestPending = Observable.of(false); const responsePending = Observable.of(false); const isSuccessful = Observable.of(true); const errorMessage = Observable.of(undefined); - const statusCode = Observable.of("200"); + const statusCode = Observable.of('200'); const pageInfo = Observable.of(new PageInfo()); const payload = Observable.of(object); return new RemoteData( diff --git a/src/app/core/shared/item.model.ts b/src/app/core/shared/item.model.ts index 5ebcb79a7f..16cce9b610 100644 --- a/src/app/core/shared/item.model.ts +++ b/src/app/core/shared/item.model.ts @@ -1,9 +1,10 @@ -import { DSpaceObject } from "./dspace-object.model"; -import { Collection } from "./collection.model"; -import { RemoteData } from "../data/remote-data"; -import { Bitstream } from "./bitstream.model"; -import { Observable } from "rxjs"; -import { isNotEmpty } from "../../shared/empty.util"; +import { Observable } from 'rxjs/Observable'; + +import { DSpaceObject } from './dspace-object.model'; +import { Collection } from './collection.model'; +import { RemoteData } from '../data/remote-data'; +import { Bitstream } from './bitstream.model'; +import { isNotEmpty } from '../../shared/empty.util'; export class Item extends DSpaceObject { @@ -48,38 +49,36 @@ export class Item extends DSpaceObject { bitstreams: RemoteData; - /** * Retrieves the thumbnail of this item - * @returns {Observable} the primaryBitstream of the "THUMBNAIL" bundle + * @returns {Observable} the primaryBitstream of the 'THUMBNAIL' bundle */ getThumbnail(): Observable { - //TODO currently this just picks the first thumbnail - //should be adjusted when we have a way to determine - //the primary thumbnail from rest - return this.getBitstreamsByBundleName("THUMBNAIL") - .filter(thumbnails => isNotEmpty(thumbnails)) - .map(thumbnails => thumbnails[0]) + // TODO: currently this just picks the first thumbnail + // should be adjusted when we have a way to determine + // the primary thumbnail from rest + return this.getBitstreamsByBundleName('THUMBNAIL') + .filter((thumbnails) => isNotEmpty(thumbnails)) + .map((thumbnails) => thumbnails[0]) } /** * Retrieves the thumbnail for the given original of this item - * @returns {Observable} the primaryBitstream of the "THUMBNAIL" bundle + * @returns {Observable} the primaryBitstream of the 'THUMBNAIL' bundle */ getThumbnailForOriginal(original: Bitstream): Observable { - return this.getBitstreamsByBundleName("THUMBNAIL").map(files => files - .find(thumbnail => thumbnail - .name.startsWith(original.name) - ) - ).startWith(undefined); + return this.getBitstreamsByBundleName('THUMBNAIL') + .map((files) => { + return files.find((thumbnail) => thumbnail.name.startsWith(original.name)) + }).startWith(undefined); } /** * Retrieves all files that should be displayed on the item page of this item - * @returns {Observable>>} an array of all Bitstreams in the "ORIGINAL" bundle + * @returns {Observable>>} an array of all Bitstreams in the 'ORIGINAL' bundle */ getFiles(): Observable { - return this.getBitstreamsByBundleName("ORIGINAL"); + return this.getBitstreamsByBundleName('ORIGINAL'); } /** @@ -89,9 +88,9 @@ export class Item extends DSpaceObject { */ getBitstreamsByBundleName(bundleName: string): Observable { return this.bitstreams.payload.startWith([]) - .map(bitstreams => bitstreams - .filter(bitstream => bitstream.bundleName === bundleName) - ); + .map((bitstreams) => { + return bitstreams.filter((bitstream) => bitstream.bundleName === bundleName) + }); } } diff --git a/src/app/core/shared/metadatum.model.ts b/src/app/core/shared/metadatum.model.ts index b2f6c804a2..a3c5830608 100644 --- a/src/app/core/shared/metadatum.model.ts +++ b/src/app/core/shared/metadatum.model.ts @@ -1,4 +1,5 @@ -import { autoserialize } from "cerialize"; +import { autoserialize } from 'cerialize'; + export class Metadatum { /** @@ -18,4 +19,5 @@ export class Metadatum { */ @autoserialize value: string; + } diff --git a/src/app/core/shared/page-info.model.ts b/src/app/core/shared/page-info.model.ts index b911c8b276..0cb5cac5b1 100644 --- a/src/app/core/shared/page-info.model.ts +++ b/src/app/core/shared/page-info.model.ts @@ -1,4 +1,4 @@ -import { autoserialize, autoserializeAs } from "cerialize"; +import { autoserialize, autoserializeAs } from 'cerialize'; /** * Represents the state of a paginated response @@ -27,4 +27,5 @@ export class PageInfo { */ @autoserializeAs(Number, 'number') currentPage: number; + } diff --git a/src/app/core/shared/resource-type.ts b/src/app/core/shared/resource-type.ts index 96edb34c19..15e707b016 100644 --- a/src/app/core/shared/resource-type.ts +++ b/src/app/core/shared/resource-type.ts @@ -3,10 +3,10 @@ * https://github.com/Microsoft/TypeScript/pull/15486 */ export enum ResourceType { - Bundle = "bundle", - Bitstream = "bitstream", - BitstreamFormat = "bitstreamformat", - Item = "item", - Collection = "collection", - Community = "community" + Bundle = 'bundle' as any, + Bitstream = 'bitstream' as any, + BitstreamFormat = 'bitstreamformat' as any, + Item = 'item' as any, + Collection = 'collection' as any, + Community = 'community' as any, } diff --git a/src/app/core/url-combiner/rest-url-combiner.ts b/src/app/core/url-combiner/rest-url-combiner.ts index afbd25020a..0169115356 100644 --- a/src/app/core/url-combiner/rest-url-combiner.ts +++ b/src/app/core/url-combiner/rest-url-combiner.ts @@ -1,4 +1,4 @@ -import { URLCombiner } from "./url-combiner"; +import { URLCombiner } from './url-combiner'; import { GlobalConfig } from '../../../config'; @@ -9,7 +9,7 @@ import { GlobalConfig } from '../../../config'; * TODO write tests once GlobalConfig becomes injectable */ export class RESTURLCombiner extends URLCombiner { - constructor(EnvConfig: GlobalConfig, ...parts: Array) { + constructor(EnvConfig: GlobalConfig, ...parts: string[]) { super(EnvConfig.rest.baseUrl, EnvConfig.rest.nameSpace, ...parts); } } diff --git a/src/app/core/url-combiner/ui-url-combiner.ts b/src/app/core/url-combiner/ui-url-combiner.ts index 27f29d89f1..415f19ce28 100644 --- a/src/app/core/url-combiner/ui-url-combiner.ts +++ b/src/app/core/url-combiner/ui-url-combiner.ts @@ -1,5 +1,5 @@ -import { URLCombiner } from "./url-combiner"; -import { GlobalConfig } from "../../../config"; +import { URLCombiner } from './url-combiner'; +import { GlobalConfig } from '../../../config'; /** * Combines a variable number of strings representing parts @@ -8,7 +8,7 @@ import { GlobalConfig } from "../../../config"; * TODO write tests once GlobalConfig becomes injectable */ export class UIURLCombiner extends URLCombiner { - constructor(EnvConfig: GlobalConfig, ...parts: Array) { + constructor(EnvConfig: GlobalConfig, ...parts: string[]) { super(EnvConfig.ui.baseUrl, EnvConfig.ui.nameSpace, ...parts); } } diff --git a/src/app/core/url-combiner/url-combiner.spec.ts b/src/app/core/url-combiner/url-combiner.spec.ts index eb94d3a20f..9689f04e10 100644 --- a/src/app/core/url-combiner/url-combiner.spec.ts +++ b/src/app/core/url-combiner/url-combiner.spec.ts @@ -1,23 +1,23 @@ -import { URLCombiner } from "./url-combiner"; +import { URLCombiner } from './url-combiner'; -describe("URLCombiner", () => { +describe('URLCombiner', () => { - it("should return a valid URL when created with a valid set of url parts", () => { + it('should return a valid URL when created with a valid set of url parts', () => { const url = new URLCombiner('http://foo.com', 'bar', 'id', '5').toString(); expect(url).toBe('http://foo.com/bar/id/5'); }); - it("should return a URL with the protocol followed by two slashes", () => { + it('should return a URL with the protocol followed by two slashes', () => { const url = new URLCombiner('http:/foo.com').toString(); expect(url).toBe('http://foo.com'); }); - it("should return a URL with a single slash between each part", () => { + it('should return a URL with a single slash between each part', () => { const url = new URLCombiner('http://foo.com/', '/bar/', '//id', '///5').toString(); expect(url).toBe('http://foo.com/bar/id/5'); }); - it("should return a URL without a trailing slash before its parameters", () => { + it('should return a URL without a trailing slash before its parameters', () => { const url1 = new URLCombiner('http://foo.com/', '?bar=25').toString(); const url2 = new URLCombiner('http://foo.com/', '#bar').toString(); @@ -25,7 +25,7 @@ describe("URLCombiner", () => { expect(url2).toBe('http://foo.com#bar'); }); - it("should return an empty string when created without url parts", () => { + it('should return an empty string when created without url parts', () => { const url = new URLCombiner().toString(); expect(url).toBe(''); }); diff --git a/src/app/core/url-combiner/url-combiner.ts b/src/app/core/url-combiner/url-combiner.ts index 2dd6ecdb28..ae622ab976 100644 --- a/src/app/core/url-combiner/url-combiner.ts +++ b/src/app/core/url-combiner/url-combiner.ts @@ -1,11 +1,11 @@ -import { isEmpty } from "../../shared/empty.util"; +import { isEmpty } from '../../shared/empty.util'; /** * Combines a variable number of strings representing parts * of a URL in to a single, normalized URL */ export class URLCombiner { - private parts: Array; + private parts: string[]; /** * Creates a new URLCombiner @@ -13,7 +13,7 @@ export class URLCombiner { * @param parts * a variable number of strings representing parts of a URL */ - constructor(...parts: Array) { + constructor(...parts: string[]) { // can't do this in the constructor signature, // because of the spread operator this.parts = parts; @@ -32,8 +32,7 @@ export class URLCombiner { toString(): string { if (isEmpty(this.parts)) { return ''; - } - else { + } else { let url = this.parts.join('/'); // make sure protocol is followed by two slashes diff --git a/src/app/header/header.actions.ts b/src/app/header/header.actions.ts index 6886960206..7176474a4a 100644 --- a/src/app/header/header.actions.ts +++ b/src/app/header/header.actions.ts @@ -1,37 +1,34 @@ -import { Action } from "@ngrx/store"; -import { type } from "../shared/ngrx/type"; +import { Action } from '@ngrx/store'; + +import { type } from '../shared/ngrx/type'; /** -* For each action type in an action group, make a simple -* enum object for all of this group's action types. -* -* The 'type' utility function coerces strings into string -* literal types and runs a simple check to guarantee all -* action types in the application are unique. -*/ + * For each action type in an action group, make a simple + * enum object for all of this group's action types. + * + * The 'type' utility function coerces strings into string + * literal types and runs a simple check to guarantee all + * action types in the application are unique. + */ export const HeaderActionTypes = { COLLAPSE: type('dspace/header/COLLAPSE'), EXPAND: type('dspace/header/EXPAND'), TOGGLE: type('dspace/header/TOGGLE') }; +/* tslint:disable:max-classes-per-file */ export class HeaderCollapseAction implements Action { type = HeaderActionTypes.COLLAPSE; - - constructor() { } } export class HeaderExpandAction implements Action { type = HeaderActionTypes.EXPAND; - - constructor() { } } export class HeaderToggleAction implements Action { type = HeaderActionTypes.TOGGLE; - - constructor() { } } +/* tslint:enable:max-classes-per-file */ /** * Export a type alias of all actions in this action group diff --git a/src/app/header/header.component.spec.ts b/src/app/header/header.component.spec.ts index 44077247e7..cd77385363 100644 --- a/src/app/header/header.component.spec.ts +++ b/src/app/header/header.component.spec.ts @@ -1,13 +1,16 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { HeaderComponent } from "./header.component"; -import { Store, StoreModule } from "@ngrx/store"; -import { HeaderState } from "./header.reducer"; +import { Store, StoreModule } from '@ngrx/store'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; + +import { Observable } from 'rxjs/Observable'; + +import { HeaderComponent } from './header.component'; +import { HeaderState } from './header.reducer'; +import { HeaderToggleAction } from './header.actions'; + import Spy = jasmine.Spy; -import { HeaderToggleAction } from "./header.actions"; -import { TranslateModule } from "@ngx-translate/core"; -import { NgbCollapseModule } from "@ng-bootstrap/ng-bootstrap"; -import { Observable } from "rxjs"; let comp: HeaderComponent; let fixture: ComponentFixture; @@ -30,7 +33,6 @@ describe('HeaderComponent', () => { comp = fixture.componentInstance; - store = fixture.debugElement.injector.get(Store); spyOn(store, 'dispatch'); }); @@ -38,17 +40,17 @@ describe('HeaderComponent', () => { describe('when the toggle button is clicked', () => { beforeEach(() => { - let navbarToggler = fixture.debugElement.query(By.css('.navbar-toggler')); + const navbarToggler = fixture.debugElement.query(By.css('.navbar-toggler')); navbarToggler.triggerEventHandler('click', null); }); - it("should dispatch a HeaderToggleAction", () => { + it('should dispatch a HeaderToggleAction', () => { expect(store.dispatch).toHaveBeenCalledWith(new HeaderToggleAction()); }); }); - describe("when navCollapsed in the store is true", () => { + describe('when navCollapsed in the store is true', () => { let menu: HTMLElement; beforeEach(() => { @@ -57,13 +59,13 @@ describe('HeaderComponent', () => { fixture.detectChanges(); }); - it("should close the menu", () => { + it('should close the menu', () => { expect(menu.classList).not.toContain('show'); }); }); - describe("when navCollapsed in the store is false", () => { + describe('when navCollapsed in the store is false', () => { let menu: HTMLElement; beforeEach(() => { @@ -72,7 +74,7 @@ describe('HeaderComponent', () => { fixture.detectChanges(); }); - it("should open the menu", () => { + it('should open the menu', () => { expect(menu.classList).toContain('show'); }); diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts index d713d5eba3..cf5b99d6f8 100644 --- a/src/app/header/header.component.ts +++ b/src/app/header/header.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from "@angular/core"; -import { Store } from "@ngrx/store"; -import { HeaderState } from "./header.reducer"; -import { Observable } from "rxjs"; -import { HeaderToggleAction } from "./header.actions"; +import { Component, OnInit } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; + +import { HeaderState } from './header.reducer'; +import { HeaderToggleAction } from './header.actions'; @Component({ selector: 'ds-header', @@ -19,7 +20,7 @@ export class HeaderComponent implements OnInit { ngOnInit(): void { this.isNavBarCollapsed = this.store.select('header') - //unwrap navCollapsed + // unwrap navCollapsed .map(({ navCollapsed }: HeaderState) => navCollapsed); } diff --git a/src/app/header/header.effects.spec.ts b/src/app/header/header.effects.spec.ts index 2abf986cf3..d8bd3af7c4 100644 --- a/src/app/header/header.effects.spec.ts +++ b/src/app/header/header.effects.spec.ts @@ -1,9 +1,10 @@ -import { TestBed, inject } from "@angular/core/testing"; +import { TestBed, inject } from '@angular/core/testing'; import { EffectsTestingModule, EffectsRunner } from '@ngrx/effects/testing'; -import { HeaderEffects } from "./header.effects"; -import { HeaderCollapseAction } from "./header.actions"; -import { HostWindowResizeAction } from "../shared/host-window.actions"; -import { routerActions } from "@ngrx/router-store"; +import { routerActions } from '@ngrx/router-store'; + +import { HeaderEffects } from './header.effects'; +import { HeaderCollapseAction } from './header.actions'; +import { HostWindowResizeAction } from '../shared/host-window.actions'; describe('HeaderEffects', () => { beforeEach(() => TestBed.configureTestingModule({ @@ -32,7 +33,7 @@ describe('HeaderEffects', () => { it('should return a COLLAPSE action in response to a RESIZE action', () => { runner.queue(new HostWindowResizeAction(800, 600)); - headerEffects.resize$.subscribe(result => { + headerEffects.resize$.subscribe((result) => { expect(result).toEqual(new HeaderCollapseAction()); }); }); @@ -44,7 +45,7 @@ describe('HeaderEffects', () => { it('should return a COLLAPSE action in response to an UPDATE_LOCATION action', () => { runner.queue({ type: routerActions.UPDATE_LOCATION }); - headerEffects.resize$.subscribe(result => { + headerEffects.resize$.subscribe((result) => { expect(result).toEqual(new HeaderCollapseAction()); }); }); diff --git a/src/app/header/header.effects.ts b/src/app/header/header.effects.ts index 33888e074d..adc5ac8df4 100644 --- a/src/app/header/header.effects.ts +++ b/src/app/header/header.effects.ts @@ -1,16 +1,13 @@ -import { Injectable } from "@angular/core"; +import { Injectable } from '@angular/core'; import { Effect, Actions } from '@ngrx/effects' -import { HostWindowActionTypes } from "../shared/host-window.actions"; -import { routerActions } from "@ngrx/router-store"; -import { HeaderCollapseAction } from "./header.actions"; +import { routerActions } from '@ngrx/router-store'; + +import { HostWindowActionTypes } from '../shared/host-window.actions'; +import { HeaderCollapseAction } from './header.actions'; @Injectable() export class HeaderEffects { - constructor( - private actions$: Actions - ) { } - @Effect() resize$ = this.actions$ .ofType(HostWindowActionTypes.RESIZE) .map(() => new HeaderCollapseAction()); @@ -18,4 +15,9 @@ export class HeaderEffects { @Effect() routeChange$ = this.actions$ .ofType(routerActions.UPDATE_LOCATION) .map(() => new HeaderCollapseAction()); + + constructor(private actions$: Actions) { + + } + } diff --git a/src/app/header/header.reducer.spec.ts b/src/app/header/header.reducer.spec.ts index 2b8c26f523..b2630ec960 100644 --- a/src/app/header/header.reducer.spec.ts +++ b/src/app/header/header.reducer.spec.ts @@ -1,11 +1,11 @@ -import * as deepFreeze from "deep-freeze"; +import * as deepFreeze from 'deep-freeze'; -import { headerReducer } from "./header.reducer"; +import { headerReducer } from './header.reducer'; import { HeaderCollapseAction, HeaderExpandAction, HeaderToggleAction -} from "./header.actions"; +} from './header.actions'; class NullAction extends HeaderCollapseAction { type = null; @@ -15,8 +15,8 @@ class NullAction extends HeaderCollapseAction { } } -describe("headerReducer", () => { - it("should return the current state when no valid actions have been made", () => { +describe('headerReducer', () => { + it('should return the current state when no valid actions have been made', () => { const state = { navCollapsed: false }; const action = new NullAction(); const newState = headerReducer(state, action); @@ -24,7 +24,7 @@ describe("headerReducer", () => { expect(newState).toEqual(state); }); - it("should start with navCollapsed = true", () => { + it('should start with navCollapsed = true', () => { const action = new NullAction(); const initialState = headerReducer(undefined, action); @@ -32,7 +32,7 @@ describe("headerReducer", () => { expect(initialState.navCollapsed).toEqual(true); }); - it("should set navCollapsed to true in response to the COLLAPSE action", () => { + it('should set navCollapsed to true in response to the COLLAPSE action', () => { const state = { navCollapsed: false }; const action = new HeaderCollapseAction(); const newState = headerReducer(state, action); @@ -40,18 +40,18 @@ describe("headerReducer", () => { expect(newState.navCollapsed).toEqual(true); }); - it("should perform the COLLAPSE action without affecting the previous state", () => { + it('should perform the COLLAPSE action without affecting the previous state', () => { const state = { navCollapsed: false }; deepFreeze(state); const action = new HeaderCollapseAction(); headerReducer(state, action); - //no expect required, deepFreeze will ensure an exception is thrown if the state - //is mutated, and any uncaught exception will cause the test to fail + // no expect required, deepFreeze will ensure an exception is thrown if the state + // is mutated, and any uncaught exception will cause the test to fail }); - it("should set navCollapsed to false in response to the EXPAND action", () => { + it('should set navCollapsed to false in response to the EXPAND action', () => { const state = { navCollapsed: true }; const action = new HeaderExpandAction(); const newState = headerReducer(state, action); @@ -59,7 +59,7 @@ describe("headerReducer", () => { expect(newState.navCollapsed).toEqual(false); }); - it("should perform the EXPAND action without affecting the previous state", () => { + it('should perform the EXPAND action without affecting the previous state', () => { const state = { navCollapsed: true }; deepFreeze(state); @@ -67,7 +67,7 @@ describe("headerReducer", () => { headerReducer(state, action); }); - it("should flip the value of navCollapsed in response to the TOGGLE action", () => { + it('should flip the value of navCollapsed in response to the TOGGLE action', () => { const state1 = { navCollapsed: true }; const action = new HeaderToggleAction(); @@ -78,7 +78,7 @@ describe("headerReducer", () => { expect(state3.navCollapsed).toEqual(true); }); - it("should perform the TOGGLE action without affecting the previous state", () => { + it('should perform the TOGGLE action without affecting the previous state', () => { const state = { navCollapsed: true }; deepFreeze(state); diff --git a/src/app/header/header.reducer.ts b/src/app/header/header.reducer.ts index c1d0fef7ea..0c41e8bf24 100644 --- a/src/app/header/header.reducer.ts +++ b/src/app/header/header.reducer.ts @@ -1,4 +1,4 @@ -import { HeaderAction, HeaderActionTypes } from "./header.actions"; +import { HeaderAction, HeaderActionTypes } from './header.actions'; export interface HeaderState { navCollapsed: boolean; diff --git a/src/app/home/home-news/home-news.component.ts b/src/app/home/home-news/home-news.component.ts index 7125235f1d..a70e95547d 100644 --- a/src/app/home/home-news/home-news.component.ts +++ b/src/app/home/home-news/home-news.component.ts @@ -1,19 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'ds-home-news', styleUrls: ['./home-news.component.scss'], templateUrl: './home-news.component.html' }) -export class HomeNewsComponent implements OnInit { - constructor() { - this.universalInit(); - } +export class HomeNewsComponent { - universalInit() { - - } - - ngOnInit(): void { - } } diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index bac88efbe1..d1222b8ae0 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -1,19 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'ds-home', styleUrls: ['./home.component.scss'], templateUrl: './home.component.html' }) -export class HomeComponent implements OnInit { - constructor() { - this.universalInit(); - } +export class HomeComponent { - universalInit() { - - } - - ngOnInit(): void { - } } diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts index 4128c91097..d5b60f4752 100644 --- a/src/app/home/home.module.ts +++ b/src/app/home/home.module.ts @@ -2,12 +2,12 @@ import { NgModule } from '@angular/core'; import { HomeComponent } from './home.component'; import { HomeRoutingModule } from './home-routing.module'; -import { CommonModule } from "@angular/common"; -import { TopLevelCommunityListComponent } from "./top-level-community-list/top-level-community-list.component"; -import { HomeNewsComponent } from "./home-news/home-news.component"; -import { RouterModule } from "@angular/router"; -import { TranslateModule } from "@ngx-translate/core"; -import { SharedModule } from "../shared/shared.module"; +import { CommonModule } from '@angular/common'; +import { TopLevelCommunityListComponent } from './top-level-community-list/top-level-community-list.component'; +import { HomeNewsComponent } from './home-news/home-news.component'; +import { RouterModule } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { SharedModule } from '../shared/shared.module'; @NgModule({ imports: [ diff --git a/src/app/home/top-level-community-list/top-level-community-list.component.ts b/src/app/home/top-level-community-list/top-level-community-list.component.ts index 24834fc391..259ea4cf5a 100644 --- a/src/app/home/top-level-community-list/top-level-community-list.component.ts +++ b/src/app/home/top-level-community-list/top-level-community-list.component.ts @@ -1,9 +1,10 @@ import { Component, OnInit, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core'; -import { RemoteData } from "../../core/data/remote-data"; -import { CommunityDataService } from "../../core/data/community-data.service"; -import { Community } from "../../core/shared/community.model"; -import { PaginationComponentOptions } from "../../shared/pagination/pagination-component-options.model"; -import { SortOptions, SortDirection } from "../../core/cache/models/sort-options.model"; + +import { RemoteData } from '../../core/data/remote-data'; +import { CommunityDataService } from '../../core/data/community-data.service'; +import { Community } from '../../core/shared/community.model'; +import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; +import { SortOptions, SortDirection } from '../../core/cache/models/sort-options.model'; @Component({ selector: 'ds-top-level-community-list', @@ -20,16 +21,12 @@ export class TopLevelCommunityListComponent implements OnInit { private cds: CommunityDataService, private ref: ChangeDetectorRef ) { - this.universalInit(); - } - - universalInit() { } ngOnInit(): void { this.config = new PaginationComponentOptions(); - this.config.id = "top-level-pagination"; + this.config.id = 'top-level-pagination'; this.config.pageSizeOptions = [4]; this.config.pageSize = 4; this.sortConfig = new SortOptions(); diff --git a/src/app/item-page/field-components/collections/collections.component.ts b/src/app/item-page/field-components/collections/collections.component.ts index 8c504f0c53..c3db3135e3 100644 --- a/src/app/item-page/field-components/collections/collections.component.ts +++ b/src/app/item-page/field-components/collections/collections.component.ts @@ -1,8 +1,9 @@ import { Component, Input, OnInit } from '@angular/core'; -import { Collection } from "../../../core/shared/collection.model"; -import { Observable } from "rxjs"; -import { Item } from "../../../core/shared/item.model"; -import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service"; +import { Observable } from 'rxjs/Observable'; + +import { Collection } from '../../../core/shared/collection.model'; +import { Item } from '../../../core/shared/item.model'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; /** * This component renders the parent collections section of the item @@ -17,30 +18,23 @@ export class CollectionsComponent implements OnInit { @Input() item: Item; - label: string = "item.page.collections"; + label = 'item.page.collections'; - separator: string = "
"; + separator = '
'; collections: Observable; - constructor( - private rdbs: RemoteDataBuildService - ) { - this.universalInit(); + constructor(private rdbs: RemoteDataBuildService) { } - universalInit() { - } - ngOnInit(): void { // this.collections = this.item.parents.payload; - //TODO this should use parents, but the collections + + // TODO: this should use parents, but the collections // for an Item aren't returned by the REST API yet, // only the owning collection - this.collections = this.item.owner.payload.map(c => [c]); + this.collections = this.item.owner.payload.map((c) => [c]); } - - } diff --git a/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts index 04784a1e9f..8c80384732 100644 --- a/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts +++ b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts @@ -4,7 +4,6 @@ import { Component, Input } from '@angular/core'; * This component renders any content inside this wrapper. * The wrapper prints a label before the content (if available) */ - @Component({ selector: 'ds-metadata-field-wrapper', styleUrls: ['./metadata-field-wrapper.component.scss'], @@ -14,13 +13,4 @@ export class MetadataFieldWrapperComponent { @Input() label: string; - constructor() { - this.universalInit(); - - } - - universalInit() { - - } - } diff --git a/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts index 25f57912c1..212dcddee8 100644 --- a/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts +++ b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; -import { MetadataValuesComponent } from "../metadata-values/metadata-values.component"; + +import { MetadataValuesComponent } from '../metadata-values/metadata-values.component'; /** * This component renders the configured 'values' into the ds-metadata-field-wrapper component as a link. @@ -8,7 +9,6 @@ import { MetadataValuesComponent } from "../metadata-values/metadata-values.comp * using the 'linktext' as it's value (if it exists) * and using the values as the 'href' attribute (and as value of the tag when no 'linktext' is defined) */ - @Component({ selector: 'ds-metadata-uri-values', styleUrls: ['./metadata-uri-values.component.scss'], diff --git a/src/app/item-page/field-components/metadata-values/metadata-values.component.ts b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts index b18b1991a7..36499c4721 100644 --- a/src/app/item-page/field-components/metadata-values/metadata-values.component.ts +++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts @@ -4,7 +4,6 @@ import { Component, Input } from '@angular/core'; * This component renders the configured 'values' into the ds-metadata-field-wrapper component. * It puts the given 'separator' between each two values. */ - @Component({ selector: 'ds-metadata-values', styleUrls: ['./metadata-values.component.scss'], @@ -18,13 +17,4 @@ export class MetadataValuesComponent { @Input() label: string; - constructor() { - this.universalInit(); - - } - - universalInit() { - - } - } diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.ts b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts index b9eefae051..262773b1be 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.ts +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts @@ -1,9 +1,10 @@ import { Component, Input, OnInit } from '@angular/core'; -import { Bitstream } from "../../../../core/shared/bitstream.model"; -import { Item } from "../../../../core/shared/item.model"; -import { Observable } from "rxjs"; -import { FileSectionComponent } from "../../../simple/field-components/file-section/file-section.component"; -import { hasValue } from "../../../../shared/empty.util"; +import { Observable } from 'rxjs/Observable'; + +import { Bitstream } from '../../../../core/shared/bitstream.model'; +import { Item } from '../../../../core/shared/item.model'; +import { FileSectionComponent } from '../../../simple/field-components/file-section/file-section.component'; +import { hasValue } from '../../../../shared/empty.util'; /** * This component renders the file section of the item @@ -23,25 +24,20 @@ export class FullFileSectionComponent extends FileSectionComponent implements On files: Observable; - thumbnails: Map> = new Map(); - - universalInit() { - } - ngOnInit(): void { super.ngOnInit(); } initialize(): void { const originals = this.item.getFiles(); - const licenses = this.item.getBitstreamsByBundleName("LICENSE"); - this.files = Observable.combineLatest(originals, licenses, (originals, licenses) => [...originals, ...licenses]); + const licenses = this.item.getBitstreamsByBundleName('LICENSE'); + this.files = Observable.combineLatest(originals, licenses, (o, l) => [...o, ...l]); this.files.subscribe( - files => + (files) => files.forEach( - original => { + (original) => { const thumbnail: Observable = this.item.getThumbnailForOriginal(original); this.thumbnails.set(original.id, thumbnail); } diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts index e79775b4f1..c952954235 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -1,11 +1,12 @@ import { Component, OnInit } from '@angular/core'; -import { Observable } from "rxjs"; -import { ItemPageComponent } from "../simple/item-page.component"; -import { Metadatum } from "../../core/shared/metadatum.model"; -import { ItemDataService } from "../../core/data/item-data.service"; -import { ActivatedRoute } from "@angular/router"; -import { RemoteData } from "../../core/data/remote-data"; -import { Item } from "../../core/shared/item.model"; +import { Observable } from 'rxjs/Observable'; + +import { ItemPageComponent } from '../simple/item-page.component'; +import { Metadatum } from '../../core/shared/metadatum.model'; +import { ItemDataService } from '../../core/data/item-data.service'; +import { ActivatedRoute } from '@angular/router'; +import { RemoteData } from '../../core/data/remote-data'; +import { Item } from '../../core/shared/item.model'; /** * This component renders a simple item page. @@ -22,16 +23,12 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit { item: RemoteData; - metadata: Observable>; + metadata: Observable; constructor(route: ActivatedRoute, items: ItemDataService) { super(route, items); } - universalInit() { - - } - /*** AoT inheritance fix, will hopefully be resolved in the near future **/ ngOnInit(): void { super.ngOnInit(); @@ -39,7 +36,7 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit { initialize(params) { super.initialize(params); - this.metadata = this.item.payload.map(i => i.metadata); + this.metadata = this.item.payload.map((i) => i.metadata); } } diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 8b7bae4477..76aa46fdaa 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; + import { ItemPageComponent } from './simple/item-page.component'; import { ItemPageRoutingModule } from './item-page-routing.module'; import { MetadataValuesComponent } from './field-components/metadata-values/metadata-values.component'; @@ -12,10 +13,10 @@ import { ItemPageUriFieldComponent } from './simple/field-components/specific-fi import { ItemPageTitleFieldComponent } from './simple/field-components/specific-field/title/item-page-title-field.component'; import { ItemPageSpecificFieldComponent } from './simple/field-components/specific-field/item-page-specific-field.component'; import { SharedModule } from './../shared/shared.module'; -import { FileSectionComponent } from "./simple/field-components/file-section/file-section.component"; -import { CollectionsComponent } from "./field-components/collections/collections.component"; -import { FullItemPageComponent } from "./full/full-item-page.component"; -import { FullFileSectionComponent } from "./full/field-components/file-section/full-file-section.component"; +import { FileSectionComponent } from './simple/field-components/file-section/file-section.component'; +import { CollectionsComponent } from './field-components/collections/collections.component'; +import { FullItemPageComponent } from './full/full-item-page.component'; +import { FullFileSectionComponent } from './full/field-components/file-section/full-file-section.component'; @NgModule({ declarations: [ diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.ts b/src/app/item-page/simple/field-components/file-section/file-section.component.ts index 4cd1daf290..a44d6c0d1e 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.ts +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.ts @@ -1,13 +1,13 @@ import { Component, Input, OnInit } from '@angular/core'; -import { Bitstream } from "../../../../core/shared/bitstream.model"; -import { Item } from "../../../../core/shared/item.model"; -import { Observable } from "rxjs"; +import { Observable } from 'rxjs/Observable'; + +import { Bitstream } from '../../../../core/shared/bitstream.model'; +import { Item } from '../../../../core/shared/item.model'; /** * This component renders the file section of the item * inside a 'ds-metadata-field-wrapper' component. */ - @Component({ selector: 'ds-item-page-file-section', templateUrl: './file-section.component.html' @@ -16,19 +16,12 @@ export class FileSectionComponent implements OnInit { @Input() item: Item; - label : string = "item.page.files"; + label = 'item.page.files'; - separator: string = "
"; + separator = '
'; files: Observable; - constructor() { - this.universalInit(); - } - - universalInit() { - } - ngOnInit(): void { this.initialize(); } diff --git a/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts b/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts index f0e410d89e..a8cc309ab6 100644 --- a/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../../core/shared/item.model"; -import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component"; + +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageSpecificFieldComponent } from '../item-page-specific-field.component'; @Component({ selector: 'ds-item-page-abstract-field', @@ -10,12 +11,12 @@ export class ItemPageAbstractFieldComponent extends ItemPageSpecificFieldCompone @Input() item: Item; - separator : string; + separator: string; - fields : string[] = [ - "dc.description.abstract" + fields: string[] = [ + 'dc.description.abstract' ]; - label : string = "item.page.abstract"; + label = 'item.page.abstract'; } diff --git a/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts b/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts index 5b85038e38..e84a52d1b9 100644 --- a/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../../core/shared/item.model"; -import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component"; + +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageSpecificFieldComponent } from '../item-page-specific-field.component'; @Component({ selector: 'ds-item-page-author-field', @@ -10,14 +11,14 @@ export class ItemPageAuthorFieldComponent extends ItemPageSpecificFieldComponent @Input() item: Item; - separator : string; + separator: string; - fields : string[] = [ - "dc.contributor.author", - "dc.creator", - "dc.contributor" + fields: string[] = [ + 'dc.contributor.author', + 'dc.creator', + 'dc.contributor' ]; - label : string = "item.page.author"; + label = 'item.page.author'; } diff --git a/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts b/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts index 2d7b3f7c41..6950944f87 100644 --- a/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../../core/shared/item.model"; -import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component"; + +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageSpecificFieldComponent } from '../item-page-specific-field.component'; @Component({ selector: 'ds-item-page-date-field', @@ -10,12 +11,12 @@ export class ItemPageDateFieldComponent extends ItemPageSpecificFieldComponent { @Input() item: Item; - separator : string = ", "; + separator = ', '; - fields : string[] = [ - "dc.date.issued" + fields: string[] = [ + 'dc.date.issued' ]; - label : string = "item.page.date"; + label = 'item.page.date'; } diff --git a/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts b/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts index 20c9528ebe..f69671a5b5 100644 --- a/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../core/shared/item.model"; + +import { Item } from '../../../../core/shared/item.model'; /** * This component can be used to represent metadata on a simple item page. @@ -17,24 +18,17 @@ export class ItemPageSpecificFieldComponent { /** * Fields (schema.element.qualifier) used to render their values. */ - fields : string[]; + fields: string[]; /** * Label i18n key for the rendered metadata */ - label : string; + label: string; /** * Separator string between multiple values of the metadata fields defined * @type {string} */ - separator : string = "
"; + separator = '
'; - constructor() { - this.universalInit(); - } - - universalInit() { - - } } diff --git a/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts index 4f926000a4..be8102359a 100644 --- a/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../../core/shared/item.model"; -import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component"; + +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageSpecificFieldComponent } from '../item-page-specific-field.component'; @Component({ selector: 'ds-item-page-title-field', @@ -10,10 +11,10 @@ export class ItemPageTitleFieldComponent extends ItemPageSpecificFieldComponent @Input() item: Item; - separator : string; + separator: string; - fields : string[] = [ - "dc.title" + fields: string[] = [ + 'dc.title' ]; } diff --git a/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts b/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts index 4879fa5aa6..4f06337032 100644 --- a/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../../../../core/shared/item.model"; -import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component"; + +import { Item } from '../../../../../core/shared/item.model'; +import { ItemPageSpecificFieldComponent } from '../item-page-specific-field.component'; @Component({ selector: 'ds-item-page-uri-field', @@ -10,12 +11,12 @@ export class ItemPageUriFieldComponent extends ItemPageSpecificFieldComponent { @Input() item: Item; - separator : string; + separator: string; - fields : string[] = [ - "dc.identifier.uri" + fields: string[] = [ + 'dc.identifier.uri' ]; - label : string = "item.page.uri"; + label = 'item.page.uri'; } diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 918e1def05..dd37036c21 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -1,17 +1,17 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Item } from "../../core/shared/item.model"; -import { ItemDataService } from "../../core/data/item-data.service"; -import { RemoteData } from "../../core/data/remote-data"; -import { Observable } from "rxjs"; -import { Bitstream } from "../../core/shared/bitstream.model"; +import { Observable } from 'rxjs/Observable'; + +import { Item } from '../../core/shared/item.model'; +import { ItemDataService } from '../../core/data/item-data.service'; +import { RemoteData } from '../../core/data/remote-data'; +import { Bitstream } from '../../core/shared/bitstream.model'; /** * This component renders a simple item page. * The route parameter 'id' is used to request the item it represents. * All fields of the item that should be displayed, are defined in its template. */ - @Component({ selector: 'ds-item-page', styleUrls: ['./item-page.component.scss'], @@ -28,25 +28,19 @@ export class ItemPageComponent implements OnInit { thumbnail: Observable; constructor(private route: ActivatedRoute, private items: ItemDataService) { - this.universalInit(); - } - - universalInit() { } ngOnInit(): void { - this.sub = this.route.params.subscribe(params => { + this.sub = this.route.params.subscribe((params) => { this.initialize(params); }); } - initialize(params) { - this.id = +params['id']; - this.item = this.items.findById(params['id']); - this.thumbnail = this.item.payload.flatMap(i => i.getThumbnail()); + this.id = +params.id; + this.item = this.items.findById(params.id); + this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail()); } - } diff --git a/src/app/object-list/collection-list-element/collection-list-element.component.ts b/src/app/object-list/collection-list-element/collection-list-element.component.ts index 5f65e60bda..45f285a60b 100644 --- a/src/app/object-list/collection-list-element/collection-list-element.component.ts +++ b/src/app/object-list/collection-list-element/collection-list-element.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; -import { Collection } from "../../core/shared/collection.model"; + +import { Collection } from '../../core/shared/collection.model'; @Component({ selector: 'ds-collection-list-element', @@ -12,12 +13,4 @@ export class CollectionListElementComponent { data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - - } - } diff --git a/src/app/object-list/community-list-element/community-list-element.component.ts b/src/app/object-list/community-list-element/community-list-element.component.ts index 9da5f52b2c..634e573e92 100644 --- a/src/app/object-list/community-list-element/community-list-element.component.ts +++ b/src/app/object-list/community-list-element/community-list-element.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; -import { Community } from "../../core/shared/community.model"; + +import { Community } from '../../core/shared/community.model'; @Component({ selector: 'ds-community-list-element', @@ -12,12 +13,4 @@ export class CommunityListElementComponent { data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - - } - } diff --git a/src/app/object-list/item-list-element/item-list-element.component.ts b/src/app/object-list/item-list-element/item-list-element.component.ts index b26b4dbf26..880f3d9fdc 100644 --- a/src/app/object-list/item-list-element/item-list-element.component.ts +++ b/src/app/object-list/item-list-element/item-list-element.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; -import { Item } from "../../core/shared/item.model"; + +import { Item } from '../../core/shared/item.model'; @Component({ selector: 'ds-item-list-element', @@ -11,12 +12,4 @@ export class ItemListElementComponent { data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - - } - } diff --git a/src/app/object-list/object-list-element/object-list-element.component.ts b/src/app/object-list/object-list-element/object-list-element.component.ts index fa881005d3..4b5f56e1e1 100644 --- a/src/app/object-list/object-list-element/object-list-element.component.ts +++ b/src/app/object-list/object-list-element/object-list-element.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; -import { DSpaceObject } from "../../core/shared/dspace-object.model"; -import { ResourceType } from "../../core/shared/resource-type"; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { ResourceType } from '../../core/shared/resource-type'; @Component({ selector: 'ds-object-list-element', @@ -15,12 +15,4 @@ export class ObjectListElementComponent { data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - - } - } diff --git a/src/app/pagenotfound/pagenotfound.component.ts b/src/app/pagenotfound/pagenotfound.component.ts index 48c9134793..97b70b8414 100644 --- a/src/app/pagenotfound/pagenotfound.component.ts +++ b/src/app/pagenotfound/pagenotfound.component.ts @@ -9,12 +9,4 @@ export class PageNotFoundComponent { data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - - } - } diff --git a/src/app/server-app.module.ts b/src/app/server-app.module.ts index ff124a7c0d..e713d9fe13 100644 --- a/src/app/server-app.module.ts +++ b/src/app/server-app.module.ts @@ -15,7 +15,7 @@ import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { Store } from "@ngrx/store"; +import { Store } from '@ngrx/store'; import { Actions, EffectsModule } from '@ngrx/effects'; import { TranslateUniversalLoader } from '../modules/translate-universal-loader'; diff --git a/src/app/shared/api.service.ts b/src/app/shared/api.service.ts index 5487bd5a36..64a1b538c8 100644 --- a/src/app/shared/api.service.ts +++ b/src/app/shared/api.service.ts @@ -1,10 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; -import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/throw'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; + @Injectable() export class ApiService { constructor(public _http: Http) { @@ -16,8 +17,8 @@ export class ApiService { */ get(url: string, options?: any) { return this._http.get(url, options) - .map(res => res.json()) - .catch(err => { + .map((res) => res.json()) + .catch((err) => { console.log('Error: ', err); return Observable.throw(err); }); diff --git a/src/app/shared/comcol-page-content/comcol-page-content.component.ts b/src/app/shared/comcol-page-content/comcol-page-content.component.ts index a25c9d3680..841b45dd39 100644 --- a/src/app/shared/comcol-page-content/comcol-page-content.component.ts +++ b/src/app/shared/comcol-page-content/comcol-page-content.component.ts @@ -6,7 +6,6 @@ import { Component, Input } from '@angular/core'; * If hasInnerHtml is true the content will be handled as html. * To see how it is used see collection-page or community-page. */ - @Component({ selector: 'ds-comcol-page-content', styleUrls: ['./comcol-page-content.component.scss'], @@ -23,15 +22,4 @@ export class ComcolPageContentComponent { // flag whether the content contains html syntax or not @Input() hasInnerHtml: boolean; - - - constructor() { - this.universalInit(); - - } - - universalInit() { - - } - } diff --git a/src/app/shared/comcol-page-header/comcol-page-header.component.ts b/src/app/shared/comcol-page-header/comcol-page-header.component.ts index 15b5145290..cbf984a349 100644 --- a/src/app/shared/comcol-page-header/comcol-page-header.component.ts +++ b/src/app/shared/comcol-page-header/comcol-page-header.component.ts @@ -1,11 +1,10 @@ import { Component, Input } from '@angular/core'; - @Component({ selector: 'ds-comcol-page-header', styleUrls: ['./comcol-page-header.component.scss'], templateUrl: './comcol-page-header.component.html', }) export class ComcolPageHeaderComponent { - @Input() name: String; + @Input() name: string; } diff --git a/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts b/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts index d8339945d4..f3c2d4e80d 100644 --- a/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts +++ b/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts @@ -1,7 +1,6 @@ import { Component, Input } from '@angular/core'; -import { Bitstream } from "../../core/shared/bitstream.model"; - +import { Bitstream } from '../../core/shared/bitstream.model'; @Component({ selector: 'ds-comcol-page-logo', @@ -16,10 +15,10 @@ export class ComcolPageLogoComponent { /** * The default 'holder.js' image */ - holderSource: string = "data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2293%22%20height%3D%22120%22%20viewBox%3D%220%200%2093%20120%22%20preserveAspectRatio%3D%22none%22%3E%3C!--%0ASource%20URL%3A%20holder.js%2F93x120%3Ftext%3DNo%20Thumbnail%0ACreated%20with%20Holder.js%202.8.2.%0ALearn%20more%20at%20http%3A%2F%2Fholderjs.com%0A(c)%202012-2015%20Ivan%20Malopinsky%20-%20http%3A%2F%2Fimsky.co%0A--%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%3C!%5BCDATA%5B%23holder_1543e460b05%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%5D%5D%3E%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1543e460b05%22%3E%3Crect%20width%3D%2293%22%20height%3D%22120%22%20fill%3D%22%23EEEEEE%22%2F%3E%3Cg%3E%3Ctext%20x%3D%2235.6171875%22%20y%3D%2257%22%3ENo%3C%2Ftext%3E%3Ctext%20x%3D%2210.8125%22%20y%3D%2272%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E"; - + holderSource = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2293%22%20height%3D%22120%22%20viewBox%3D%220%200%2093%20120%22%20preserveAspectRatio%3D%22none%22%3E%3C!--%0ASource%20URL%3A%20holder.js%2F93x120%3Ftext%3DNo%20Thumbnail%0ACreated%20with%20Holder.js%202.8.2.%0ALearn%20more%20at%20http%3A%2F%2Fholderjs.com%0A(c)%202012-2015%20Ivan%20Malopinsky%20-%20http%3A%2F%2Fimsky.co%0A--%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%3C!%5BCDATA%5B%23holder_1543e460b05%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%5D%5D%3E%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1543e460b05%22%3E%3Crect%20width%3D%2293%22%20height%3D%22120%22%20fill%3D%22%23EEEEEE%22%2F%3E%3Cg%3E%3Ctext%20x%3D%2235.6171875%22%20y%3D%2257%22%3ENo%3C%2Ftext%3E%3Ctext%20x%3D%2210.8125%22%20y%3D%2272%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'; errorHandler(event) { event.currentTarget.src = this.holderSource; } + } diff --git a/src/app/shared/empty.util.spec.ts b/src/app/shared/empty.util.spec.ts index b12e4b40ca..f9dd549adf 100644 --- a/src/app/shared/empty.util.spec.ts +++ b/src/app/shared/empty.util.spec.ts @@ -1,219 +1,219 @@ -import { isEmpty, hasNoValue, hasValue, isNotEmpty } from "./empty.util"; +import { isEmpty, hasNoValue, hasValue, isNotEmpty } from './empty.util'; -describe("Empty Utils", () => { - const string: string = 'string'; - const fn: () => void = function () {}; +describe('Empty Utils', () => { + const strng = 'string'; + const fn: () => void = () => { + console.info(); + }; const object: any = { length: 0 }; const emptyMap: Map = new Map(); - let fullMap: Map = new Map(); + const fullMap: Map = new Map(); fullMap.set('foo', 'bar'); - describe("hasNoValue", () => { - it("should return true for null", () => { + describe('hasNoValue', () => { + it('should return true for null', () => { expect(hasNoValue(null)).toBe(true); }); - it("should return true for undefined", () => { + it('should return true for undefined', () => { expect(hasNoValue(undefined)).toBe(true); }); - it("should return false for an empty String", () => { + it('should return false for an empty String', () => { expect(hasNoValue('')).toBe(false); }); - it("should return false for true", () => { + it('should return false for true', () => { expect(hasNoValue(true)).toBe(false); }); - it("should return false for false", () => { + it('should return false for false', () => { expect(hasNoValue(false)).toBe(false); }); - it("should return false for a String", () => { - expect(hasNoValue(string)).toBe(false); + it('should return false for a String', () => { + expect(hasNoValue(strng)).toBe(false); }); - it("should return false for a Function", () => { + it('should return false for a Function', () => { expect(hasNoValue(fn)).toBe(false); }); - it("should return false for 0", () => { + it('should return false for 0', () => { expect(hasNoValue(0)).toBe(false); }); - it("should return false for an empty Array", () => { + it('should return false for an empty Array', () => { expect(hasNoValue([])).toBe(false); }); - it("should return false for an empty Object", () => { + it('should return false for an empty Object', () => { expect(hasNoValue({})).toBe(false); }); }); - describe("hasValue", () => { + describe('hasValue', () => { - it("should return false for null", () => { + it('should return false for null', () => { expect(hasValue(null)).toBe(false); }); - it("should return false for undefined", () => { + it('should return false for undefined', () => { expect(hasValue(undefined)).toBe(false); }); - it("should return true for an empty String", () => { + it('should return true for an empty String', () => { expect(hasValue('')).toBe(true); }); - it("should return true for false", () => { + it('should return true for false', () => { expect(hasValue(false)).toBe(true); }); - it("should return true for true", () => { + it('should return true for true', () => { expect(hasValue(true)).toBe(true); }); - it("should return true for a String", () => { - expect(hasValue(string)).toBe(true); + it('should return true for a String', () => { + expect(hasValue(strng)).toBe(true); }); - it("should return true for a Function", () => { + it('should return true for a Function', () => { expect(hasValue(fn)).toBe(true); }); - it("should return true for 0", () => { + it('should return true for 0', () => { expect(hasValue(0)).toBe(true); }); - it("should return true for an empty Array", () => { + it('should return true for an empty Array', () => { expect(hasValue([])).toBe(true); }); - it("should return true for an empty Object", () => { + it('should return true for an empty Object', () => { expect(hasValue({})).toBe(true); }); }); - describe("isEmpty", () => { - it("should return true for null", () => { + describe('isEmpty', () => { + it('should return true for null', () => { expect(isEmpty(null)).toBe(true); }); - it("should return true for undefined", () => { + it('should return true for undefined', () => { expect(isEmpty(undefined)).toBe(true); }); - it("should return true for an empty String", () => { + it('should return true for an empty String', () => { expect(isEmpty('')).toBe(true); }); - it("should return false for a whitespace String", () => { + it('should return false for a whitespace String', () => { expect(isEmpty(' ')).toBe(false); expect(isEmpty('\n\t')).toBe(false); }); - it("should return false for true", () => { + it('should return false for true', () => { expect(isEmpty(true)).toBe(false); }); - it("should return false for false", () => { + it('should return false for false', () => { expect(isEmpty(false)).toBe(false); }); - it("should return false for a String", () => { - expect(isEmpty(string)).toBe(false); + it('should return false for a String', () => { + expect(isEmpty(strng)).toBe(false); }); - it("should return false for a Function", () => { + it('should return false for a Function', () => { expect(isEmpty(fn)).toBe(false); }); - it("should return false for 0", () => { + it('should return false for 0', () => { expect(isEmpty(0)).toBe(false); }); - it("should return true for an empty Array", () => { + it('should return true for an empty Array', () => { expect(isEmpty([])).toBe(true); }); - it("should return false for an empty Object", () => { + it('should return false for an empty Object', () => { expect(isEmpty({})).toBe(false); }); - it("should return true for an Object that has zero \'length\'", () => { + it('should return true for an Object that has zero \'length\'', () => { expect(isEmpty(object)).toBe(true); }); - it("should return true for an Empty map", () => { + it('should return true for an Empty map', () => { expect(isEmpty(emptyMap)).toBe(true); }); - it("should return false for a Map that is not empty", () => { + it('should return false for a Map that is not empty', () => { expect(isEmpty(fullMap)).toBe(false); }); }); - describe("isNotEmpty", () => { - it("should return false for null", () => { + describe('isNotEmpty', () => { + it('should return false for null', () => { expect(isNotEmpty(null)).toBe(false); }); - it("should return false for undefined", () => { + it('should return false for undefined', () => { expect(isNotEmpty(undefined)).toBe(false); }); - it("should return false for an empty String", () => { + it('should return false for an empty String', () => { expect(isNotEmpty('')).toBe(false); }); - it("should return true for a whitespace String", () => { + it('should return true for a whitespace String', () => { expect(isNotEmpty(' ')).toBe(true); expect(isNotEmpty('\n\t')).toBe(true); }); - it("should return true for false", () => { + it('should return true for false', () => { expect(isNotEmpty(false)).toBe(true); }); - it("should return true for true", () => { + it('should return true for true', () => { expect(isNotEmpty(true)).toBe(true); }); - it("should return true for a String", () => { - expect(isNotEmpty(string)).toBe(true); + it('should return true for a String', () => { + expect(isNotEmpty(strng)).toBe(true); }); - it("should return true for a Function", () => { + it('should return true for a Function', () => { expect(isNotEmpty(fn)).toBe(true); }); - it("should return true for 0", () => { + it('should return true for 0', () => { expect(isNotEmpty(0)).toBe(true); }); - it("should return false for an empty Array", () => { + it('should return false for an empty Array', () => { expect(isNotEmpty([])).toBe(false); }); - it("should return true for an empty Object", () => { + it('should return true for an empty Object', () => { expect(isNotEmpty({})).toBe(true); }); - it("should return false for an Object that has zero length", () => { + it('should return false for an Object that has zero length', () => { expect(isNotEmpty(object)).toBe(false); }); - it("should return false for an Empty map", () => { + it('should return false for an Empty map', () => { expect(isNotEmpty(emptyMap)).toBe(false); }); - it("should return true for a Map that is not empty", () => { + it('should return true for a Map that is not empty', () => { expect(isNotEmpty(fullMap)).toBe(true); }); }); }); - - diff --git a/src/app/shared/empty.util.ts b/src/app/shared/empty.util.ts index a20d3dc98a..4ed2b2b560 100644 --- a/src/app/shared/empty.util.ts +++ b/src/app/shared/empty.util.ts @@ -1,45 +1,42 @@ /** - Returns true if the passed value is null or undefined. - - hasNoValue(); // true - hasNoValue(null); // true - hasNoValue(undefined); // true - hasNoValue(''); // false - hasNoValue([]); // false - hasNoValue(function() {}); // false + * Returns true if the passed value is null or undefined. + * hasNoValue(); // true + * hasNoValue(null); // true + * hasNoValue(undefined); // true + * hasNoValue(''); // false + * hasNoValue([]); // false + * hasNoValue(function() {}); // false */ export function hasNoValue(obj?: any): boolean { return obj === null || obj === undefined; } /** - Returns true if the passed value is not null or undefined. - - hasValue(); // false - hasValue(null); // false - hasValue(undefined); // false - hasValue(''); // true - hasValue([]); // true - hasValue(function() {}); // true + * Returns true if the passed value is not null or undefined. + * hasValue(); // false + * hasValue(null); // false + * hasValue(undefined); // false + * hasValue(''); // true + * hasValue([]); // true + * hasValue(function() {}); // true */ export function hasValue(obj?: any): boolean { return !hasNoValue(obj); } /** - Verifies that a value is `null` or an empty string, empty array, - or empty function. - - isEmpty(); // true - isEmpty(null); // true - isEmpty(undefined); // true - isEmpty(''); // true - isEmpty([]); // true - isEmpty({}); // false - isEmpty('Adam Hawkins'); // false - isEmpty([0,1,2]); // false - isEmpty('\n\t'); // false - isEmpty(' '); // false + * Verifies that a value is `null` or an empty string, empty array, + * or empty function. + * isEmpty(); // true + * isEmpty(null); // true + * isEmpty(undefined); // true + * isEmpty(''); // true + * isEmpty([]); // true + * isEmpty({}); // false + * isEmpty('Adam Hawkins'); // false + * isEmpty([0,1,2]); // false + * isEmpty('\n\t'); // false + * isEmpty(' '); // false */ export function isEmpty(obj?: any): boolean { if (hasNoValue(obj)) { @@ -50,10 +47,10 @@ export function isEmpty(obj?: any): boolean { return !obj.size; } - let objectType = typeof obj; + const objectType = typeof obj; if (objectType === 'object') { - let size = obj['size']; + const size = obj.size; if (typeof size === 'number') { return !size; } @@ -64,7 +61,7 @@ export function isEmpty(obj?: any): boolean { } if (objectType === 'object') { - let length = obj['length']; + const length = obj.length; if (typeof length === 'number') { return !length; } @@ -73,21 +70,19 @@ export function isEmpty(obj?: any): boolean { return false; } - /** - Verifies that a value is not `null`, an empty string, empty array, - or empty function. - - isNotEmpty(); // false - isNotEmpty(null); // false - isNotEmpty(undefined); // false - isNotEmpty(''); // false - isNotEmpty([]); // false - isNotEmpty({}); // true - isNotEmpty('Adam Hawkins'); // true - isNotEmpty([0,1,2]); // true - isNotEmpty('\n\t'); // true - isNotEmpty(' '); // true + * Verifies that a value is not `null`, an empty string, empty array, + * or empty function. + * isNotEmpty(); // false + * isNotEmpty(null); // false + * isNotEmpty(undefined); // false + * isNotEmpty(''); // false + * isNotEmpty([]); // false + * isNotEmpty({}); // true + * isNotEmpty('Adam Hawkins'); // true + * isNotEmpty([0,1,2]); // true + * isNotEmpty('\n\t'); // true + * isNotEmpty(' '); // true */ export function isNotEmpty(obj?: any): boolean { return !isEmpty(obj); diff --git a/src/app/shared/host-window.actions.ts b/src/app/shared/host-window.actions.ts index 99be01cdc2..ad785bae66 100644 --- a/src/app/shared/host-window.actions.ts +++ b/src/app/shared/host-window.actions.ts @@ -1,5 +1,6 @@ -import { Action } from "@ngrx/store"; -import { type } from "./ngrx/type"; +import { Action } from '@ngrx/store'; + +import { type } from './ngrx/type'; export const HostWindowActionTypes = { RESIZE: type('dspace/host-window/RESIZE') diff --git a/src/app/shared/host-window.reducer.spec.ts b/src/app/shared/host-window.reducer.spec.ts index 19d4f67697..fa013b0f10 100644 --- a/src/app/shared/host-window.reducer.spec.ts +++ b/src/app/shared/host-window.reducer.spec.ts @@ -1,18 +1,18 @@ -import * as deepFreeze from "deep-freeze"; -import { hostWindowReducer } from "./host-window.reducer"; -import { HostWindowResizeAction } from "./host-window.actions"; +import * as deepFreeze from 'deep-freeze'; +import { hostWindowReducer } from './host-window.reducer'; +import { HostWindowResizeAction } from './host-window.actions'; class NullAction extends HostWindowResizeAction { type = null; constructor() { - super(0,0); + super(0, 0); } } describe('hostWindowReducer', () => { - it("should return the current state when no valid actions have been made", () => { + it('should return the current state when no valid actions have been made', () => { const state = { width: 800, height: 600 }; const action = new NullAction(); const newState = hostWindowReducer(state, action); @@ -20,7 +20,7 @@ describe('hostWindowReducer', () => { expect(newState).toEqual(state); }); - it("should start with width = null and height = null", () => { + it('should start with width = null and height = null', () => { const action = new NullAction(); const initialState = hostWindowReducer(undefined, action); @@ -28,7 +28,7 @@ describe('hostWindowReducer', () => { expect(initialState.height).toEqual(null); }); - it("should update the width and height in the state in response to a RESIZE action", () => { + it('should update the width and height in the state in response to a RESIZE action', () => { const state = { width: 800, height: 600 }; const action = new HostWindowResizeAction(1024, 768); const newState = hostWindowReducer(state, action); @@ -37,7 +37,7 @@ describe('hostWindowReducer', () => { expect(newState.height).toEqual(768); }); - it("should perform the RESIZE action without affecting the previous state", () => { + it('should perform the RESIZE action without affecting the previous state', () => { const state = { width: 800, height: 600 }; deepFreeze(state); diff --git a/src/app/shared/host-window.reducer.ts b/src/app/shared/host-window.reducer.ts index 03349b3a91..ae9204c6c5 100644 --- a/src/app/shared/host-window.reducer.ts +++ b/src/app/shared/host-window.reducer.ts @@ -1,4 +1,4 @@ -import { HostWindowAction, HostWindowActionTypes } from "./host-window.actions"; +import { HostWindowAction, HostWindowActionTypes } from './host-window.actions'; export interface HostWindowState { width: number; diff --git a/src/app/shared/host-window.service.spec.ts b/src/app/shared/host-window.service.spec.ts index 3495bdce26..b48d094a1e 100644 --- a/src/app/shared/host-window.service.spec.ts +++ b/src/app/shared/host-window.service.spec.ts @@ -1,187 +1,187 @@ -import { HostWindowService } from "./host-window.service"; -import { HostWindowState } from "./host-window.reducer"; -import { Observable } from "rxjs"; -import { Store } from "@ngrx/store"; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; -describe("HostWindowService", () => { +import { HostWindowService } from './host-window.service'; +import { HostWindowState } from './host-window.reducer'; + +describe('HostWindowService', () => { let service: HostWindowService; - let mockStore: any; let store: Store; - describe("", () => { + describe('', () => { beforeEach(() => { - let _initialState = { width: 1600, height: 770 }; + const _initialState = { width: 1600, height: 770 }; store = new Store(undefined, undefined, Observable.of(_initialState)); service = new HostWindowService(store); }); - it("isXs() should return false with width = 1600", () => { + it('isXs() should return false with width = 1600', () => { service.isXs().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isSm() should return false with width = 1600", () => { + it('isSm() should return false with width = 1600', () => { service.isSm().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isMd() should return false with width = 1600", () => { + it('isMd() should return false with width = 1600', () => { service.isMd().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isLg() should return false with width = 1600", () => { + it('isLg() should return false with width = 1600', () => { service.isLg().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isXl() should return true with width = 1600", () => { + it('isXl() should return true with width = 1600', () => { service.isXl().subscribe((status) => { expect(status).toBeTruthy(); }); }); }); - describe("", () => { + describe('', () => { beforeEach(() => { - let _initialState = { width: 1100, height: 770 }; + const _initialState = { width: 1100, height: 770 }; store = new Store(undefined, undefined, Observable.of(_initialState)); service = new HostWindowService(store); }); - it("isXs() should return false with width = 1100", () => { + it('isXs() should return false with width = 1100', () => { service.isXs().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isSm() should return false with width = 1100", () => { + it('isSm() should return false with width = 1100', () => { service.isSm().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isMd() should return false with width = 1100", () => { + it('isMd() should return false with width = 1100', () => { service.isMd().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isLg() should return true with width = 1100", () => { + it('isLg() should return true with width = 1100', () => { service.isLg().subscribe((status) => { expect(status).toBeTruthy(); }); }); - it("isXl() should return false with width = 1100", () => { + it('isXl() should return false with width = 1100', () => { service.isXl().subscribe((status) => { expect(status).toBeFalsy(); }); }); }); - describe("", () => { + describe('', () => { beforeEach(() => { - let _initialState = { width: 800, height: 770 }; + const _initialState = { width: 800, height: 770 }; store = new Store(undefined, undefined, Observable.of(_initialState)); service = new HostWindowService(store); }); - it("isXs() should return false with width = 800", () => { + it('isXs() should return false with width = 800', () => { service.isXs().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isSm() should return false with width = 800", () => { + it('isSm() should return false with width = 800', () => { service.isSm().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isMd() should return true with width = 800", () => { + it('isMd() should return true with width = 800', () => { service.isMd().subscribe((status) => { expect(status).toBeTruthy(); }); }); - it("isLg() should return false with width = 800", () => { + it('isLg() should return false with width = 800', () => { service.isLg().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isXl() should return false with width = 800", () => { + it('isXl() should return false with width = 800', () => { service.isXl().subscribe((status) => { expect(status).toBeFalsy(); }); }); }); - describe("", () => { + describe('', () => { beforeEach(() => { - let _initialState = { width: 600, height: 770 }; + const _initialState = { width: 600, height: 770 }; store = new Store(undefined, undefined, Observable.of(_initialState)); service = new HostWindowService(store); }); - it("isXs() should return false with width = 600", () => { + it('isXs() should return false with width = 600', () => { service.isXs().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isSm() should return true with width = 600", () => { + it('isSm() should return true with width = 600', () => { service.isSm().subscribe((status) => { expect(status).toBeTruthy(); }); }); - it("isMd() should return false with width = 600", () => { + it('isMd() should return false with width = 600', () => { service.isMd().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isLg() should return false with width = 600", () => { + it('isLg() should return false with width = 600', () => { service.isLg().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isXl() should return false with width = 600", () => { + it('isXl() should return false with width = 600', () => { service.isXl().subscribe((status) => { expect(status).toBeFalsy(); }); }); }); - describe("", () => { + describe('', () => { beforeEach(() => { - let _initialState = { width: 400, height: 770 }; + const _initialState = { width: 400, height: 770 }; store = new Store(undefined, undefined, Observable.of(_initialState)); service = new HostWindowService(store); }); - it("isXs() should return true with width = 400", () => { + it('isXs() should return true with width = 400', () => { service.isXs().subscribe((status) => { expect(status).toBeTruthy(); }); }); - it("isSm() should return false with width = 400", () => { + it('isSm() should return false with width = 400', () => { service.isSm().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isMd() should return false with width = 400", () => { + it('isMd() should return false with width = 400', () => { service.isMd().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isLg() should return false with width = 400", () => { + it('isLg() should return false with width = 400', () => { service.isLg().subscribe((status) => { expect(status).toBeFalsy(); }); }); - it("isXl() should return false with width = 400", () => { + it('isXl() should return false with width = 400', () => { service.isXl().subscribe((status) => { expect(status).toBeFalsy(); }); diff --git a/src/app/shared/host-window.service.ts b/src/app/shared/host-window.service.ts index 6015e1de56..d04ce3a7dd 100644 --- a/src/app/shared/host-window.service.ts +++ b/src/app/shared/host-window.service.ts @@ -1,10 +1,11 @@ -import { HostWindowState } from "./host-window.reducer"; -import { Injectable } from "@angular/core"; -import { Store } from "@ngrx/store"; -import { Observable } from "rxjs/Observable"; -import { hasValue } from "./empty.util"; +import { HostWindowState } from './host-window.reducer'; +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; -//TODO ideally we should get these from sass somehow +import { hasValue } from './empty.util'; + +// TODO: ideally we should get these from sass somehow export enum GridBreakpoint { XS = 0, SM = 576, @@ -23,36 +24,36 @@ export class HostWindowService { private getWidthObs(): Observable { return this.store.select('hostWindow', 'width') - .filter(width => hasValue(width)); + .filter((width) => hasValue(width)); } isXs(): Observable { return this.getWidthObs() - .map(width => width < GridBreakpoint.SM) + .map((width) => width < GridBreakpoint.SM) .distinctUntilChanged(); } isSm(): Observable { return this.getWidthObs() - .map(width => width >= GridBreakpoint.SM && width < GridBreakpoint.MD) + .map((width) => width >= GridBreakpoint.SM && width < GridBreakpoint.MD) .distinctUntilChanged(); } isMd(): Observable { return this.getWidthObs() - .map(width => width >= GridBreakpoint.MD && width < GridBreakpoint.LG) + .map((width) => width >= GridBreakpoint.MD && width < GridBreakpoint.LG) .distinctUntilChanged(); } isLg(): Observable { return this.getWidthObs() - .map(width => width >= GridBreakpoint.LG && width < GridBreakpoint.XL) + .map((width) => width >= GridBreakpoint.LG && width < GridBreakpoint.XL) .distinctUntilChanged(); } isXl(): Observable { return this.getWidthObs() - .map(width => width >= GridBreakpoint.XL) + .map((width) => width >= GridBreakpoint.XL) .distinctUntilChanged(); } } diff --git a/src/app/shared/ngrx/type.ts b/src/app/shared/ngrx/type.ts index 1acb3c91f1..9026d296cb 100644 --- a/src/app/shared/ngrx/type.ts +++ b/src/app/shared/ngrx/type.ts @@ -12,18 +12,18 @@ * are unique. */ -let typeCache: { [label: string]: boolean } = {}; +const typeCache: { [label: string]: boolean } = {}; export function types(): string[] { return Object.keys(typeCache); } export function type(label: T | ''): T { - if (typeCache[label]) { + if (typeCache[label as string]) { throw new Error(`Action type "${label}" is not unique"`); } - typeCache[label] = true; + typeCache[label as string] = true; - return label; + return label as T; } diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts index dc7e13d358..c36a3f5b1f 100644 --- a/src/app/shared/object-list/object-list.component.ts +++ b/src/app/shared/object-list/object-list.component.ts @@ -7,14 +7,16 @@ import { OnInit, Output } from '@angular/core'; -import { RemoteData } from "../../core/data/remote-data"; -import { DSpaceObject } from "../../core/shared/dspace-object.model"; -import { PageInfo } from "../../core/shared/page-info.model"; -import { Observable } from "rxjs"; -import { PaginationComponentOptions } from "../pagination/pagination-component-options.model"; -import { SortOptions, SortDirection } from "../../core/cache/models/sort-options.model"; +import { Observable } from 'rxjs/Observable'; +import { RemoteData } from '../../core/data/remote-data'; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { PageInfo } from '../../core/shared/page-info.model'; + +import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; + +import { SortOptions, SortDirection } from '../../core/cache/models/sort-options.model'; @Component({ changeDetection: ChangeDetectionStrategy.Default, @@ -28,8 +30,8 @@ export class ObjectListComponent implements OnInit { @Input() objects: RemoteData; @Input() config: PaginationComponentOptions; @Input() sortConfig: SortOptions; - @Input() hideGear: boolean = false; - @Input() hidePagerWhenSinglePage: boolean = true; + @Input() hideGear = false; + @Input() hidePagerWhenSinglePage = true; pageInfo: Observable; /** @@ -57,13 +59,6 @@ export class ObjectListComponent implements OnInit { @Output() sortFieldChange: EventEmitter = new EventEmitter(); data: any = {}; - constructor() { - this.universalInit(); - } - - universalInit() { - } - ngOnInit(): void { this.pageInfo = this.objects.pageInfo; } diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 2192ae3367..4f10b5b541 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -1,4 +1,3 @@ -import 'rxjs/add/operator/switchMap'; import { ChangeDetectionStrategy, @@ -303,7 +302,8 @@ export class PaginationComponent implements OnDestroy, OnInit { * The page size to validate */ private validateParams(page: any, pageSize: any, sortDirection: any, sortField: any) { - let filteredPageSize = this.pageSizeOptions.find((x) => x === pageSize); + // tslint:disable-next-line:triple-equals + let filteredPageSize = this.pageSizeOptions.find((x) => x == pageSize); if (!isNumeric(page) || !filteredPageSize) { const filteredPage = isNumeric(page) ? page : this.currentPage; filteredPageSize = (filteredPageSize) ? filteredPageSize : this.pageSize;