diff --git a/src/app/core/config/config.service.spec.ts b/src/app/core/config/config.service.spec.ts index 46c8fd18593ca08a203f8d510753a6c46ae6e00a..fe8185187a717811434303936d07b31e477114f3 100644 --- a/src/app/core/config/config.service.spec.ts +++ b/src/app/core/config/config.service.spec.ts @@ -1,4 +1,4 @@ -import { cold, getTestScheduler, hot } from 'jasmine-marbles'; +import { cold, getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/mock-request.service'; import { ResponseCacheService } from '../cache/response-cache.service'; diff --git a/src/app/core/config/config.service.ts b/src/app/core/config/config.service.ts index 872bc57c2b9136ae895a1dac71c1f81f8cb15548..a05eb9e330d36536405b9386e300b3b74dfa2391 100644 --- a/src/app/core/config/config.service.ts +++ b/src/app/core/config/config.service.ts @@ -1,4 +1,4 @@ -import { Observable, of as observableOf, throwError as observableThrowError, merge as observableMerge } from 'rxjs'; +import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs'; import { distinctUntilChanged, filter, map, mergeMap, tap } from 'rxjs/operators'; import { RequestService } from '../data/request.service'; import { ResponseCacheService } from '../cache/response-cache.service'; diff --git a/src/app/core/json-patch/json-patch-operations.effects.ts b/src/app/core/json-patch/json-patch-operations.effects.ts index 79fd63fafaf5a6d7a4c3655fbad737e96a7430b6..d7f831f33c7345470c914207b548fedbef7a5eef 100644 --- a/src/app/core/json-patch/json-patch-operations.effects.ts +++ b/src/app/core/json-patch/json-patch-operations.effects.ts @@ -1,5 +1,7 @@ import { Injectable } from '@angular/core'; -import { Effect, Actions } from '@ngrx/effects'; + +import { map } from 'rxjs/operators'; +import { Effect, Actions, ofType } from '@ngrx/effects'; import { CommitPatchOperationsAction, FlushPatchOperationsAction, @@ -9,11 +11,11 @@ import { @Injectable() export class JsonPatchOperationsEffects { - @Effect() commit$ = this.actions$ - .ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS) - .map((action: CommitPatchOperationsAction) => { + @Effect() commit$ = this.actions$.pipe( + ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS), + map((action: CommitPatchOperationsAction) => { return new FlushPatchOperationsAction(action.payload.resourceType, action.payload.resourceId); - }); + })); constructor(private actions$: Actions) {} diff --git a/src/app/core/submission/models/submission-object.model.ts b/src/app/core/submission/models/submission-object.model.ts index 8160b46d1edaf1f1fb6368e2d8e82f781cdea219..3a899e4a07433af6ab276f41dff4c8245665c9ec 100644 --- a/src/app/core/submission/models/submission-object.model.ts +++ b/src/app/core/submission/models/submission-object.model.ts @@ -1,4 +1,4 @@ -import { Observable } from 'rxjs/Observable'; +import { Observable } from 'rxjs'; import { CacheableObject } from '../../cache/object-cache.reducer'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; diff --git a/src/app/core/submission/workflowitem-data.service.ts b/src/app/core/submission/workflowitem-data.service.ts index 3951ca7392b2a94d84b8ae47f2d109ce0fb833b7..0b71812cbf0bcc408c934f3f32030090b27ff838 100644 --- a/src/app/core/submission/workflowitem-data.service.ts +++ b/src/app/core/submission/workflowitem-data.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs/Observable'; import { BrowseService } from '../browse/browse.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ResponseCacheService } from '../cache/response-cache.service'; diff --git a/src/app/core/submission/workspaceitem-data.service.ts b/src/app/core/submission/workspaceitem-data.service.ts index b61d1960273b597ab7460cfd7f26358a6be97836..b3685f9775f0403e3527b6f85d9cd3b25966e1f7 100644 --- a/src/app/core/submission/workspaceitem-data.service.ts +++ b/src/app/core/submission/workspaceitem-data.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs/Observable'; import { BrowseService } from '../browse/browse.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ResponseCacheService } from '../cache/response-cache.service'; diff --git a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts index cf635d9067982d3fe15c47c7d6afac927c09d087..da62204d10819f9e125017dd8c85fd8790e223f6 100644 --- a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts +++ b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts @@ -91,7 +91,7 @@ export class AuthorityConfidenceStateDirective implements OnChanges { const confidenceIndex: number = findIndex(confidenceIcons, {value: confidence}); - const defaultconfidenceIndex: number = findIndex(confidenceIcons, {value: 'default'}); + const defaultconfidenceIndex: number = findIndex(confidenceIcons, {value: 'default' as any}); const defaultClass: string = (defaultconfidenceIndex !== -1) ? confidenceIcons[defaultconfidenceIndex].style : ''; return (confidenceIndex !== -1) ? confidenceIcons[confidenceIndex].style : defaultClass; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts index 0a94c89095cb08c2d1d7398f879a7ac9126ea3d8..1c119a7223494f4706fc3b8dbaa217f0c0aa14bf 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts @@ -11,7 +11,7 @@ import { } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { of as observableOf, Subscription } from 'rxjs'; +import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { filter, flatMap, map, mergeMap, scan } from 'rxjs/operators'; import { DynamicFormControlComponent, @@ -34,7 +34,6 @@ import { shrinkInOut } from '../../../../../animations/shrink'; import { ChipsItem } from '../../../../../chips/models/chips-item.model'; import { GlobalConfig } from '../../../../../../../config/global-config.interface'; import { GLOBAL_CONFIG } from '../../../../../../../config'; -import { FormGroup } from '@angular/forms'; import { hasOnlyEmptyProperties } from '../../../../../object.util'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { AuthorityService } from '../../../../../../core/integration/authority.service'; @@ -48,7 +47,7 @@ import { AuthorityValue } from '../../../../../../core/integration/models/author templateUrl: './dynamic-group.component.html', animations: [shrinkInOut] }) -export class DsDynamicGroupComponent implements OnDestroy, OnInit { +export class DsDynamicGroupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit { @Input() formId: string; @Input() group: FormGroup; @@ -78,7 +77,6 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit { protected validationService: DynamicFormValidationService ) { super(layoutService, validationService); - } ngOnInit() { @@ -244,21 +242,21 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit { (model as any).maxOptions, 1); - return$ = this.authorityService.getEntryByValue(searchOptions) - .map((result: IntegrationData) => Object.assign( + return$ = this.authorityService.getEntryByValue(searchOptions).pipe( + map((result: IntegrationData) => Object.assign( new FormFieldMetadataValueObject(), valueObj[fieldName], { otherInformation: (result.payload[0] as AuthorityValue).otherInformation }) - ); + )); } else { return$ = observableOf(valueObj[fieldName]); } - return return$.map((entry) => ({[fieldName]: entry})); + return return$.pipe(map((entry) => ({[fieldName]: entry}))); }); - returnList.push(Observable.combineLatest(returnObj)); + returnList.push(combineLatest(returnObj)); }); return returnList; }), diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts index b6e87034f096d184b14ff7f1a19dc1a593bfc6bd..66697cab61671229a507f7f059ef01eecc67ea56 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts @@ -1,25 +1,32 @@ import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { FormGroup } from '@angular/forms'; +import { Subscription } from 'rxjs'; +import { distinctUntilChanged } from 'rxjs/operators'; +import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; + import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { DynamicLookupModel } from './dynamic-lookup.model'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util'; import { IntegrationData } from '../../../../../../core/integration/integration-data'; import { PageInfo } from '../../../../../../core/shared/page-info.model'; -import { Subscription } from 'rxjs/Subscription'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type'; -import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; +import { + DynamicFormControlComponent, + DynamicFormLayoutService, + DynamicFormValidationService +} from '@ng-dynamic-forms/core'; @Component({ selector: 'ds-dynamic-lookup', styleUrls: ['./dynamic-lookup.component.scss'], templateUrl: './dynamic-lookup.component.html' }) -export class DsDynamicLookupComponent implements OnDestroy, OnInit { +export class DsDynamicLookupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit { @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicLookupModel | DynamicLookupNameModel; @@ -40,7 +47,11 @@ export class DsDynamicLookupComponent implements OnDestroy, OnInit { protected sub: Subscription; constructor(private authorityService: AuthorityService, - private cdr: ChangeDetectorRef) { + private cdr: ChangeDetectorRef, + protected layoutService: DynamicFormLayoutService, + protected validationService: DynamicFormValidationService + ) { + super(layoutService, validationService); } inputFormatter = (x: { display: string }, y: number) => { @@ -223,8 +234,8 @@ export class DsDynamicLookupComponent implements OnDestroy, OnInit { this.searchOptions.query = this.getCurrentValue(); this.loading = true; - this.authorityService.getEntriesByName(this.searchOptions) - .distinctUntilChanged() + this.authorityService.getEntriesByName(this.searchOptions).pipe( + distinctUntilChanged()) .subscribe((object: IntegrationData) => { this.optionsList = object.payload; this.pageInfo = object.pageInfo; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts index 0e5975c36a552ad43eec9b9327f213eadaec2f9d..3b54226654f5c18b71cf3172eb8c17fd71160cfd 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts @@ -1,24 +1,22 @@ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormGroup } from '@angular/forms'; +import { Observable, of as observableOf } from 'rxjs'; +import { tap } from 'rxjs/operators'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; import { DynamicFormControlComponent, DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; -import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; -import { Observable } from 'rxjs/Observable'; -import {tap} from 'rxjs/operators'; +import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model'; import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { isNull, isUndefined } from '../../../../../empty.util'; import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { IntegrationData } from '../../../../../../core/integration/integration-data'; -import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; - @Component({ selector: 'ds-dynamic-scrollable-dropdown', @@ -120,6 +118,6 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp } } } - this.currentValue = Observable.of(result); + this.currentValue = observableOf(result); } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts index b01540d751614320b80bf8a75e0aaa72a25d9b32..142fbb0b868e3a2a18841557d7938288da198bc1 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts @@ -1,4 +1,3 @@ - import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormGroup } from '@angular/forms'; @@ -7,9 +6,8 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; -import { distinctUntilChanged, switchMap, tap, filter, catchError, debounceTime, merge, map } from 'rxjs/operators'; -import {of as observableOf, Observable } from 'rxjs'; -import { Subject } from 'rxjs/Subject'; +import { catchError, debounceTime, distinctUntilChanged, filter, map, merge, switchMap, tap } from 'rxjs/operators'; +import { Observable, of as observableOf, Subject } from 'rxjs'; import { NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; import { AuthorityService } from '../../../../../../core/integration/authority.service'; diff --git a/src/app/shared/mocks/mock-router.ts b/src/app/shared/mocks/mock-router.ts index 8312d353d7b9e5536b260a5a297288c4161ad19c..9ebe321cf6fcee4cbd1bb72ae03f7aa55a62dcc9 100644 --- a/src/app/shared/mocks/mock-router.ts +++ b/src/app/shared/mocks/mock-router.ts @@ -1,7 +1,7 @@ -import { Observable } from 'rxjs/Observable'; +import { Observable, of as observableOf } from 'rxjs'; export class MockRouter { - public events = Observable.of({}); + public events = observableOf({}); public routerState = { snapshot: { url: '' diff --git a/src/app/shared/notifications/notifications.service.ts b/src/app/shared/notifications/notifications.service.ts index 8da7d78cb70b07e4c9e0a5a5caf7f9dae07ea2d9..b8a10da1c7a3e545a0bf6168e80a72ed88c63d2e 100644 --- a/src/app/shared/notifications/notifications.service.ts +++ b/src/app/shared/notifications/notifications.service.ts @@ -1,17 +1,17 @@ -import { of as observableOf, Observable } from 'rxjs'; import { Inject, Injectable } from '@angular/core'; + +import { of as observableOf } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { TranslateService } from '@ngx-translate/core'; +import { uniqueId } from 'lodash'; + import { INotification, Notification } from './models/notification.model'; import { NotificationType } from './models/notification-type'; import { NotificationOptions } from './models/notification-options.model'; -import { uniqueId } from 'lodash'; -import { Store } from '@ngrx/store'; -import { - NewNotificationAction, - RemoveAllNotificationsAction, - RemoveNotificationAction -} from './notifications.actions'; + +import { NewNotificationAction, RemoveAllNotificationsAction, RemoveNotificationAction } from './notifications.actions'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; -import { TranslateService } from '@ngx-translate/core'; @Injectable() export class NotificationsService { @@ -70,7 +70,7 @@ export class NotificationsService { messageTranslateLabel: string, interpolateParam: string) { this.translate.get(hrefTranslateLabel) - .take(1) + .pipe(first()) .subscribe((hrefMsg) => { const anchor = `<a class="btn btn-link p-0 m-0" href="${href}" > <strong>${hrefMsg}</strong> @@ -78,7 +78,7 @@ export class NotificationsService { const interpolateParams = Object.create({}); interpolateParams[interpolateParam] = anchor; this.translate.get(messageTranslateLabel, interpolateParams) - .take(1) + .pipe(first()) .subscribe((m) => { switch (notificationType) { case NotificationType.Success: diff --git a/src/app/shared/services/route.service.ts b/src/app/shared/services/route.service.ts index 57c03e695433f548562a730e159e002b5274957b..8e03f941cb5d3884dcd7220aa54c713fe325e8bc 100644 --- a/src/app/shared/services/route.service.ts +++ b/src/app/shared/services/route.service.ts @@ -1,14 +1,9 @@ import { Injectable } from '@angular/core'; -import { - ActivatedRoute, convertToParamMap, NavigationEnd, NavigationExtras, Params, - Router, -} from '@angular/router'; +import { ActivatedRoute, NavigationEnd, Params, Router, } from '@angular/router'; -import { distinctUntilChanged, map } from 'rxjs/operators'; +import { distinctUntilChanged, filter, map } from 'rxjs/operators'; import { Observable } from 'rxjs'; -import { isNotEmpty } from '../empty.util'; - @Injectable() export class RouteService { diff --git a/src/app/shared/testing/submission-rest-service-stub.ts b/src/app/shared/testing/submission-rest-service-stub.ts index a71d3d3793ed65d9c3f0c5c1ebc284c0ef51e690..1ef821f626b8c32f29873eb9977022daf1f8d124 100644 --- a/src/app/shared/testing/submission-rest-service-stub.ts +++ b/src/app/shared/testing/submission-rest-service-stub.ts @@ -1,9 +1,10 @@ +import { of as observableOf } from 'rxjs'; +import { Store } from '@ngrx/store'; + import { ResponseCacheService } from '../../core/cache/response-cache.service'; import { RequestService } from '../../core/data/request.service'; -import { Store } from '@ngrx/store'; import { CoreState } from '../../core/core.reducers'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; -import { Observable } from 'rxjs/Observable'; export class SubmissionRestServiceStub { protected linkPath = 'workspaceitems'; @@ -18,6 +19,6 @@ export class SubmissionRestServiceStub { getDataByHref = jasmine.createSpy('getDataByHref'); getEndpointByIDHref = jasmine.createSpy('getEndpointByIDHref'); patchToEndpoint = jasmine.createSpy('patchToEndpoint'); - postToEndpoint = jasmine.createSpy('postToEndpoint').and.returnValue(Observable.of({})); + postToEndpoint = jasmine.createSpy('postToEndpoint').and.returnValue(observableOf({})); submitData = jasmine.createSpy('submitData'); } diff --git a/src/app/submission/edit/submission-edit.component.ts b/src/app/submission/edit/submission-edit.component.ts index 776184e6f9e15aac734ff1110b8f05d631e15b58..99758b9e751248c18f38e26fcf8e711282764e0a 100644 --- a/src/app/submission/edit/submission-edit.component.ts +++ b/src/app/submission/edit/submission-edit.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { Subscription } from 'rxjs/Subscription'; +import { Subscription } from 'rxjs'; import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model'; import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util'; diff --git a/src/app/submission/form/collection/submission-form-collection.component.ts b/src/app/submission/form/collection/submission-form-collection.component.ts index 52eee7e2a19bbc979cbe6a3ab5345440c6bbe2bc..e39a6af25224c18f6de8e04579d82d16644ee8d9 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.ts +++ b/src/app/submission/form/collection/submission-form-collection.component.ts @@ -10,7 +10,7 @@ import { SimpleChanges } from '@angular/core'; import { FormControl } from '@angular/forms'; -import { Subscription } from 'rxjs/Subscription'; +import { combineLatest, Observable, Subscription } from 'rxjs'; import { isNullOrUndefined } from 'util'; import { Collection } from '../../../core/shared/collection.model'; @@ -26,7 +26,6 @@ import { JsonPatchOperationsService } from '../../../core/json-patch/json-patch- import { SubmitDataResponseDefinitionObject } from '../../../core/shared/submit-data-response-definition.model'; import { SubmissionService } from '../../submission.service'; import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; -import { Observable } from 'rxjs/Observable'; import { debounceTime, distinctUntilChanged, @@ -144,14 +143,14 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit { startWith('') ); - this.searchListCollection$ = Observable.combineLatest(searchTerm$, listCollection$) - .map(([searchTerm, listCollection]) => { + this.searchListCollection$ = combineLatest(searchTerm$, listCollection$).pipe( + map(([searchTerm, listCollection]) => { if (searchTerm === '' || isNullOrUndefined(searchTerm)) { return listCollection; } else { return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5) } - }); + })); } } diff --git a/src/app/submission/form/footer/submission-form-footer.component.ts b/src/app/submission/form/footer/submission-form-footer.component.ts index a968de4ef52ab75fb8a14e18aafe29a84a024687..593f4a3e10528cf7b7d8836712791c2548b62343 100644 --- a/src/app/submission/form/footer/submission-form-footer.component.ts +++ b/src/app/submission/form/footer/submission-form-footer.component.ts @@ -1,8 +1,10 @@ import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; + +import { Observable, of as observableOf } from 'rxjs'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; + import { SubmissionRestService } from '../../submission-rest.service'; import { SubmissionService } from '../../submission.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { Observable } from 'rxjs/Observable'; import { SubmissionScopeType } from '../../../core/submission/submission-scope-type'; @Component({ @@ -33,7 +35,7 @@ export class SubmissionFormFooterComponent implements OnChanges { this.processingSaveStatus = this.submissionService.getSubmissionSaveProcessingStatus(this.submissionId); this.processingDepositStatus = this.submissionService.getSubmissionDepositProcessingStatus(this.submissionId); - this.showDepositAndDiscard = Observable.of(this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkspaceItem); + this.showDepositAndDiscard = observableOf(this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkspaceItem); } } diff --git a/src/app/submission/form/section-add/submission-form-section-add.component.ts b/src/app/submission/form/section-add/submission-form-section-add.component.ts index 105059dfc1f5627b0d32d1e63b0a1bb1ad2d269e..304e53ac6c3b29307a9c43893705e183d2c0bd34 100644 --- a/src/app/submission/form/section-add/submission-form-section-add.component.ts +++ b/src/app/submission/form/section-add/submission-form-section-add.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit, } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; +import { Observable } from 'rxjs'; import { SectionsService } from '../../sections/sections.service'; import { HostWindowService } from '../../../shared/host-window.service'; diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 3eace39fb9d53faa631bf7c583424b751f8011d4..57a6d77a7958450bb308df5a02bab095997aa6e2 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -1,13 +1,14 @@ import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; + +import { of as observableOf, Observable, Subscription } from 'rxjs'; +import { distinctUntilChanged, filter, flatMap, map } from 'rxjs/operators'; + import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; -import { Workspaceitem } from '../../core/submission/models/workspaceitem.model'; import { SubmissionService } from '../submission.service'; -import { Subscription } from 'rxjs/Subscription'; import { AuthService } from '../../core/auth/auth.service'; -import { Observable } from 'rxjs/Observable'; import { SectionDataObject } from '../sections/models/section-data.model'; import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; @@ -28,7 +29,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { public definitionId: string; public test = true; - public loading: Observable<boolean> = Observable.of(true); + public loading: Observable<boolean> = observableOf(true); public submissionSections: Observable<any>; public uploadFilesOptions: UploaderOptions = { url: '', @@ -51,29 +52,29 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { ngOnChanges(changes: SimpleChanges) { if (this.collectionId && this.submissionId) { this.isActive = true; - this.submissionSections = this.submissionService.getSubmissionObject(this.submissionId) - .filter(() => this.isActive) - .map((submission: SubmissionObjectEntry) => submission.isLoading) - .map((isLoading: boolean) => isLoading) - .distinctUntilChanged() - .flatMap((isLoading: boolean) => { + this.submissionSections = this.submissionService.getSubmissionObject(this.submissionId).pipe( + filter(() => this.isActive), + map((submission: SubmissionObjectEntry) => submission.isLoading), + map((isLoading: boolean) => isLoading), + distinctUntilChanged(), + flatMap((isLoading: boolean) => { if (!isLoading) { return this.getSectionsList(); } else { - return Observable.of([]) + return observableOf([]) } - }); + })); - this.loading = this.submissionService.getSubmissionObject(this.submissionId) - .filter(() => this.isActive) - .map((submission: SubmissionObjectEntry) => submission.isLoading) - .map((isLoading: boolean) => isLoading) - .distinctUntilChanged(); + this.loading = this.submissionService.getSubmissionObject(this.submissionId).pipe( + filter(() => this.isActive), + map((submission: SubmissionObjectEntry) => submission.isLoading), + map((isLoading: boolean) => isLoading), + distinctUntilChanged()); this.subs.push( - this.halService.getEndpoint('workspaceitems') - .filter((href: string) => isNotEmpty(href)) - .distinctUntilChanged() + this.halService.getEndpoint('workspaceitems').pipe( + filter((href: string) => isNotEmpty(href)), + distinctUntilChanged()) .subscribe((endpointURL) => { this.uploadFilesOptions.authToken = this.authService.buildAuthHeader(); this.uploadFilesOptions.url = endpointURL.concat(`/${this.submissionId}`); @@ -123,8 +124,8 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { } protected getSectionsList(): Observable<any> { - return this.submissionService.getSubmissionSections(this.submissionId) - .filter((sections: SectionDataObject[]) => isNotEmpty(sections)) - .map((sections: SectionDataObject[]) => sections); + return this.submissionService.getSubmissionSections(this.submissionId).pipe( + filter((sections: SectionDataObject[]) => isNotEmpty(sections)), + map((sections: SectionDataObject[]) => sections)); } } diff --git a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts index b474a56e9d033bfd4fff66986dc4b4bf55b120aa..13a33b52a7c4d6849e6918d32c72a8af59ab6a91 100644 --- a/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts +++ b/src/app/submission/form/submission-upload-files/submission-upload-files.component.ts @@ -1,7 +1,8 @@ import { Component, Input, OnChanges } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { Observable } from 'rxjs/Observable'; +import { Observable, of as observableOf } from 'rxjs'; +import { first } from 'rxjs/operators'; import { SectionsService } from '../../sections/sections.service'; import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util'; @@ -30,7 +31,7 @@ export class SubmissionUploadFilesComponent implements OnChanges { public dropMsg = 'submission.sections.upload.drop-message'; private subs = []; - private uploadEnabled: Observable<boolean> = Observable.of(false); + private uploadEnabled: Observable<boolean> = observableOf(false); public onBeforeUpload = () => { this.operationsService.jsonPatchByResourceType( @@ -55,7 +56,7 @@ export class SubmissionUploadFilesComponent implements OnChanges { // Checks if upload section is enabled so do upload this.subs.push( this.uploadEnabled - .first() + .pipe(first()) .subscribe((isUploadEnabled) => { if (isUploadEnabled) { diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index 1e0c9063d4785fa9b47bf6c495706ade4fee2b40..3b305f1bff999b6f6112dee9d57cbb7959fe2726 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -1,6 +1,9 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect } from '@ngrx/effects'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { from as observableFrom, of as observableOf } from 'rxjs'; +import { catchError, map, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; import { union } from 'lodash'; import { @@ -28,11 +31,9 @@ import { import { SectionsService } from '../sections/sections.service'; import { isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; import { Workspaceitem } from '../../core/submission/models/workspaceitem.model'; -import { Observable } from 'rxjs/Observable'; import { JsonPatchOperationsService } from '../../core/json-patch/json-patch-operations.service'; import { SubmitDataResponseDefinitionObject } from '../../core/shared/submit-data-response-definition.model'; import { SubmissionService } from '../submission.service'; -import { Store } from '@ngrx/store'; import { Workflowitem } from '../../core/submission/models/workflowitem.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { SubmissionObject } from '../../core/submission/models/submission-object.model'; @@ -48,9 +49,9 @@ import { SectionsType } from '../sections/sections-type'; @Injectable() export class SubmissionObjectEffects { - @Effect() loadForm$ = this.actions$ - .ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM) - .map((action: InitSubmissionFormAction) => { + @Effect() loadForm$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM), + map((action: InitSubmissionFormAction) => { const definition = action.payload.submissionDefinition; const mappedActions = []; definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel) => { @@ -75,17 +76,17 @@ export class SubmissionObjectEffects { ) }); return {action: action, definition: definition, mappedActions: mappedActions}; - }) - .mergeMap((result) => { - return Observable.from( + }), + mergeMap((result) => { + return observableFrom( result.mappedActions.concat( new CompleteInitSubmissionFormAction(result.action.payload.submissionId) )); - }); + })); - @Effect() resetForm$ = this.actions$ - .ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM) - .map((action: ResetSubmissionFormAction) => + @Effect() resetForm$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM), + map((action: ResetSubmissionFormAction) => new InitSubmissionFormAction( action.payload.collectionId, action.payload.submissionId, @@ -93,108 +94,108 @@ export class SubmissionObjectEffects { action.payload.submissionDefinition, action.payload.sections, null - )); + ))); - @Effect() saveSubmission$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM) - .switchMap((action: SaveSubmissionFormAction) => { + @Effect() saveSubmission$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM), + switchMap((action: SaveSubmissionFormAction) => { return this.operationsService.jsonPatchByResourceType( this.submissionService.getSubmissionObjectLinkName(), action.payload.submissionId, - 'sections') - .map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response)) - .catch(() => Observable.of(new SaveSubmissionFormErrorAction(action.payload.submissionId))); - }); - - @Effect() saveForLaterSubmission$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM) - .switchMap((action: SaveForLaterSubmissionFormAction) => { + 'sections').pipe( + map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response)), + catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId)))); + })); + + @Effect() saveForLaterSubmission$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM), + switchMap((action: SaveForLaterSubmissionFormAction) => { return this.operationsService.jsonPatchByResourceType( this.submissionService.getSubmissionObjectLinkName(), action.payload.submissionId, - 'sections') - .map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)) - .catch(() => Observable.of(new SaveSubmissionFormErrorAction(action.payload.submissionId))); - }); - - @Effect() saveSubmissionSuccess$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS) - .withLatestFrom(this.store$) - .map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => { + 'sections').pipe( + map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)), + catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId)))); + })); + + @Effect() saveSubmissionSuccess$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS), + withLatestFrom(this.store$), + map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => { return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId); - }) - .mergeMap((actions) => Observable.from(actions)); + }), + mergeMap((actions) => observableFrom(actions))); - @Effect() saveSection$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM) - .switchMap((action: SaveSubmissionSectionFormAction) => { + @Effect() saveSection$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM), + switchMap((action: SaveSubmissionSectionFormAction) => { return this.operationsService.jsonPatchByResourceID( this.submissionService.getSubmissionObjectLinkName(), action.payload.submissionId, 'sections', - action.payload.sectionId) - .map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)) - .catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))); - }); - - @Effect() saveAndDepositSection$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION) - .withLatestFrom(this.store$) - .switchMap(([action, currentState]: [SaveAndDepositSubmissionAction, any]) => { + action.payload.sectionId).pipe( + map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)), + catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId)))); + })); + + @Effect() saveAndDepositSection$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION), + withLatestFrom(this.store$), + switchMap(([action, currentState]: [SaveAndDepositSubmissionAction, any]) => { return this.operationsService.jsonPatchByResourceType( this.submissionService.getSubmissionObjectLinkName(), action.payload.submissionId, - 'sections') - .map((response: SubmissionObject[]) => { + 'sections').pipe( + map((response: SubmissionObject[]) => { if (this.canDeposit(response)) { return new DepositSubmissionAction(action.payload.submissionId); } else { this.notificationsService.warning(null, this.translate.get('submission.sections.general.sections_not_valid')); return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], response, action.payload.submissionId); } - }) - .catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))); - }); - - @Effect() depositSubmission$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION) - .withLatestFrom(this.store$) - .switchMap(([action, state]: [DepositSubmissionAction, any]) => { - return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl) - .map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)) - .catch(() => Observable.of(new DepositSubmissionErrorAction(action.payload.submissionId))); - }); - - @Effect({dispatch: false}) SaveForLaterSubmissionSuccess$ = this.actions$ - .ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS) - .do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))) - .do(() => this.submissionService.redirectToMyDSpace()); - - @Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS) - .do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))) - .do(() => this.submissionService.redirectToMyDSpace()); - - @Effect({dispatch: false}) depositSubmissionError$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR) - .do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))); - - @Effect() discardSubmission$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION) - .switchMap((action: DepositSubmissionAction) => { - return this.submissionService.discardSubmission(action.payload.submissionId) - .map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)) - .catch(() => Observable.of(new DiscardSubmissionErrorAction(action.payload.submissionId))); - }); - - @Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS) - .do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))) - .do(() => this.submissionService.redirectToMyDSpace()); - - @Effect({dispatch: false}) discardSubmissionError$ = this.actions$ - .ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR) - .do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))); + }), + catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId)))); + })); + + @Effect() depositSubmission$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION), + withLatestFrom(this.store$), + switchMap(([action, state]: [DepositSubmissionAction, any]) => { + return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl).pipe( + map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)), + catchError(() => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId)))); + })); + + @Effect({dispatch: false}) SaveForLaterSubmissionSuccess$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS), + tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))), + tap(() => this.submissionService.redirectToMyDSpace())); + + @Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS), + tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))), + tap(() => this.submissionService.redirectToMyDSpace())); + + @Effect({dispatch: false}) depositSubmissionError$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR), + tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice')))); + + @Effect() discardSubmission$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION), + switchMap((action: DepositSubmissionAction) => { + return this.submissionService.discardSubmission(action.payload.submissionId).pipe( + map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)), + catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId)))); + })); + + @Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS), + tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))), + tap(() => this.submissionService.redirectToMyDSpace())); + + @Effect({dispatch: false}) discardSubmissionError$ = this.actions$.pipe( + ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR), + tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')))); constructor(private actions$: Actions, private notificationsService: NotificationsService, diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 46eea15fac63971217fb6aa42d083a1b5e22ff55..a57fb60fafcea9f8c3e1b0d6c6d09d5faa3b1be5 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -1,8 +1,8 @@ -import { ChangeDetectorRef, Component, Inject, OnDestroy, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core'; import { DynamicFormControlEvent, DynamicFormControlModel } from '@ng-dynamic-forms/core'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; +import { Observable, Subscription } from 'rxjs'; +import { distinctUntilChanged, filter, flatMap, map, take, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { isEqual } from 'lodash'; @@ -70,12 +70,29 @@ export class FormSectionComponent extends SectionModelComponent { this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id); this.formId = this.formService.getUniqueId(this.sectionData.id); - this.formConfigService.getConfigByHref(this.sectionData.config) - .map((config: ConfigData) => config.payload) + this.formConfigService.getConfigByHref(this.sectionData.config).pipe( + map((configData: ConfigData) => configData.payload), + tap((config: SubmissionFormsModel) => this.formConfig = config), + flatMap((config: ConfigData) => this.sectionService.getSectionData(this.submissionId, this.sectionData.id)), + take(1)) + .subscribe((sectionData: WorkspaceitemSectionDataType) => { + if (isUndefined(this.formModel)) { + this.sectionData.errors = []; + // Is the first loading so init form + this.initForm(sectionData); + this.sectionData.data = sectionData; + this.subscriptions(); + this.isLoading = false; + this.cdr.detectChanges(); + } + }) + +/* this.formConfigService.getConfigByHref(this.sectionData.config).pipe( + map((config: ConfigData) => config.payload)) .subscribe((config: SubmissionFormsModel) => { this.formConfig = config; - this.sectionService.getSectionData(this.submissionId, this.sectionData.id) - .take(1) + this.sectionService.getSectionData(this.submissionId, this.sectionData.id).pipe( + take(1)) .subscribe((sectionData: WorkspaceitemSectionDataType) => { if (isUndefined(this.formModel)) { this.sectionData.errors = []; @@ -87,7 +104,7 @@ export class FormSectionComponent extends SectionModelComponent { this.cdr.detectChanges(); } }) - }); + });*/ } onSectionDestroy() { @@ -142,7 +159,7 @@ export class FormSectionComponent extends SectionModelComponent { if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data) && this.hasMetadataEnrichment(sectionData)) { this.translate.get('submission.sections.general.metadata-extracted', {sectionId: this.sectionData.id}) - .take(1) + .pipe(take(1)) .subscribe((m) => { this.notificationsService.info(null, m, null, true); }); @@ -161,9 +178,9 @@ export class FormSectionComponent extends SectionModelComponent { } checksForErrors(errors: SubmissionSectionError[]) { - this.formService.isFormInitialized(this.formId) - .filter((status: boolean) => status === true && !this.isUpdating) - .take(1) + this.formService.isFormInitialized(this.formId).pipe( + filter((status: boolean) => status === true && !this.isUpdating), + take(1)) .subscribe(() => { this.sectionService.checkSectionErrors(this.submissionId, this.sectionData.id, this.formId, errors, this.sectionData.errors); this.sectionData.errors = errors; @@ -177,19 +194,19 @@ export class FormSectionComponent extends SectionModelComponent { /** * Subscribe to form's data */ - this.formService.getFormData(this.formId) - .distinctUntilChanged() + this.formService.getFormData(this.formId).pipe( + distinctUntilChanged()) .subscribe((formData) => { this.formData = formData; }), /** * Subscribe to section state */ - this.sectionService.getSectionState(this.submissionId, this.sectionData.id) - .filter((sectionState: SubmissionSectionObject) => { + this.sectionService.getSectionState(this.submissionId, this.sectionData.id).pipe( + filter((sectionState: SubmissionSectionObject) => { return isNotEmpty(sectionState) && (isNotEmpty(sectionState.data) || isNotEmpty(sectionState.errors)) - }) - .distinctUntilChanged() + }), + distinctUntilChanged()) .subscribe((sectionState: SubmissionSectionObject) => { this.updateForm(sectionState.data, sectionState.errors); }) diff --git a/src/app/submission/sections/license/section-license.component.ts b/src/app/submission/sections/license/section-license.component.ts index 5aea0b313f781fd07c0491a687f83e6bfeaeaa9b..31021e34db4fb4f78f76b49c8228461b9c2aca63 100644 --- a/src/app/submission/sections/license/section-license.component.ts +++ b/src/app/submission/sections/license/section-license.component.ts @@ -1,8 +1,8 @@ -import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core'; +import { Observable, Subscription } from 'rxjs'; +import { distinctUntilChanged, filter, flatMap, map, take } from 'rxjs/operators'; import { DynamicCheckboxModel, DynamicFormControlEvent, DynamicFormControlModel } from '@ng-dynamic-forms/core'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; import { SectionModelComponent } from '../models/section.model'; import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; @@ -63,11 +63,11 @@ export class LicenseSectionComponent extends SectionModelComponent { const model = this.formBuilderService.findById('granted', this.formModel); this.subs.push( - this.collectionDataService.findById(this.collectionId) - .filter((collectionData: RemoteData<Collection>) => isNotUndefined((collectionData.payload))) - .flatMap((collectionData: RemoteData<Collection>) => collectionData.payload.license) - .filter((licenseData: RemoteData<License>) => isNotUndefined((licenseData.payload))) - .take(1) + this.collectionDataService.findById(this.collectionId).pipe( + filter((collectionData: RemoteData<Collection>) => isNotUndefined((collectionData.payload))), + flatMap((collectionData: RemoteData<Collection>) => collectionData.payload.license), + filter((licenseData: RemoteData<License>) => isNotUndefined((licenseData.payload))), + take(1)) .subscribe((licenseData: RemoteData<License>) => { this.licenseText = licenseData.payload.text; @@ -79,18 +79,22 @@ export class LicenseSectionComponent extends SectionModelComponent { } // Disable checkbox whether it's in workflow or item scope - this.sectionService.isSectionReadOnly(this.submissionId, this.sectionData.id, this.submissionService.getSubmissionScope()) - .take(1) - .filter((isReadOnly) => isReadOnly) + this.sectionService.isSectionReadOnly( + this.submissionId, + this.sectionData.id, + this.submissionService.getSubmissionScope() + ).pipe( + take(1), + filter((isReadOnly) => isReadOnly)) .subscribe(() => { model.disabled = true; }); this.changeDetectorRef.detectChanges(); }), - this.sectionService.getSectionErrors(this.submissionId, this.sectionData.id) - .filter((errors) => isNotEmpty(errors)) - .distinctUntilChanged() + this.sectionService.getSectionErrors(this.submissionId, this.sectionData.id).pipe( + filter((errors) => isNotEmpty(errors)), + distinctUntilChanged()) .subscribe((errors) => { // parse errors const newErrors = errors.map((error) => { @@ -122,8 +126,8 @@ export class LicenseSectionComponent extends SectionModelComponent { protected getSectionStatus(): Observable<boolean> { const model = this.formBuilderService.findById('granted', this.formModel); - return (model as DynamicCheckboxModel).valueUpdates - .map((value) => value === true); + return (model as DynamicCheckboxModel).valueUpdates.pipe( + map((value) => value === true)); } onChange(event: DynamicFormControlEvent) { diff --git a/src/app/submission/sections/models/section.model.ts b/src/app/submission/sections/models/section.model.ts index 3830e202a27c70ee8204d57bae3749c42a98219e..016ce620671f36b1edcc49fa186ee8571d465f95 100644 --- a/src/app/submission/sections/models/section.model.ts +++ b/src/app/submission/sections/models/section.model.ts @@ -1,9 +1,11 @@ import { Inject, OnDestroy, OnInit } from '@angular/core'; + +import { Observable, Subscription } from 'rxjs'; +import { filter, startWith } from 'rxjs/operators'; + import { SectionDataObject } from './section-data.model'; -import { Observable } from 'rxjs/Observable'; import { SectionsService } from '../sections.service'; import { hasValue, isNotUndefined } from '../../../shared/empty.util'; -import { Subscription } from 'rxjs/Subscription'; export interface SectionDataModel { sectionData: SectionDataObject @@ -38,9 +40,9 @@ export abstract class SectionModelComponent implements OnDestroy, OnInit, Sectio protected abstract onSectionDestroy(): void; protected updateSectionStatus(): void { - this.sectionStatusSub = this.getSectionStatus() - .filter((sectionStatus: boolean) => isNotUndefined(sectionStatus)) - .startWith(true) + this.sectionStatusSub = this.getSectionStatus().pipe( + filter((sectionStatus: boolean) => isNotUndefined(sectionStatus)), + startWith(true)) .subscribe((sectionStatus: boolean) => { this.sectionService.setSectionStatus(this.submissionId, this.sectionData.id, sectionStatus); }); diff --git a/src/app/submission/sections/sections.directive.ts b/src/app/submission/sections/sections.directive.ts index 797020e3a26e2b2d9dc3e2992d59369fccf37bc6..3ad8237ce448d2b71f0c01fc0248df0f9c46e7e8 100644 --- a/src/app/submission/sections/sections.directive.ts +++ b/src/app/submission/sections/sections.directive.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Directive, Input, OnDestroy, OnInit } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; +import { Observable, Subscription } from 'rxjs'; +import { map } from 'rxjs/operators'; import { uniq } from 'lodash'; import { SectionsService } from './sections.service'; @@ -33,17 +33,17 @@ export class SectionsDirective implements OnDestroy, OnInit { } ngOnInit() { - this.valid = this.sectionService.isSectionValid(this.submissionId, this.sectionId) - .map((valid: boolean) => { + this.valid = this.sectionService.isSectionValid(this.submissionId, this.sectionId).pipe( + map((valid: boolean) => { if (valid) { this.resetErrors(); } return valid; - }); + })); this.subs.push( - this.sectionService.getSectionState(this.submissionId, this.sectionId) - .map((state: SubmissionSectionObject) => state.errors) + this.sectionService.getSectionState(this.submissionId, this.sectionId).pipe( + map((state: SubmissionSectionObject) => state.errors)) .subscribe((errors: SubmissionSectionError[]) => { if (isNotEmpty(errors)) { errors.forEach((errorItem: SubmissionSectionError) => { diff --git a/src/app/submission/sections/sections.service.ts b/src/app/submission/sections/sections.service.ts index 0edc968f82fb10335cab645efbd84ef76b24b5b8..e1a92cc07e699771da62ee8a1fa145db494f1364 100644 --- a/src/app/submission/sections/sections.service.ts +++ b/src/app/submission/sections/sections.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; +import { combineLatest, Observable } from 'rxjs'; +import { distinctUntilChanged, filter, map, take } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; import { ScrollToConfigOptions, ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; @@ -92,58 +93,58 @@ export class SectionsService { } public getSectionData(submissionId: string, sectionId: string): Observable<WorkspaceitemSectionDataType> { - return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)) - .distinctUntilChanged(); + return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)).pipe( + distinctUntilChanged()); } public getSectionErrors(submissionId: string, sectionId: string): Observable<SubmissionSectionError[]> { - return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)) - .distinctUntilChanged(); + return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)).pipe( + distinctUntilChanged()); } public getSectionState(submissionId: string, sectionId: string): Observable<SubmissionSectionObject> { - return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) - .filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)) - .map((sectionObj: SubmissionSectionObject) => sectionObj) - .distinctUntilChanged(); + return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe( + filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)), + map((sectionObj: SubmissionSectionObject) => sectionObj), + distinctUntilChanged()); } public isSectionValid(submissionId: string, sectionId: string): Observable<boolean> { - return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) - .filter((sectionObj) => hasValue(sectionObj)) - .map((sectionObj: SubmissionSectionObject) => sectionObj.isValid) - .distinctUntilChanged(); + return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe( + filter((sectionObj) => hasValue(sectionObj)), + map((sectionObj: SubmissionSectionObject) => sectionObj.isValid), + distinctUntilChanged()); } public isSectionActive(submissionId: string, sectionId: string): Observable<boolean> { - return this.submissionService.getActiveSectionId(submissionId) - .map((activeSectionId: string) => sectionId === activeSectionId) - .distinctUntilChanged(); + return this.submissionService.getActiveSectionId(submissionId).pipe( + map((activeSectionId: string) => sectionId === activeSectionId), + distinctUntilChanged()); } public isSectionEnabled(submissionId: string, sectionId: string): Observable<boolean> { - return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) - .filter((sectionObj) => hasValue(sectionObj)) - .map((sectionObj: SubmissionSectionObject) => sectionObj.enabled) - .distinctUntilChanged(); + return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe( + filter((sectionObj) => hasValue(sectionObj)), + map((sectionObj: SubmissionSectionObject) => sectionObj.enabled), + distinctUntilChanged()); } public isSectionReadOnly(submissionId: string, sectionId: string, submissionScope: SubmissionScopeType): Observable<boolean> { - return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) - .filter((sectionObj) => hasValue(sectionObj)) - .map((sectionObj: SubmissionSectionObject) => { + return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe( + filter((sectionObj) => hasValue(sectionObj)), + map((sectionObj: SubmissionSectionObject) => { return sectionObj.visibility.other === 'READONLY' && submissionScope !== SubmissionScopeType.WorkspaceItem - }) - .distinctUntilChanged(); + }), + distinctUntilChanged()); } public isSectionAvailable(submissionId: string, sectionId: string): Observable<boolean> { - return this.store.select(submissionObjectFromIdSelector(submissionId)) - .filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)) - .map((submissionState: SubmissionObjectEntry) => { + return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe( + filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)), + map((submissionState: SubmissionObjectEntry) => { return isNotUndefined(submissionState.sections) && isNotUndefined(submissionState.sections[sectionId]); - }) - .distinctUntilChanged(); + }), + distinctUntilChanged()); } public addSection(submissionId: string, @@ -166,13 +167,13 @@ export class SectionsService { const isAvailable$ = this.isSectionAvailable(submissionId, sectionId); const isEnabled$ = this.isSectionEnabled(submissionId, sectionId); - Observable.combineLatest(isAvailable$, isEnabled$) - .take(1) - .filter(([available, enabled]: [boolean, boolean]) => available) + combineLatest(isAvailable$, isEnabled$).pipe( + take(1), + filter(([available, enabled]: [boolean, boolean]) => available)) .subscribe(([available, enabled]: [boolean, boolean]) => { if (!enabled) { this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}) - .take(1) + .pipe(take(1)) .subscribe((m) => { this.notificationsService.info(null, m, null, true); }); diff --git a/src/app/submission/sections/upload/accessConditions/accessConditions.component.ts b/src/app/submission/sections/upload/accessConditions/accessConditions.component.ts index d05da19b0ee722acadf39e999131a3523bc71913..24a735d1e82fae7d399bf15a6121729d0d1bad4b 100644 --- a/src/app/submission/sections/upload/accessConditions/accessConditions.component.ts +++ b/src/app/submission/sections/upload/accessConditions/accessConditions.component.ts @@ -1,4 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; + +import { filter, first } from 'rxjs/operators'; + import { GroupEpersonService } from '../../../../core/eperson/group-eperson.service'; import { ResourcePolicy } from '../../../../core/shared/resource-policy.model'; import { isEmpty } from '../../../../shared/empty.util'; @@ -20,9 +23,9 @@ export class AccessConditionsComponent implements OnInit { ngOnInit() { this.accessConditions.forEach((accessCondition: ResourcePolicy) => { if (isEmpty(accessCondition.name)) { - this.groupService.findById(accessCondition.groupUUID) - .filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded) - .take(1) + this.groupService.findById(accessCondition.groupUUID).pipe( + filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded), + first()) .subscribe((rd: RemoteData<Group>) => { const group: Group = rd.payload; const accessConditionEntry = Object.assign({}, accessCondition); diff --git a/src/app/submission/sections/upload/file/file.component.ts b/src/app/submission/sections/upload/file/file.component.ts index b0f79a8a9870335da5fe969b09b7c81b819c3e95..489dd858674a01a4265c81da01807ecee6d4275d 100644 --- a/src/app/submission/sections/upload/file/file.component.ts +++ b/src/app/submission/sections/upload/file/file.component.ts @@ -17,6 +17,7 @@ import { SubmitDataResponseDefinitionObject } from '../../../../core/shared/subm import { SubmissionService } from '../../../submission.service'; import { FileService } from '../../../../core/shared/file.service'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; +import { filter, first } from 'rxjs/operators'; @Component({ selector: 'ds-submission-upload-section-file', @@ -62,8 +63,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { // Retrieve file state this.subscriptions.push( this.uploadService - .getFileData(this.submissionId, this.sectionId, this.fileId) - .filter((bitstream) => isNotUndefined(bitstream)) + .getFileData(this.submissionId, this.sectionId, this.fileId).pipe( + filter((bitstream) => isNotUndefined(bitstream))) .subscribe((bitstream) => { this.fileData = bitstream; } @@ -99,8 +100,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { } public downloadBitstreamFile() { - this.halService.getEndpoint('bitstreams') - .first() + this.halService.getEndpoint('bitstreams').pipe( + first()) .subscribe((url) => { const fileUrl = `${url}/${this.fileData.uuid}/content`; this.fileService.downloadFile(fileUrl); @@ -110,8 +111,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { public saveBitstreamData(event) { event.preventDefault(); this.subscriptions.push( - this.formService.getFormData(this.formId) - .take(1) + this.formService.getFormData(this.formId).pipe( + first()) .subscribe((formData: any) => { Object.keys((formData.metadata)) .filter((key) => isNotEmpty(formData.metadata[key])) diff --git a/src/app/submission/sections/upload/section-upload.component.ts b/src/app/submission/sections/upload/section-upload.component.ts index dd127054d53de69cad0fb337ce664332ccf18af6..0006fa1420763bf60bd7e2ad7eab901c4f401610 100644 --- a/src/app/submission/sections/upload/section-upload.component.ts +++ b/src/app/submission/sections/upload/section-upload.component.ts @@ -1,6 +1,7 @@ -import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; +import { combineLatest, forkJoin as observableForkJoin, Observable } from 'rxjs'; +import { distinctUntilChanged, filter, flatMap, map, take } from 'rxjs/operators'; import { SectionModelComponent } from '../models/section.model'; import { hasValue, isNotEmpty, isNotUndefined, isUndefined } from '../../../shared/empty.util'; @@ -79,30 +80,30 @@ export class UploadSectionComponent extends SectionModelComponent { } onSectionInit() { - const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config) - .map((config) => config.payload); + const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config).pipe( + map((config) => config.payload)); - this.configMetadataForm$ = config$ - .take(1) - .map((config: SubmissionUploadsModel) => config.metadata); + this.configMetadataForm$ = config$.pipe( + take(1), + map((config: SubmissionUploadsModel) => config.metadata)); this.subs.push( - this.submissionService.getSubmissionObject(this.submissionId) - .filter((submissionObject: SubmissionObjectEntry) => isNotUndefined(submissionObject) && !submissionObject.isLoading) - .filter((submissionObject: SubmissionObjectEntry) => isUndefined(this.collectionId) || this.collectionId !== submissionObject.collection) + this.submissionService.getSubmissionObject(this.submissionId).pipe( + filter((submissionObject: SubmissionObjectEntry) => isNotUndefined(submissionObject) && !submissionObject.isLoading), + filter((submissionObject: SubmissionObjectEntry) => isUndefined(this.collectionId) || this.collectionId !== submissionObject.collection)) .subscribe((submissionObject: SubmissionObjectEntry) => { this.collectionId = submissionObject.collection; - this.collectionDataService.findById(this.collectionId) - .filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload))) - .take(1) + this.collectionDataService.findById(this.collectionId).pipe( + filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload))), + take(1)) .subscribe((collectionRemoteData: RemoteData<Collection>) => { this.collectionName = collectionRemoteData.payload.name; // Default Access Conditions - this.subs.push(collectionRemoteData.payload.defaultAccessConditions - .filter((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => - defaultAccessConditionsRemoteData.hasSucceeded) - .take(1) + this.subs.push(collectionRemoteData.payload.defaultAccessConditions.pipe( + filter((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => + defaultAccessConditionsRemoteData.hasSucceeded), + take(1)) .subscribe((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => { if (isNotEmpty(defaultAccessConditionsRemoteData.payload)) { @@ -111,8 +112,8 @@ export class UploadSectionComponent extends SectionModelComponent { } // Edit Form Configuration, access policy list - this.subs.push(config$ - .take(1) + this.subs.push(config$.pipe( + take(1)) .subscribe((config: SubmissionUploadsModel) => { this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : []; @@ -127,16 +128,16 @@ export class UploadSectionComponent extends SectionModelComponent { this.availableAccessConditionOptions.forEach((accessCondition: AccessConditionOption) => { if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) { groupsObs.push( - this.groupService.findById(accessCondition.groupUUID) - .filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded) - .take(1) + this.groupService.findById(accessCondition.groupUUID).pipe( + filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded), + take(1)) ); } }); let obsCounter = 1; - Observable.forkJoin(groupsObs) - .flatMap((group) => group) - .take(groupsObs.length) + observableForkJoin(groupsObs).pipe( + flatMap((group) => group), + take(groupsObs.length)) .subscribe((rd: RemoteData<Group>) => { const group: Group = rd.payload; if (isUndefined(this.availableGroups.get(group.uuid))) { @@ -161,12 +162,12 @@ export class UploadSectionComponent extends SectionModelComponent { }) }) , - Observable.combineLatest(this.configMetadataForm$, - this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id)) - .filter(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => { + combineLatest(this.configMetadataForm$, + this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id)).pipe( + filter(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => { return isNotEmpty(configMetadataForm) && isNotUndefined(fileList) - }) - .distinctUntilChanged() + }), + distinctUntilChanged()) .subscribe(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => { this.fileList = []; this.fileIndexes = []; @@ -198,8 +199,8 @@ export class UploadSectionComponent extends SectionModelComponent { } protected getSectionStatus(): Observable<boolean> { - return this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id) - .map((fileList: any[]) => (isNotUndefined(fileList) && fileList.length > 0)); + return this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id).pipe( + map((fileList: any[]) => (isNotUndefined(fileList) && fileList.length > 0))); } /** diff --git a/src/app/submission/sections/upload/section-upload.service.ts b/src/app/submission/sections/upload/section-upload.service.ts index 3e0a1735ef36a466d1d6552e9da4e608313daa09..ab18807fa53897ec5c7c0087b5d55b87468d8de4 100644 --- a/src/app/submission/sections/upload/section-upload.service.ts +++ b/src/app/submission/sections/upload/section-upload.service.ts @@ -1,12 +1,16 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; + +import { Observable } from 'rxjs'; +import { distinctUntilChanged, filter, map } from 'rxjs/operators'; import { Store } from '@ngrx/store'; + import { SubmissionState } from '../../submission.reducers'; -import { DeleteUploadedFileAction, EditFileDataAction, NewUploadedFileAction } from '../../objects/submission-objects.actions'; import { - submissionUploadedFileFromUuidSelector, - submissionUploadedFilesFromIdSelector -} from '../../selectors'; + DeleteUploadedFileAction, + EditFileDataAction, + NewUploadedFileAction +} from '../../objects/submission-objects.actions'; +import { submissionUploadedFileFromUuidSelector, submissionUploadedFilesFromIdSelector } from '../../selectors'; import { isUndefined } from '../../../shared/empty.util'; import { WorkspaceitemSectionUploadFileObject } from '../../../core/submission/models/workspaceitem-section-upload-file.model'; @@ -16,28 +20,28 @@ export class SectionUploadService { constructor(private store: Store<SubmissionState>) {} public getUploadedFileList(submissionId: string, sectionId: string): Observable<any> { - return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)) - .map((state) => state) - .distinctUntilChanged(); + return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)).pipe( + map((state) => state), + distinctUntilChanged()); } public getFileData(submissionId: string, sectionId: string, fileUuid: string): Observable<any> { - return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)) - .filter((state) => !isUndefined(state)) - .map((state) => { + return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)).pipe( + filter((state) => !isUndefined(state)), + map((state) => { let fileState; Object.keys(state) .filter((key) => state[key].uuid === fileUuid) .forEach((key) => fileState = state[key]); return fileState; - }) - .distinctUntilChanged(); + }), + distinctUntilChanged()); } public getDefaultPolicies(submissionId: string, sectionId: string, fileId: string): Observable<any> { - return this.store.select(submissionUploadedFileFromUuidSelector(submissionId, sectionId, fileId)) - .map((state) => state) - .distinctUntilChanged(); + return this.store.select(submissionUploadedFileFromUuidSelector(submissionId, sectionId, fileId)).pipe( + map((state) => state), + distinctUntilChanged()); } public addUploadedFile(submissionId: string, sectionId: string, fileId: string, data: WorkspaceitemSectionUploadFileObject) { diff --git a/src/app/submission/server-submission.service.ts b/src/app/submission/server-submission.service.ts index cf3500fb94a4d7f144cd11c7af29a51db9dcc579..bfb46f985b67f08a420b409feed617a2dcdb0584 100644 --- a/src/app/submission/server-submission.service.ts +++ b/src/app/submission/server-submission.service.ts @@ -1,17 +1,19 @@ import { Injectable } from '@angular/core'; + +import { Observable, of as observableOf } from 'rxjs'; + import { SubmissionService } from './submission.service'; import { SubmissionObject } from '../core/submission/models/submission-object.model'; -import { Observable } from 'rxjs/Observable'; @Injectable() export class ServerSubmissionService extends SubmissionService { createSubmission(): Observable<SubmissionObject> { - return Observable.of(null); + return observableOf(null); } retrieveSubmission(submissionId): Observable<SubmissionObject> { - return Observable.of(null); + return observableOf(null); } startAutoSave(submissionId) { diff --git a/src/app/submission/submission-rest.service.ts b/src/app/submission/submission-rest.service.ts index e415f8a3faca484ede9059a431ea6f7d6559a6ef..469ea80ac955359d448590b4f1cdd69f2158d990 100644 --- a/src/app/submission/submission-rest.service.ts +++ b/src/app/submission/submission-rest.service.ts @@ -1,11 +1,13 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; + +import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs'; +import { distinctUntilChanged, filter, flatMap, map, mergeMap, tap } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { ResponseCacheService } from '../core/cache/response-cache.service'; import { RequestService } from '../core/data/request.service'; import { ResponseCacheEntry } from '../core/cache/response-cache.reducer'; -import { ErrorResponse, RestResponse, SubmissionSuccessResponse } from '../core/cache/response-cache.models'; +import { SubmissionSuccessResponse } from '../core/cache/response-cache.models'; import { isNotEmpty } from '../shared/empty.util'; import { ConfigRequest, @@ -36,30 +38,55 @@ export class SubmissionRestService { } protected submitData(request: RestRequest): Observable<SubmitDataResponseDefinitionObject> { - const [successResponse, errorResponse] = this.responseCache.get(request.href) + const responses = this.responseCache.get(request.href).pipe(map((entry: ResponseCacheEntry) => entry.response)); + const errorResponses = responses.pipe( + filter((response: SubmissionSuccessResponse) => !response.isSuccessful), + mergeMap(() => observableThrowError(new Error(`Couldn't send data to server`))) + ); + const successResponses = responses.pipe( + filter((response: SubmissionSuccessResponse) => response.isSuccessful), + map((response: SubmissionSuccessResponse) => response.dataDefinition as any), + distinctUntilChanged() + ); + return observableMerge(errorResponses, successResponses); +/* const [successResponse, errorResponse] = this.responseCache.get(request.href) .map((entry: ResponseCacheEntry) => entry.response) .partition((response: RestResponse) => response.isSuccessful); return Observable.merge( errorResponse.flatMap((response: ErrorResponse) => - Observable.throw(new Error(`Couldn't send data to server`))), + observableThrowError(new Error(`Couldn't send data to server`))), successResponse .filter((response: SubmissionSuccessResponse) => isNotEmpty(response)) .map((response: SubmissionSuccessResponse) => response.dataDefinition) - .distinctUntilChanged()); + .distinctUntilChanged());*/ } protected fetchRequest(request: RestRequest): Observable<SubmitDataResponseDefinitionObject> { - const [successResponse, errorResponse] = this.responseCache.get(request.href) + const responses = this.responseCache.get(request.href).pipe( + map((entry: ResponseCacheEntry) => entry.response), + tap(() => this.responseCache.remove(request.href))); + const errorResponses = responses.pipe( + filter((response: SubmissionSuccessResponse) => !response.isSuccessful), + mergeMap(() => observableThrowError(new Error(`Couldn't retrieve the data`))) + ); + const successResponses = responses.pipe( + filter((response: SubmissionSuccessResponse) => response.isSuccessful && isNotEmpty(response)), + map((response: SubmissionSuccessResponse) => response.dataDefinition as any), + distinctUntilChanged() + ); + return observableMerge(errorResponses, successResponses); + +/* const [successResponse, errorResponse] = this.responseCache.get(request.href) .map((entry: ResponseCacheEntry) => entry.response) .do(() => this.responseCache.remove(request.href)) .partition((response: RestResponse) => response.isSuccessful); return Observable.merge( errorResponse.flatMap((response: ErrorResponse) => - Observable.throw(new Error(`Couldn't retrieve the data`))), + observableThrowError(new Error(`Couldn't retrieve the data`))), successResponse .filter((response: SubmissionSuccessResponse) => isNotEmpty(response)) .map((response: SubmissionSuccessResponse) => response.dataDefinition) - .distinctUntilChanged()); + .distinctUntilChanged());*/ } protected getEndpointByIDHref(endpoint, resourceID): string { @@ -67,14 +94,14 @@ export class SubmissionRestService { } public deleteById(scopeId: string, linkName?: string): Observable<SubmitDataResponseDefinitionObject> { - return this.halService.getEndpoint(linkName || this.linkPath) - .filter((href: string) => isNotEmpty(href)) - .distinctUntilChanged() - .map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) - .map((endpointURL: string) => new SubmissionDeleteRequest(this.requestService.generateRequestId(), endpointURL)) - .do((request: DeleteRequest) => this.requestService.configure(request)) - .flatMap((request: DeleteRequest) => this.submitData(request)) - .distinctUntilChanged(); + return this.halService.getEndpoint(linkName || this.linkPath).pipe( + filter((href: string) => isNotEmpty(href)), + distinctUntilChanged(), + map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)), + map((endpointURL: string) => new SubmissionDeleteRequest(this.requestService.generateRequestId(), endpointURL)), + tap((request: DeleteRequest) => this.requestService.configure(request)), + flatMap((request: DeleteRequest) => this.submitData(request)), + distinctUntilChanged()); } public getDataByHref(href: string, options?: HttpOptions): Observable<any> { @@ -85,36 +112,36 @@ export class SubmissionRestService { } public getDataById(linkName: string, id: string): Observable<any> { - return this.halService.getEndpoint(linkName) - .map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, id)) - .filter((href: string) => isNotEmpty(href)) - .distinctUntilChanged() - .map((endpointURL: string) => new SubmissionRequest(this.requestService.generateRequestId(), endpointURL)) - .do((request: RestRequest) => this.requestService.configure(request, true)) - .flatMap((request: RestRequest) => this.fetchRequest(request)) - .distinctUntilChanged(); + return this.halService.getEndpoint(linkName).pipe( + map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, id)), + filter((href: string) => isNotEmpty(href)), + distinctUntilChanged(), + map((endpointURL: string) => new SubmissionRequest(this.requestService.generateRequestId(), endpointURL)), + tap((request: RestRequest) => this.requestService.configure(request, true)), + flatMap((request: RestRequest) => this.fetchRequest(request)), + distinctUntilChanged()); } public postToEndpoint(linkName: string, body: any, scopeId?: string, options?: HttpOptions): Observable<SubmitDataResponseDefinitionObject> { - return this.halService.getEndpoint(linkName) - .filter((href: string) => isNotEmpty(href)) - .map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) - .distinctUntilChanged() - .map((endpointURL: string) => new SubmissionPostRequest(this.requestService.generateRequestId(), endpointURL, body, options)) - .do((request: PostRequest) => this.requestService.configure(request, true)) - .flatMap((request: PostRequest) => this.submitData(request)) - .distinctUntilChanged(); + return this.halService.getEndpoint(linkName).pipe( + filter((href: string) => isNotEmpty(href)), + map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)), + distinctUntilChanged(), + map((endpointURL: string) => new SubmissionPostRequest(this.requestService.generateRequestId(), endpointURL, body, options)), + tap((request: PostRequest) => this.requestService.configure(request, true)), + flatMap((request: PostRequest) => this.submitData(request)), + distinctUntilChanged()); } public patchToEndpoint(linkName: string, body: any, scopeId?: string): Observable<SubmitDataResponseDefinitionObject> { - return this.halService.getEndpoint(linkName) - .filter((href: string) => isNotEmpty(href)) - .map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) - .distinctUntilChanged() - .map((endpointURL: string) => new SubmissionPatchRequest(this.requestService.generateRequestId(), endpointURL, body)) - .do((request: PostRequest) => this.requestService.configure(request, true)) - .flatMap((request: PostRequest) => this.submitData(request)) - .distinctUntilChanged(); + return this.halService.getEndpoint(linkName).pipe( + filter((href: string) => isNotEmpty(href)), + map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)), + distinctUntilChanged(), + map((endpointURL: string) => new SubmissionPatchRequest(this.requestService.generateRequestId(), endpointURL, body)), + tap((request: PostRequest) => this.requestService.configure(request, true)), + flatMap((request: PostRequest) => this.submitData(request)), + distinctUntilChanged()); } } diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts index 0fa06943f614b48046e21b6e4ea140825acc9bc4..0d919d4adfc154413cc9ae33dcc1ec4b450a461e 100644 --- a/src/app/submission/submission.service.ts +++ b/src/app/submission/submission.service.ts @@ -1,16 +1,21 @@ import { Inject, Injectable } from '@angular/core'; +import { HttpHeaders } from '@angular/common/http'; import { Router } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; +import { Observable, of as observableOf, Subscription, timer as observableTimer } from 'rxjs'; +import { catchError, distinctUntilChanged, filter, first, map, startWith } from 'rxjs/operators'; import { Store } from '@ngrx/store'; +import { TranslateService } from '@ngx-translate/core'; +import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; import { submissionSelector, SubmissionState } from './submission.reducers'; import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util'; import { CancelSubmissionFormAction, ChangeSubmissionCollectionAction, - DiscardSubmissionAction, InitSubmissionFormAction, ResetSubmissionFormAction, + DiscardSubmissionAction, + InitSubmissionFormAction, + ResetSubmissionFormAction, SaveAndDepositSubmissionAction, SaveForLaterSubmissionFormAction, SaveSubmissionFormAction, @@ -18,13 +23,13 @@ import { } from './objects/submission-objects.actions'; import { SubmissionObjectEntry, - SubmissionSectionEntry, SubmissionSectionError, + SubmissionSectionEntry, + SubmissionSectionError, SubmissionSectionObject } from './objects/submission-objects.reducer'; import { submissionObjectFromIdSelector } from './selectors'; import { GlobalConfig } from '../../config/global-config.interface'; import { GLOBAL_CONFIG } from '../../config'; -import { HttpHeaders } from '@angular/common/http'; import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service'; import { SubmissionRestService } from './submission-rest.service'; import { SectionDataObject } from './sections/models/section-data.model'; @@ -32,9 +37,7 @@ import { SubmissionScopeType } from '../core/submission/submission-scope-type'; import { SubmissionObject } from '../core/submission/models/submission-object.model'; import { RouteService } from '../shared/services/route.service'; import { SectionsType } from './sections/sections-type'; -import { TranslateService } from '@ngx-translate/core'; import { NotificationsService } from '../shared/notifications/notifications.service'; -import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; import { SubmissionDefinitionsModel } from '../core/config/models/config-submission-definitions.model'; import { WorkspaceitemSectionsObject } from '../core/submission/models/workspaceitem-sections.model'; @@ -59,9 +62,9 @@ export class SubmissionService { } createSubmission(): Observable<SubmissionObject> { - return this.restService.postToEndpoint('workspaceitems', {}) - .map((workspaceitem: SubmissionObject) => workspaceitem[0]) - .catch(() => Observable.of({})) + return this.restService.postToEndpoint('workspaceitems', {}).pipe( + map((workspaceitem: SubmissionObject) => workspaceitem[0]), + catchError(() => observableOf({}))) } depositSubmission(selfUrl: string): Observable<any> { @@ -107,21 +110,21 @@ export class SubmissionService { } getActiveSectionId(submissionId: string): Observable<string> { - return this.getSubmissionObject(submissionId) - .map((submission: SubmissionObjectEntry) => submission.activeSection); + return this.getSubmissionObject(submissionId).pipe( + map((submission: SubmissionObjectEntry) => submission.activeSection)); } getSubmissionObject(submissionId: string): Observable<SubmissionObjectEntry> { - return this.store.select(submissionObjectFromIdSelector(submissionId)) - .filter((submission: SubmissionObjectEntry) => isNotUndefined(submission)) + return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe( + filter((submission: SubmissionObjectEntry) => isNotUndefined(submission))); } getSubmissionSections(submissionId: string): Observable<SectionDataObject[]> { - return this.getSubmissionObject(submissionId) - .filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading) - .take(1) - .map((submission: SubmissionObjectEntry) => submission.sections) - .map((sections: SubmissionSectionEntry) => { + return this.getSubmissionObject(submissionId).pipe( + filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading), + first(), + map((submission: SubmissionObjectEntry) => submission.sections), + map((sections: SubmissionSectionEntry) => { const availableSections: SectionDataObject[] = []; Object.keys(sections) .filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject)) @@ -137,16 +140,16 @@ export class SubmissionService { availableSections.push(sectionObject); }); return availableSections; - }) - .startWith([]) - .distinctUntilChanged(); + }), + startWith([]), + distinctUntilChanged()); } getDisabledSectionsList(submissionId: string): Observable<SectionDataObject[]> { - return this.getSubmissionObject(submissionId) - .filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading) - .map((submission: SubmissionObjectEntry) => submission.sections) - .map((sections: SubmissionSectionEntry) => { + return this.getSubmissionObject(submissionId).pipe( + filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading), + map((submission: SubmissionObjectEntry) => submission.sections), + map((sections: SubmissionSectionEntry) => { const disabledSections: SectionDataObject[] = []; Object.keys(sections) .filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject)) @@ -158,9 +161,9 @@ export class SubmissionService { disabledSections.push(sectionObject); }); return disabledSections; - }) - .startWith([]) - .distinctUntilChanged(); + }), + startWith([]), + distinctUntilChanged()); } getSubmissionObjectLinkName(): string { @@ -191,11 +194,11 @@ export class SubmissionService { } getSubmissionStatus(submissionId: string): Observable<boolean> { - return this.store.select(submissionSelector) - .map((submissions: SubmissionState) => submissions.objects[submissionId]) - .filter((item) => isNotUndefined(item) && isNotUndefined(item.sections)) - .map((item) => item.sections) - .map((sections) => { + return this.store.select(submissionSelector).pipe( + map((submissions: SubmissionState) => submissions.objects[submissionId]), + filter((item) => isNotUndefined(item) && isNotUndefined(item.sections)), + map((item) => item.sections), + map((sections) => { const states = []; if (isNotUndefined(sections)) { @@ -210,23 +213,23 @@ export class SubmissionService { } return !isEmpty(sections) && isEmpty(states); - }) - .distinctUntilChanged() - .startWith(false); + }), + distinctUntilChanged(), + startWith(false)); } getSubmissionSaveProcessingStatus(submissionId: string): Observable<boolean> { - return this.getSubmissionObject(submissionId) - .map((state: SubmissionObjectEntry) => state.savePending) - .distinctUntilChanged() - .startWith(false); + return this.getSubmissionObject(submissionId).pipe( + map((state: SubmissionObjectEntry) => state.savePending), + distinctUntilChanged(), + startWith(false)); } getSubmissionDepositProcessingStatus(submissionId: string): Observable<boolean> { - return this.getSubmissionObject(submissionId) - .map((state: SubmissionObjectEntry) => state.depositPending) - .distinctUntilChanged() - .startWith(false); + return this.getSubmissionObject(submissionId).pipe( + map((state: SubmissionObjectEntry) => state.depositPending), + distinctUntilChanged(), + startWith(false)); } isSectionHidden(sectionData: SubmissionSectionObject) { @@ -237,14 +240,14 @@ export class SubmissionService { } isSubmissionLoading(submissionId: string): Observable<boolean> { - return this.getSubmissionObject(submissionId) - .map((submission: SubmissionObjectEntry) => submission.isLoading) - .distinctUntilChanged() + return this.getSubmissionObject(submissionId).pipe( + map((submission: SubmissionObjectEntry) => submission.isLoading), + distinctUntilChanged()); } notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) { - this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}) - .take(1) + this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}).pipe( + first()) .subscribe((m) => { this.notificationsService.info(null, m, null, true); }); @@ -274,10 +277,10 @@ export class SubmissionService { } retrieveSubmission(submissionId): Observable<SubmissionObject> { - return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId) - .filter((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)) - .take(1) - .map((submissionObjects: SubmissionObject[]) => submissionObjects[0]); + return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId).pipe( + filter((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)), + first(), + map((submissionObjects: SubmissionObject[]) => submissionObjects[0])); } setActiveSection(submissionId, sectionId) { @@ -291,7 +294,7 @@ export class SubmissionService { // Retrieve interval from config and convert to milliseconds const duration = this.EnvConfig.submission.autosave.timer * (1000 * 60); // Dispatch save action after given duration - this.timerObs = Observable.timer(duration, duration); + this.timerObs = observableTimer(duration, duration); this.autoSaveSub = this.timerObs .subscribe(() => this.store.dispatch(new SaveSubmissionFormAction(submissionId))); } diff --git a/src/app/submission/submit/submission-submit.component.ts b/src/app/submission/submit/submission-submit.component.ts index 9e5aa14c2a34724b1cb85252a5c2a64d5a029bb0..2354c2b8abeea686a085ba999f9544579fc7e35c 100644 --- a/src/app/submission/submit/submission-submit.component.ts +++ b/src/app/submission/submit/submission-submit.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewContainerRef } from '@angular/core'; import { Router } from '@angular/router'; -import { Subscription } from 'rxjs/Subscription'; +import { Subscription } from 'rxjs'; import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model';