Fix Pipeable operators

This commit is contained in:
Giuseppe Digilio
2018-12-16 20:22:01 +01:00
parent 7407740e3b
commit 3b2aebb649
35 changed files with 484 additions and 414 deletions

View File

@@ -1,4 +1,4 @@
import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { cold, getTestScheduler } from 'jasmine-marbles';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { getMockRequestService } from '../../shared/mocks/mock-request.service'; import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';

View File

@@ -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 { distinctUntilChanged, filter, map, mergeMap, tap } from 'rxjs/operators';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';

View File

@@ -1,5 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Effect, Actions } from '@ngrx/effects';
import { map } from 'rxjs/operators';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { import {
CommitPatchOperationsAction, FlushPatchOperationsAction, CommitPatchOperationsAction, FlushPatchOperationsAction,
@@ -9,11 +11,11 @@ import {
@Injectable() @Injectable()
export class JsonPatchOperationsEffects { export class JsonPatchOperationsEffects {
@Effect() commit$ = this.actions$ @Effect() commit$ = this.actions$.pipe(
.ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS) ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS),
.map((action: CommitPatchOperationsAction) => { map((action: CommitPatchOperationsAction) => {
return new FlushPatchOperationsAction(action.payload.resourceType, action.payload.resourceId); return new FlushPatchOperationsAction(action.payload.resourceType, action.payload.resourceId);
}); }));
constructor(private actions$: Actions) {} constructor(private actions$: Actions) {}

View File

@@ -1,4 +1,4 @@
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
import { CacheableObject } from '../../cache/object-cache.reducer'; import { CacheableObject } from '../../cache/object-cache.reducer';
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';

View File

@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { BrowseService } from '../browse/browse.service'; import { BrowseService } from '../browse/browse.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';

View File

@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { BrowseService } from '../browse/browse.service'; import { BrowseService } from '../browse/browse.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';

View File

@@ -91,7 +91,7 @@ export class AuthorityConfidenceStateDirective implements OnChanges {
const confidenceIndex: number = findIndex(confidenceIcons, {value: confidence}); 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 : ''; const defaultClass: string = (defaultconfidenceIndex !== -1) ? confidenceIcons[defaultconfidenceIndex].style : '';
return (confidenceIndex !== -1) ? confidenceIcons[confidenceIndex].style : defaultClass; return (confidenceIndex !== -1) ? confidenceIcons[confidenceIndex].style : defaultClass;

View File

@@ -11,7 +11,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import { FormGroup } from '@angular/forms'; 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 { filter, flatMap, map, mergeMap, scan } from 'rxjs/operators';
import { import {
DynamicFormControlComponent, DynamicFormControlComponent,
@@ -34,7 +34,6 @@ import { shrinkInOut } from '../../../../../animations/shrink';
import { ChipsItem } from '../../../../../chips/models/chips-item.model'; import { ChipsItem } from '../../../../../chips/models/chips-item.model';
import { GlobalConfig } from '../../../../../../../config/global-config.interface'; import { GlobalConfig } from '../../../../../../../config/global-config.interface';
import { GLOBAL_CONFIG } from '../../../../../../../config'; import { GLOBAL_CONFIG } from '../../../../../../../config';
import { FormGroup } from '@angular/forms';
import { hasOnlyEmptyProperties } from '../../../../../object.util'; import { hasOnlyEmptyProperties } from '../../../../../object.util';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { AuthorityService } from '../../../../../../core/integration/authority.service';
@@ -48,7 +47,7 @@ import { AuthorityValue } from '../../../../../../core/integration/models/author
templateUrl: './dynamic-group.component.html', templateUrl: './dynamic-group.component.html',
animations: [shrinkInOut] animations: [shrinkInOut]
}) })
export class DsDynamicGroupComponent implements OnDestroy, OnInit { export class DsDynamicGroupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit {
@Input() formId: string; @Input() formId: string;
@Input() group: FormGroup; @Input() group: FormGroup;
@@ -78,7 +77,6 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
protected validationService: DynamicFormValidationService protected validationService: DynamicFormValidationService
) { ) {
super(layoutService, validationService); super(layoutService, validationService);
} }
ngOnInit() { ngOnInit() {
@@ -244,21 +242,21 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
(model as any).maxOptions, (model as any).maxOptions,
1); 1);
return$ = this.authorityService.getEntryByValue(searchOptions) return$ = this.authorityService.getEntryByValue(searchOptions).pipe(
.map((result: IntegrationData) => Object.assign( map((result: IntegrationData) => Object.assign(
new FormFieldMetadataValueObject(), new FormFieldMetadataValueObject(),
valueObj[fieldName], valueObj[fieldName],
{ {
otherInformation: (result.payload[0] as AuthorityValue).otherInformation otherInformation: (result.payload[0] as AuthorityValue).otherInformation
}) })
); ));
} else { } else {
return$ = observableOf(valueObj[fieldName]); 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; return returnList;
}), }),

View File

@@ -1,25 +1,32 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; 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 { AuthorityService } from '../../../../../../core/integration/authority.service';
import { DynamicLookupModel } from './dynamic-lookup.model'; import { DynamicLookupModel } from './dynamic-lookup.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util'; import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util';
import { IntegrationData } from '../../../../../../core/integration/integration-data'; import { IntegrationData } from '../../../../../../core/integration/integration-data';
import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { PageInfo } from '../../../../../../core/shared/page-info.model';
import { Subscription } from 'rxjs/Subscription';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type'; 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({ @Component({
selector: 'ds-dynamic-lookup', selector: 'ds-dynamic-lookup',
styleUrls: ['./dynamic-lookup.component.scss'], styleUrls: ['./dynamic-lookup.component.scss'],
templateUrl: './dynamic-lookup.component.html' templateUrl: './dynamic-lookup.component.html'
}) })
export class DsDynamicLookupComponent implements OnDestroy, OnInit { export class DsDynamicLookupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit {
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicLookupModel | DynamicLookupNameModel; @Input() model: DynamicLookupModel | DynamicLookupNameModel;
@@ -40,7 +47,11 @@ export class DsDynamicLookupComponent implements OnDestroy, OnInit {
protected sub: Subscription; protected sub: Subscription;
constructor(private authorityService: AuthorityService, 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) => { inputFormatter = (x: { display: string }, y: number) => {
@@ -223,8 +234,8 @@ export class DsDynamicLookupComponent implements OnDestroy, OnInit {
this.searchOptions.query = this.getCurrentValue(); this.searchOptions.query = this.getCurrentValue();
this.loading = true; this.loading = true;
this.authorityService.getEntriesByName(this.searchOptions) this.authorityService.getEntriesByName(this.searchOptions).pipe(
.distinctUntilChanged() distinctUntilChanged())
.subscribe((object: IntegrationData) => { .subscribe((object: IntegrationData) => {
this.optionsList = object.payload; this.optionsList = object.payload;
this.pageInfo = object.pageInfo; this.pageInfo = object.pageInfo;

View File

@@ -1,24 +1,22 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; 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 { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { import {
DynamicFormControlComponent, DynamicFormControlComponent,
DynamicFormLayoutService, DynamicFormLayoutService,
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } 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 { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model';
import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { PageInfo } from '../../../../../../core/shared/page-info.model';
import { isNull, isUndefined } from '../../../../../empty.util'; import { isNull, isUndefined } from '../../../../../empty.util';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { AuthorityService } from '../../../../../../core/integration/authority.service';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { IntegrationData } from '../../../../../../core/integration/integration-data'; import { IntegrationData } from '../../../../../../core/integration/integration-data';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
@Component({ @Component({
selector: 'ds-dynamic-scrollable-dropdown', selector: 'ds-dynamic-scrollable-dropdown',
@@ -120,6 +118,6 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
} }
} }
} }
this.currentValue = Observable.of(result); this.currentValue = observableOf(result);
} }
} }

View File

@@ -1,4 +1,3 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
@@ -7,9 +6,8 @@ import {
DynamicFormLayoutService, DynamicFormLayoutService,
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { distinctUntilChanged, switchMap, tap, filter, catchError, debounceTime, merge, map } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, filter, map, merge, switchMap, tap } from 'rxjs/operators';
import {of as observableOf, Observable } from 'rxjs'; import { Observable, of as observableOf, Subject } from 'rxjs';
import { Subject } from 'rxjs/Subject';
import { NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; import { NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { AuthorityService } from '../../../../../../core/integration/authority.service';

View File

@@ -1,7 +1,7 @@
import { Observable } from 'rxjs/Observable'; import { Observable, of as observableOf } from 'rxjs';
export class MockRouter { export class MockRouter {
public events = Observable.of({}); public events = observableOf({});
public routerState = { public routerState = {
snapshot: { snapshot: {
url: '' url: ''

View File

@@ -1,17 +1,17 @@
import { of as observableOf, Observable } from 'rxjs';
import { Inject, Injectable } from '@angular/core'; 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 { INotification, Notification } from './models/notification.model';
import { NotificationType } from './models/notification-type'; import { NotificationType } from './models/notification-type';
import { NotificationOptions } from './models/notification-options.model'; 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 { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
import { TranslateService } from '@ngx-translate/core';
@Injectable() @Injectable()
export class NotificationsService { export class NotificationsService {
@@ -70,7 +70,7 @@ export class NotificationsService {
messageTranslateLabel: string, messageTranslateLabel: string,
interpolateParam: string) { interpolateParam: string) {
this.translate.get(hrefTranslateLabel) this.translate.get(hrefTranslateLabel)
.take(1) .pipe(first())
.subscribe((hrefMsg) => { .subscribe((hrefMsg) => {
const anchor = `<a class="btn btn-link p-0 m-0" href="${href}" > const anchor = `<a class="btn btn-link p-0 m-0" href="${href}" >
<strong>${hrefMsg}</strong> <strong>${hrefMsg}</strong>
@@ -78,7 +78,7 @@ export class NotificationsService {
const interpolateParams = Object.create({}); const interpolateParams = Object.create({});
interpolateParams[interpolateParam] = anchor; interpolateParams[interpolateParam] = anchor;
this.translate.get(messageTranslateLabel, interpolateParams) this.translate.get(messageTranslateLabel, interpolateParams)
.take(1) .pipe(first())
.subscribe((m) => { .subscribe((m) => {
switch (notificationType) { switch (notificationType) {
case NotificationType.Success: case NotificationType.Success:

View File

@@ -1,14 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import { ActivatedRoute, NavigationEnd, Params, Router, } from '@angular/router';
ActivatedRoute, convertToParamMap, NavigationEnd, NavigationExtras, Params,
Router,
} from '@angular/router';
import { distinctUntilChanged, map } from 'rxjs/operators'; import { distinctUntilChanged, filter, map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { isNotEmpty } from '../empty.util';
@Injectable() @Injectable()
export class RouteService { export class RouteService {

View File

@@ -1,9 +1,10 @@
import { of as observableOf } from 'rxjs';
import { Store } from '@ngrx/store';
import { ResponseCacheService } from '../../core/cache/response-cache.service'; import { ResponseCacheService } from '../../core/cache/response-cache.service';
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../../core/core.reducers'; import { CoreState } from '../../core/core.reducers';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { Observable } from 'rxjs/Observable';
export class SubmissionRestServiceStub { export class SubmissionRestServiceStub {
protected linkPath = 'workspaceitems'; protected linkPath = 'workspaceitems';
@@ -18,6 +19,6 @@ export class SubmissionRestServiceStub {
getDataByHref = jasmine.createSpy('getDataByHref'); getDataByHref = jasmine.createSpy('getDataByHref');
getEndpointByIDHref = jasmine.createSpy('getEndpointByIDHref'); getEndpointByIDHref = jasmine.createSpy('getEndpointByIDHref');
patchToEndpoint = jasmine.createSpy('patchToEndpoint'); patchToEndpoint = jasmine.createSpy('patchToEndpoint');
postToEndpoint = jasmine.createSpy('postToEndpoint').and.returnValue(Observable.of({})); postToEndpoint = jasmine.createSpy('postToEndpoint').and.returnValue(observableOf({}));
submitData = jasmine.createSpy('submitData'); submitData = jasmine.createSpy('submitData');
} }

View File

@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap, Router } from '@angular/router'; 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 { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model';
import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util'; import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util';

View File

@@ -10,7 +10,7 @@ import {
SimpleChanges SimpleChanges
} from '@angular/core'; } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription'; import { combineLatest, Observable, Subscription } from 'rxjs';
import { isNullOrUndefined } from 'util'; import { isNullOrUndefined } from 'util';
import { Collection } from '../../../core/shared/collection.model'; 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 { SubmitDataResponseDefinitionObject } from '../../../core/shared/submit-data-response-definition.model';
import { SubmissionService } from '../../submission.service'; import { SubmissionService } from '../../submission.service';
import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; import { SubmissionObject } from '../../../core/submission/models/submission-object.model';
import { Observable } from 'rxjs/Observable';
import { import {
debounceTime, debounceTime,
distinctUntilChanged, distinctUntilChanged,
@@ -144,14 +143,14 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
startWith('') startWith('')
); );
this.searchListCollection$ = Observable.combineLatest(searchTerm$, listCollection$) this.searchListCollection$ = combineLatest(searchTerm$, listCollection$).pipe(
.map(([searchTerm, listCollection]) => { map(([searchTerm, listCollection]) => {
if (searchTerm === '' || isNullOrUndefined(searchTerm)) { if (searchTerm === '' || isNullOrUndefined(searchTerm)) {
return listCollection; return listCollection;
} else { } else {
return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5) return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5)
} }
}); }));
} }
} }

View File

@@ -1,8 +1,10 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; 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 { SubmissionRestService } from '../../submission-rest.service';
import { SubmissionService } from '../../submission.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'; import { SubmissionScopeType } from '../../../core/submission/submission-scope-type';
@Component({ @Component({
@@ -33,7 +35,7 @@ export class SubmissionFormFooterComponent implements OnChanges {
this.processingSaveStatus = this.submissionService.getSubmissionSaveProcessingStatus(this.submissionId); this.processingSaveStatus = this.submissionService.getSubmissionSaveProcessingStatus(this.submissionId);
this.processingDepositStatus = this.submissionService.getSubmissionDepositProcessingStatus(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);
} }
} }

View File

@@ -1,6 +1,6 @@
import { Component, Input, OnInit, } from '@angular/core'; import { Component, Input, OnInit, } from '@angular/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
import { SectionsService } from '../../sections/sections.service'; import { SectionsService } from '../../sections/sections.service';
import { HostWindowService } from '../../../shared/host-window.service'; import { HostWindowService } from '../../../shared/host-window.service';

View File

@@ -1,13 +1,14 @@
import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; 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 { hasValue, isNotEmpty } from '../../shared/empty.util';
import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer';
import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model'; import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model';
import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.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 { SubmissionService } from '../submission.service';
import { Subscription } from 'rxjs/Subscription';
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { Observable } from 'rxjs/Observable';
import { SectionDataObject } from '../sections/models/section-data.model'; import { SectionDataObject } from '../sections/models/section-data.model';
import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
@@ -28,7 +29,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
public definitionId: string; public definitionId: string;
public test = true; public test = true;
public loading: Observable<boolean> = Observable.of(true); public loading: Observable<boolean> = observableOf(true);
public submissionSections: Observable<any>; public submissionSections: Observable<any>;
public uploadFilesOptions: UploaderOptions = { public uploadFilesOptions: UploaderOptions = {
url: '', url: '',
@@ -51,29 +52,29 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if (this.collectionId && this.submissionId) { if (this.collectionId && this.submissionId) {
this.isActive = true; this.isActive = true;
this.submissionSections = this.submissionService.getSubmissionObject(this.submissionId) this.submissionSections = this.submissionService.getSubmissionObject(this.submissionId).pipe(
.filter(() => this.isActive) filter(() => this.isActive),
.map((submission: SubmissionObjectEntry) => submission.isLoading) map((submission: SubmissionObjectEntry) => submission.isLoading),
.map((isLoading: boolean) => isLoading) map((isLoading: boolean) => isLoading),
.distinctUntilChanged() distinctUntilChanged(),
.flatMap((isLoading: boolean) => { flatMap((isLoading: boolean) => {
if (!isLoading) { if (!isLoading) {
return this.getSectionsList(); return this.getSectionsList();
} else { } else {
return Observable.of([]) return observableOf([])
} }
}); }));
this.loading = this.submissionService.getSubmissionObject(this.submissionId) this.loading = this.submissionService.getSubmissionObject(this.submissionId).pipe(
.filter(() => this.isActive) filter(() => this.isActive),
.map((submission: SubmissionObjectEntry) => submission.isLoading) map((submission: SubmissionObjectEntry) => submission.isLoading),
.map((isLoading: boolean) => isLoading) map((isLoading: boolean) => isLoading),
.distinctUntilChanged(); distinctUntilChanged());
this.subs.push( this.subs.push(
this.halService.getEndpoint('workspaceitems') this.halService.getEndpoint('workspaceitems').pipe(
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.distinctUntilChanged() distinctUntilChanged())
.subscribe((endpointURL) => { .subscribe((endpointURL) => {
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader(); this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
this.uploadFilesOptions.url = endpointURL.concat(`/${this.submissionId}`); this.uploadFilesOptions.url = endpointURL.concat(`/${this.submissionId}`);
@@ -123,8 +124,8 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
} }
protected getSectionsList(): Observable<any> { protected getSectionsList(): Observable<any> {
return this.submissionService.getSubmissionSections(this.submissionId) return this.submissionService.getSubmissionSections(this.submissionId).pipe(
.filter((sections: SectionDataObject[]) => isNotEmpty(sections)) filter((sections: SectionDataObject[]) => isNotEmpty(sections)),
.map((sections: SectionDataObject[]) => sections); map((sections: SectionDataObject[]) => sections));
} }
} }

View File

@@ -1,7 +1,8 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges } from '@angular/core';
import { TranslateService } from '@ngx-translate/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 { SectionsService } from '../../sections/sections.service';
import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util'; import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
@@ -30,7 +31,7 @@ export class SubmissionUploadFilesComponent implements OnChanges {
public dropMsg = 'submission.sections.upload.drop-message'; public dropMsg = 'submission.sections.upload.drop-message';
private subs = []; private subs = [];
private uploadEnabled: Observable<boolean> = Observable.of(false); private uploadEnabled: Observable<boolean> = observableOf(false);
public onBeforeUpload = () => { public onBeforeUpload = () => {
this.operationsService.jsonPatchByResourceType( this.operationsService.jsonPatchByResourceType(
@@ -55,7 +56,7 @@ export class SubmissionUploadFilesComponent implements OnChanges {
// Checks if upload section is enabled so do upload // Checks if upload section is enabled so do upload
this.subs.push( this.subs.push(
this.uploadEnabled this.uploadEnabled
.first() .pipe(first())
.subscribe((isUploadEnabled) => { .subscribe((isUploadEnabled) => {
if (isUploadEnabled) { if (isUploadEnabled) {

View File

@@ -1,6 +1,9 @@
import { Injectable } from '@angular/core'; 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 { union } from 'lodash';
import { import {
@@ -28,11 +31,9 @@ import {
import { SectionsService } from '../sections/sections.service'; import { SectionsService } from '../sections/sections.service';
import { isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; import { isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util';
import { Workspaceitem } from '../../core/submission/models/workspaceitem.model'; import { Workspaceitem } from '../../core/submission/models/workspaceitem.model';
import { Observable } from 'rxjs/Observable';
import { JsonPatchOperationsService } from '../../core/json-patch/json-patch-operations.service'; import { JsonPatchOperationsService } from '../../core/json-patch/json-patch-operations.service';
import { SubmitDataResponseDefinitionObject } from '../../core/shared/submit-data-response-definition.model'; import { SubmitDataResponseDefinitionObject } from '../../core/shared/submit-data-response-definition.model';
import { SubmissionService } from '../submission.service'; import { SubmissionService } from '../submission.service';
import { Store } from '@ngrx/store';
import { Workflowitem } from '../../core/submission/models/workflowitem.model'; import { Workflowitem } from '../../core/submission/models/workflowitem.model';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { SubmissionObject } from '../../core/submission/models/submission-object.model'; import { SubmissionObject } from '../../core/submission/models/submission-object.model';
@@ -48,9 +49,9 @@ import { SectionsType } from '../sections/sections-type';
@Injectable() @Injectable()
export class SubmissionObjectEffects { export class SubmissionObjectEffects {
@Effect() loadForm$ = this.actions$ @Effect() loadForm$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM) ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM),
.map((action: InitSubmissionFormAction) => { map((action: InitSubmissionFormAction) => {
const definition = action.payload.submissionDefinition; const definition = action.payload.submissionDefinition;
const mappedActions = []; const mappedActions = [];
definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel) => { definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel) => {
@@ -75,17 +76,17 @@ export class SubmissionObjectEffects {
) )
}); });
return {action: action, definition: definition, mappedActions: mappedActions}; return {action: action, definition: definition, mappedActions: mappedActions};
}) }),
.mergeMap((result) => { mergeMap((result) => {
return Observable.from( return observableFrom(
result.mappedActions.concat( result.mappedActions.concat(
new CompleteInitSubmissionFormAction(result.action.payload.submissionId) new CompleteInitSubmissionFormAction(result.action.payload.submissionId)
)); ));
}); }));
@Effect() resetForm$ = this.actions$ @Effect() resetForm$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM) ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM),
.map((action: ResetSubmissionFormAction) => map((action: ResetSubmissionFormAction) =>
new InitSubmissionFormAction( new InitSubmissionFormAction(
action.payload.collectionId, action.payload.collectionId,
action.payload.submissionId, action.payload.submissionId,
@@ -93,108 +94,108 @@ export class SubmissionObjectEffects {
action.payload.submissionDefinition, action.payload.submissionDefinition,
action.payload.sections, action.payload.sections,
null null
)); )));
@Effect() saveSubmission$ = this.actions$ @Effect() saveSubmission$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM) ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM),
.switchMap((action: SaveSubmissionFormAction) => { switchMap((action: SaveSubmissionFormAction) => {
return this.operationsService.jsonPatchByResourceType( return this.operationsService.jsonPatchByResourceType(
this.submissionService.getSubmissionObjectLinkName(), this.submissionService.getSubmissionObjectLinkName(),
action.payload.submissionId, action.payload.submissionId,
'sections') 'sections').pipe(
.map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response)) map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response)),
.catch(() => Observable.of(new SaveSubmissionFormErrorAction(action.payload.submissionId))); catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
}); }));
@Effect() saveForLaterSubmission$ = this.actions$ @Effect() saveForLaterSubmission$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM) ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM),
.switchMap((action: SaveForLaterSubmissionFormAction) => { switchMap((action: SaveForLaterSubmissionFormAction) => {
return this.operationsService.jsonPatchByResourceType( return this.operationsService.jsonPatchByResourceType(
this.submissionService.getSubmissionObjectLinkName(), this.submissionService.getSubmissionObjectLinkName(),
action.payload.submissionId, action.payload.submissionId,
'sections') 'sections').pipe(
.map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)) map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)),
.catch(() => Observable.of(new SaveSubmissionFormErrorAction(action.payload.submissionId))); catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
}); }));
@Effect() saveSubmissionSuccess$ = this.actions$ @Effect() saveSubmissionSuccess$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS) ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS),
.withLatestFrom(this.store$) withLatestFrom(this.store$),
.map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => { map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => {
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId); 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$ @Effect() saveSection$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM) ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM),
.switchMap((action: SaveSubmissionSectionFormAction) => { switchMap((action: SaveSubmissionSectionFormAction) => {
return this.operationsService.jsonPatchByResourceID( return this.operationsService.jsonPatchByResourceID(
this.submissionService.getSubmissionObjectLinkName(), this.submissionService.getSubmissionObjectLinkName(),
action.payload.submissionId, action.payload.submissionId,
'sections', 'sections',
action.payload.sectionId) action.payload.sectionId).pipe(
.map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)) map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)),
.catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))); catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))));
}); }));
@Effect() saveAndDepositSection$ = this.actions$ @Effect() saveAndDepositSection$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION) ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
.withLatestFrom(this.store$) withLatestFrom(this.store$),
.switchMap(([action, currentState]: [SaveAndDepositSubmissionAction, any]) => { switchMap(([action, currentState]: [SaveAndDepositSubmissionAction, any]) => {
return this.operationsService.jsonPatchByResourceType( return this.operationsService.jsonPatchByResourceType(
this.submissionService.getSubmissionObjectLinkName(), this.submissionService.getSubmissionObjectLinkName(),
action.payload.submissionId, action.payload.submissionId,
'sections') 'sections').pipe(
.map((response: SubmissionObject[]) => { map((response: SubmissionObject[]) => {
if (this.canDeposit(response)) { if (this.canDeposit(response)) {
return new DepositSubmissionAction(action.payload.submissionId); return new DepositSubmissionAction(action.payload.submissionId);
} else { } else {
this.notificationsService.warning(null, this.translate.get('submission.sections.general.sections_not_valid')); 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); return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], response, action.payload.submissionId);
} }
}) }),
.catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))); catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))));
}); }));
@Effect() depositSubmission$ = this.actions$ @Effect() depositSubmission$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION) ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION),
.withLatestFrom(this.store$) withLatestFrom(this.store$),
.switchMap(([action, state]: [DepositSubmissionAction, any]) => { switchMap(([action, state]: [DepositSubmissionAction, any]) => {
return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl) return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl).pipe(
.map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)) map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)),
.catch(() => Observable.of(new DepositSubmissionErrorAction(action.payload.submissionId))); catchError(() => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId))));
}); }));
@Effect({dispatch: false}) SaveForLaterSubmissionSuccess$ = this.actions$ @Effect({dispatch: false}) SaveForLaterSubmissionSuccess$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS) ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS),
.do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))) tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))),
.do(() => this.submissionService.redirectToMyDSpace()); tap(() => this.submissionService.redirectToMyDSpace()));
@Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$ @Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS) ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS),
.do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))) tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))),
.do(() => this.submissionService.redirectToMyDSpace()); tap(() => this.submissionService.redirectToMyDSpace()));
@Effect({dispatch: false}) depositSubmissionError$ = this.actions$ @Effect({dispatch: false}) depositSubmissionError$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR) ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR),
.do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))); tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))));
@Effect() discardSubmission$ = this.actions$ @Effect() discardSubmission$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION) ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION),
.switchMap((action: DepositSubmissionAction) => { switchMap((action: DepositSubmissionAction) => {
return this.submissionService.discardSubmission(action.payload.submissionId) return this.submissionService.discardSubmission(action.payload.submissionId).pipe(
.map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)) map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)),
.catch(() => Observable.of(new DiscardSubmissionErrorAction(action.payload.submissionId))); catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId))));
}); }));
@Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$ @Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS) ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS),
.do(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))) tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))),
.do(() => this.submissionService.redirectToMyDSpace()); tap(() => this.submissionService.redirectToMyDSpace()));
@Effect({dispatch: false}) discardSubmissionError$ = this.actions$ @Effect({dispatch: false}) discardSubmissionError$ = this.actions$.pipe(
.ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR) ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR),
.do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))); tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))));
constructor(private actions$: Actions, constructor(private actions$: Actions,
private notificationsService: NotificationsService, private notificationsService: NotificationsService,

View File

@@ -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 { DynamicFormControlEvent, DynamicFormControlModel } from '@ng-dynamic-forms/core';
import { Observable } from 'rxjs/Observable'; import { Observable, Subscription } from 'rxjs';
import { Subscription } from 'rxjs/Subscription'; import { distinctUntilChanged, filter, flatMap, map, take, tap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
@@ -70,12 +70,29 @@ export class FormSectionComponent extends SectionModelComponent {
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id); this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id);
this.formId = this.formService.getUniqueId(this.sectionData.id); this.formId = this.formService.getUniqueId(this.sectionData.id);
this.formConfigService.getConfigByHref(this.sectionData.config) this.formConfigService.getConfigByHref(this.sectionData.config).pipe(
.map((config: ConfigData) => config.payload) 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) => { .subscribe((config: SubmissionFormsModel) => {
this.formConfig = config; this.formConfig = config;
this.sectionService.getSectionData(this.submissionId, this.sectionData.id) this.sectionService.getSectionData(this.submissionId, this.sectionData.id).pipe(
.take(1) take(1))
.subscribe((sectionData: WorkspaceitemSectionDataType) => { .subscribe((sectionData: WorkspaceitemSectionDataType) => {
if (isUndefined(this.formModel)) { if (isUndefined(this.formModel)) {
this.sectionData.errors = []; this.sectionData.errors = [];
@@ -87,7 +104,7 @@ export class FormSectionComponent extends SectionModelComponent {
this.cdr.detectChanges(); this.cdr.detectChanges();
} }
}) })
}); });*/
} }
onSectionDestroy() { onSectionDestroy() {
@@ -142,7 +159,7 @@ export class FormSectionComponent extends SectionModelComponent {
if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data) && this.hasMetadataEnrichment(sectionData)) { if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data) && this.hasMetadataEnrichment(sectionData)) {
this.translate.get('submission.sections.general.metadata-extracted', {sectionId: this.sectionData.id}) this.translate.get('submission.sections.general.metadata-extracted', {sectionId: this.sectionData.id})
.take(1) .pipe(take(1))
.subscribe((m) => { .subscribe((m) => {
this.notificationsService.info(null, m, null, true); this.notificationsService.info(null, m, null, true);
}); });
@@ -161,9 +178,9 @@ export class FormSectionComponent extends SectionModelComponent {
} }
checksForErrors(errors: SubmissionSectionError[]) { checksForErrors(errors: SubmissionSectionError[]) {
this.formService.isFormInitialized(this.formId) this.formService.isFormInitialized(this.formId).pipe(
.filter((status: boolean) => status === true && !this.isUpdating) filter((status: boolean) => status === true && !this.isUpdating),
.take(1) take(1))
.subscribe(() => { .subscribe(() => {
this.sectionService.checkSectionErrors(this.submissionId, this.sectionData.id, this.formId, errors, this.sectionData.errors); this.sectionService.checkSectionErrors(this.submissionId, this.sectionData.id, this.formId, errors, this.sectionData.errors);
this.sectionData.errors = errors; this.sectionData.errors = errors;
@@ -177,19 +194,19 @@ export class FormSectionComponent extends SectionModelComponent {
/** /**
* Subscribe to form's data * Subscribe to form's data
*/ */
this.formService.getFormData(this.formId) this.formService.getFormData(this.formId).pipe(
.distinctUntilChanged() distinctUntilChanged())
.subscribe((formData) => { .subscribe((formData) => {
this.formData = formData; this.formData = formData;
}), }),
/** /**
* Subscribe to section state * Subscribe to section state
*/ */
this.sectionService.getSectionState(this.submissionId, this.sectionData.id) this.sectionService.getSectionState(this.submissionId, this.sectionData.id).pipe(
.filter((sectionState: SubmissionSectionObject) => { filter((sectionState: SubmissionSectionObject) => {
return isNotEmpty(sectionState) && (isNotEmpty(sectionState.data) || isNotEmpty(sectionState.errors)) return isNotEmpty(sectionState) && (isNotEmpty(sectionState.data) || isNotEmpty(sectionState.errors))
}) }),
.distinctUntilChanged() distinctUntilChanged())
.subscribe((sectionState: SubmissionSectionObject) => { .subscribe((sectionState: SubmissionSectionObject) => {
this.updateForm(sectionState.data, sectionState.errors); this.updateForm(sectionState.data, sectionState.errors);
}) })

View File

@@ -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 { 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 { SectionModelComponent } from '../models/section.model';
import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; 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); const model = this.formBuilderService.findById('granted', this.formModel);
this.subs.push( this.subs.push(
this.collectionDataService.findById(this.collectionId) this.collectionDataService.findById(this.collectionId).pipe(
.filter((collectionData: RemoteData<Collection>) => isNotUndefined((collectionData.payload))) filter((collectionData: RemoteData<Collection>) => isNotUndefined((collectionData.payload))),
.flatMap((collectionData: RemoteData<Collection>) => collectionData.payload.license) flatMap((collectionData: RemoteData<Collection>) => collectionData.payload.license),
.filter((licenseData: RemoteData<License>) => isNotUndefined((licenseData.payload))) filter((licenseData: RemoteData<License>) => isNotUndefined((licenseData.payload))),
.take(1) take(1))
.subscribe((licenseData: RemoteData<License>) => { .subscribe((licenseData: RemoteData<License>) => {
this.licenseText = licenseData.payload.text; this.licenseText = licenseData.payload.text;
@@ -79,18 +79,22 @@ export class LicenseSectionComponent extends SectionModelComponent {
} }
// Disable checkbox whether it's in workflow or item scope // Disable checkbox whether it's in workflow or item scope
this.sectionService.isSectionReadOnly(this.submissionId, this.sectionData.id, this.submissionService.getSubmissionScope()) this.sectionService.isSectionReadOnly(
.take(1) this.submissionId,
.filter((isReadOnly) => isReadOnly) this.sectionData.id,
this.submissionService.getSubmissionScope()
).pipe(
take(1),
filter((isReadOnly) => isReadOnly))
.subscribe(() => { .subscribe(() => {
model.disabled = true; model.disabled = true;
}); });
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
}), }),
this.sectionService.getSectionErrors(this.submissionId, this.sectionData.id) this.sectionService.getSectionErrors(this.submissionId, this.sectionData.id).pipe(
.filter((errors) => isNotEmpty(errors)) filter((errors) => isNotEmpty(errors)),
.distinctUntilChanged() distinctUntilChanged())
.subscribe((errors) => { .subscribe((errors) => {
// parse errors // parse errors
const newErrors = errors.map((error) => { const newErrors = errors.map((error) => {
@@ -122,8 +126,8 @@ export class LicenseSectionComponent extends SectionModelComponent {
protected getSectionStatus(): Observable<boolean> { protected getSectionStatus(): Observable<boolean> {
const model = this.formBuilderService.findById('granted', this.formModel); const model = this.formBuilderService.findById('granted', this.formModel);
return (model as DynamicCheckboxModel).valueUpdates return (model as DynamicCheckboxModel).valueUpdates.pipe(
.map((value) => value === true); map((value) => value === true));
} }
onChange(event: DynamicFormControlEvent) { onChange(event: DynamicFormControlEvent) {

View File

@@ -1,9 +1,11 @@
import { Inject, OnDestroy, OnInit } from '@angular/core'; 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 { SectionDataObject } from './section-data.model';
import { Observable } from 'rxjs/Observable';
import { SectionsService } from '../sections.service'; import { SectionsService } from '../sections.service';
import { hasValue, isNotUndefined } from '../../../shared/empty.util'; import { hasValue, isNotUndefined } from '../../../shared/empty.util';
import { Subscription } from 'rxjs/Subscription';
export interface SectionDataModel { export interface SectionDataModel {
sectionData: SectionDataObject sectionData: SectionDataObject
@@ -38,9 +40,9 @@ export abstract class SectionModelComponent implements OnDestroy, OnInit, Sectio
protected abstract onSectionDestroy(): void; protected abstract onSectionDestroy(): void;
protected updateSectionStatus(): void { protected updateSectionStatus(): void {
this.sectionStatusSub = this.getSectionStatus() this.sectionStatusSub = this.getSectionStatus().pipe(
.filter((sectionStatus: boolean) => isNotUndefined(sectionStatus)) filter((sectionStatus: boolean) => isNotUndefined(sectionStatus)),
.startWith(true) startWith(true))
.subscribe((sectionStatus: boolean) => { .subscribe((sectionStatus: boolean) => {
this.sectionService.setSectionStatus(this.submissionId, this.sectionData.id, sectionStatus); this.sectionService.setSectionStatus(this.submissionId, this.sectionData.id, sectionStatus);
}); });

View File

@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Directive, Input, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Directive, Input, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable'; import { Observable, Subscription } from 'rxjs';
import { Subscription } from 'rxjs/Subscription'; import { map } from 'rxjs/operators';
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { SectionsService } from './sections.service'; import { SectionsService } from './sections.service';
@@ -33,17 +33,17 @@ export class SectionsDirective implements OnDestroy, OnInit {
} }
ngOnInit() { ngOnInit() {
this.valid = this.sectionService.isSectionValid(this.submissionId, this.sectionId) this.valid = this.sectionService.isSectionValid(this.submissionId, this.sectionId).pipe(
.map((valid: boolean) => { map((valid: boolean) => {
if (valid) { if (valid) {
this.resetErrors(); this.resetErrors();
} }
return valid; return valid;
}); }));
this.subs.push( this.subs.push(
this.sectionService.getSectionState(this.submissionId, this.sectionId) this.sectionService.getSectionState(this.submissionId, this.sectionId).pipe(
.map((state: SubmissionSectionObject) => state.errors) map((state: SubmissionSectionObject) => state.errors))
.subscribe((errors: SubmissionSectionError[]) => { .subscribe((errors: SubmissionSectionError[]) => {
if (isNotEmpty(errors)) { if (isNotEmpty(errors)) {
errors.forEach((errorItem: SubmissionSectionError) => { errors.forEach((errorItem: SubmissionSectionError) => {

View File

@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core'; 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 { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ScrollToConfigOptions, ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; import { ScrollToConfigOptions, ScrollToService } from '@nicky-lenaers/ngx-scroll-to';
@@ -92,58 +93,58 @@ export class SectionsService {
} }
public getSectionData(submissionId: string, sectionId: string): Observable<WorkspaceitemSectionDataType> { public getSectionData(submissionId: string, sectionId: string): Observable<WorkspaceitemSectionDataType> {
return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)).pipe(
.distinctUntilChanged(); distinctUntilChanged());
} }
public getSectionErrors(submissionId: string, sectionId: string): Observable<SubmissionSectionError[]> { public getSectionErrors(submissionId: string, sectionId: string): Observable<SubmissionSectionError[]> {
return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)).pipe(
.distinctUntilChanged(); distinctUntilChanged());
} }
public getSectionState(submissionId: string, sectionId: string): Observable<SubmissionSectionObject> { public getSectionState(submissionId: string, sectionId: string): Observable<SubmissionSectionObject> {
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
.filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)) filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)),
.map((sectionObj: SubmissionSectionObject) => sectionObj) map((sectionObj: SubmissionSectionObject) => sectionObj),
.distinctUntilChanged(); distinctUntilChanged());
} }
public isSectionValid(submissionId: string, sectionId: string): Observable<boolean> { public isSectionValid(submissionId: string, sectionId: string): Observable<boolean> {
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
.filter((sectionObj) => hasValue(sectionObj)) filter((sectionObj) => hasValue(sectionObj)),
.map((sectionObj: SubmissionSectionObject) => sectionObj.isValid) map((sectionObj: SubmissionSectionObject) => sectionObj.isValid),
.distinctUntilChanged(); distinctUntilChanged());
} }
public isSectionActive(submissionId: string, sectionId: string): Observable<boolean> { public isSectionActive(submissionId: string, sectionId: string): Observable<boolean> {
return this.submissionService.getActiveSectionId(submissionId) return this.submissionService.getActiveSectionId(submissionId).pipe(
.map((activeSectionId: string) => sectionId === activeSectionId) map((activeSectionId: string) => sectionId === activeSectionId),
.distinctUntilChanged(); distinctUntilChanged());
} }
public isSectionEnabled(submissionId: string, sectionId: string): Observable<boolean> { public isSectionEnabled(submissionId: string, sectionId: string): Observable<boolean> {
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
.filter((sectionObj) => hasValue(sectionObj)) filter((sectionObj) => hasValue(sectionObj)),
.map((sectionObj: SubmissionSectionObject) => sectionObj.enabled) map((sectionObj: SubmissionSectionObject) => sectionObj.enabled),
.distinctUntilChanged(); distinctUntilChanged());
} }
public isSectionReadOnly(submissionId: string, sectionId: string, submissionScope: SubmissionScopeType): Observable<boolean> { public isSectionReadOnly(submissionId: string, sectionId: string, submissionScope: SubmissionScopeType): Observable<boolean> {
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)) return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
.filter((sectionObj) => hasValue(sectionObj)) filter((sectionObj) => hasValue(sectionObj)),
.map((sectionObj: SubmissionSectionObject) => { map((sectionObj: SubmissionSectionObject) => {
return sectionObj.visibility.other === 'READONLY' && submissionScope !== SubmissionScopeType.WorkspaceItem return sectionObj.visibility.other === 'READONLY' && submissionScope !== SubmissionScopeType.WorkspaceItem
}) }),
.distinctUntilChanged(); distinctUntilChanged());
} }
public isSectionAvailable(submissionId: string, sectionId: string): Observable<boolean> { public isSectionAvailable(submissionId: string, sectionId: string): Observable<boolean> {
return this.store.select(submissionObjectFromIdSelector(submissionId)) return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
.filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)) filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)),
.map((submissionState: SubmissionObjectEntry) => { map((submissionState: SubmissionObjectEntry) => {
return isNotUndefined(submissionState.sections) && isNotUndefined(submissionState.sections[sectionId]); return isNotUndefined(submissionState.sections) && isNotUndefined(submissionState.sections[sectionId]);
}) }),
.distinctUntilChanged(); distinctUntilChanged());
} }
public addSection(submissionId: string, public addSection(submissionId: string,
@@ -166,13 +167,13 @@ export class SectionsService {
const isAvailable$ = this.isSectionAvailable(submissionId, sectionId); const isAvailable$ = this.isSectionAvailable(submissionId, sectionId);
const isEnabled$ = this.isSectionEnabled(submissionId, sectionId); const isEnabled$ = this.isSectionEnabled(submissionId, sectionId);
Observable.combineLatest(isAvailable$, isEnabled$) combineLatest(isAvailable$, isEnabled$).pipe(
.take(1) take(1),
.filter(([available, enabled]: [boolean, boolean]) => available) filter(([available, enabled]: [boolean, boolean]) => available))
.subscribe(([available, enabled]: [boolean, boolean]) => { .subscribe(([available, enabled]: [boolean, boolean]) => {
if (!enabled) { if (!enabled) {
this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}) this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId})
.take(1) .pipe(take(1))
.subscribe((m) => { .subscribe((m) => {
this.notificationsService.info(null, m, null, true); this.notificationsService.info(null, m, null, true);
}); });

View File

@@ -1,4 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { filter, first } from 'rxjs/operators';
import { GroupEpersonService } from '../../../../core/eperson/group-eperson.service'; import { GroupEpersonService } from '../../../../core/eperson/group-eperson.service';
import { ResourcePolicy } from '../../../../core/shared/resource-policy.model'; import { ResourcePolicy } from '../../../../core/shared/resource-policy.model';
import { isEmpty } from '../../../../shared/empty.util'; import { isEmpty } from '../../../../shared/empty.util';
@@ -20,9 +23,9 @@ export class AccessConditionsComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.accessConditions.forEach((accessCondition: ResourcePolicy) => { this.accessConditions.forEach((accessCondition: ResourcePolicy) => {
if (isEmpty(accessCondition.name)) { if (isEmpty(accessCondition.name)) {
this.groupService.findById(accessCondition.groupUUID) this.groupService.findById(accessCondition.groupUUID).pipe(
.filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded) filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded),
.take(1) first())
.subscribe((rd: RemoteData<Group>) => { .subscribe((rd: RemoteData<Group>) => {
const group: Group = rd.payload; const group: Group = rd.payload;
const accessConditionEntry = Object.assign({}, accessCondition); const accessConditionEntry = Object.assign({}, accessCondition);

View File

@@ -17,6 +17,7 @@ import { SubmitDataResponseDefinitionObject } from '../../../../core/shared/subm
import { SubmissionService } from '../../../submission.service'; import { SubmissionService } from '../../../submission.service';
import { FileService } from '../../../../core/shared/file.service'; import { FileService } from '../../../../core/shared/file.service';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { filter, first } from 'rxjs/operators';
@Component({ @Component({
selector: 'ds-submission-upload-section-file', selector: 'ds-submission-upload-section-file',
@@ -62,8 +63,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit {
// Retrieve file state // Retrieve file state
this.subscriptions.push( this.subscriptions.push(
this.uploadService this.uploadService
.getFileData(this.submissionId, this.sectionId, this.fileId) .getFileData(this.submissionId, this.sectionId, this.fileId).pipe(
.filter((bitstream) => isNotUndefined(bitstream)) filter((bitstream) => isNotUndefined(bitstream)))
.subscribe((bitstream) => { .subscribe((bitstream) => {
this.fileData = bitstream; this.fileData = bitstream;
} }
@@ -99,8 +100,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit {
} }
public downloadBitstreamFile() { public downloadBitstreamFile() {
this.halService.getEndpoint('bitstreams') this.halService.getEndpoint('bitstreams').pipe(
.first() first())
.subscribe((url) => { .subscribe((url) => {
const fileUrl = `${url}/${this.fileData.uuid}/content`; const fileUrl = `${url}/${this.fileData.uuid}/content`;
this.fileService.downloadFile(fileUrl); this.fileService.downloadFile(fileUrl);
@@ -110,8 +111,8 @@ export class UploadSectionFileComponent implements OnChanges, OnInit {
public saveBitstreamData(event) { public saveBitstreamData(event) {
event.preventDefault(); event.preventDefault();
this.subscriptions.push( this.subscriptions.push(
this.formService.getFormData(this.formId) this.formService.getFormData(this.formId).pipe(
.take(1) first())
.subscribe((formData: any) => { .subscribe((formData: any) => {
Object.keys((formData.metadata)) Object.keys((formData.metadata))
.filter((key) => isNotEmpty(formData.metadata[key])) .filter((key) => isNotEmpty(formData.metadata[key]))

View File

@@ -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 { SectionModelComponent } from '../models/section.model';
import { hasValue, isNotEmpty, isNotUndefined, isUndefined } from '../../../shared/empty.util'; import { hasValue, isNotEmpty, isNotUndefined, isUndefined } from '../../../shared/empty.util';
@@ -79,30 +80,30 @@ export class UploadSectionComponent extends SectionModelComponent {
} }
onSectionInit() { onSectionInit() {
const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config) const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config).pipe(
.map((config) => config.payload); map((config) => config.payload));
this.configMetadataForm$ = config$ this.configMetadataForm$ = config$.pipe(
.take(1) take(1),
.map((config: SubmissionUploadsModel) => config.metadata); map((config: SubmissionUploadsModel) => config.metadata));
this.subs.push( this.subs.push(
this.submissionService.getSubmissionObject(this.submissionId) this.submissionService.getSubmissionObject(this.submissionId).pipe(
.filter((submissionObject: SubmissionObjectEntry) => isNotUndefined(submissionObject) && !submissionObject.isLoading) filter((submissionObject: SubmissionObjectEntry) => isNotUndefined(submissionObject) && !submissionObject.isLoading),
.filter((submissionObject: SubmissionObjectEntry) => isUndefined(this.collectionId) || this.collectionId !== submissionObject.collection) filter((submissionObject: SubmissionObjectEntry) => isUndefined(this.collectionId) || this.collectionId !== submissionObject.collection))
.subscribe((submissionObject: SubmissionObjectEntry) => { .subscribe((submissionObject: SubmissionObjectEntry) => {
this.collectionId = submissionObject.collection; this.collectionId = submissionObject.collection;
this.collectionDataService.findById(this.collectionId) this.collectionDataService.findById(this.collectionId).pipe(
.filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload))) filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload))),
.take(1) take(1))
.subscribe((collectionRemoteData: RemoteData<Collection>) => { .subscribe((collectionRemoteData: RemoteData<Collection>) => {
this.collectionName = collectionRemoteData.payload.name; this.collectionName = collectionRemoteData.payload.name;
// Default Access Conditions // Default Access Conditions
this.subs.push(collectionRemoteData.payload.defaultAccessConditions this.subs.push(collectionRemoteData.payload.defaultAccessConditions.pipe(
.filter((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => filter((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) =>
defaultAccessConditionsRemoteData.hasSucceeded) defaultAccessConditionsRemoteData.hasSucceeded),
.take(1) take(1))
.subscribe((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => { .subscribe((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => {
if (isNotEmpty(defaultAccessConditionsRemoteData.payload)) { if (isNotEmpty(defaultAccessConditionsRemoteData.payload)) {
@@ -111,8 +112,8 @@ export class UploadSectionComponent extends SectionModelComponent {
} }
// Edit Form Configuration, access policy list // Edit Form Configuration, access policy list
this.subs.push(config$ this.subs.push(config$.pipe(
.take(1) take(1))
.subscribe((config: SubmissionUploadsModel) => { .subscribe((config: SubmissionUploadsModel) => {
this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : []; this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : [];
@@ -127,16 +128,16 @@ export class UploadSectionComponent extends SectionModelComponent {
this.availableAccessConditionOptions.forEach((accessCondition: AccessConditionOption) => { this.availableAccessConditionOptions.forEach((accessCondition: AccessConditionOption) => {
if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) { if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) {
groupsObs.push( groupsObs.push(
this.groupService.findById(accessCondition.groupUUID) this.groupService.findById(accessCondition.groupUUID).pipe(
.filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded) filter((rd: RemoteData<Group>) => !rd.isResponsePending && rd.hasSucceeded),
.take(1) take(1))
); );
} }
}); });
let obsCounter = 1; let obsCounter = 1;
Observable.forkJoin(groupsObs) observableForkJoin(groupsObs).pipe(
.flatMap((group) => group) flatMap((group) => group),
.take(groupsObs.length) take(groupsObs.length))
.subscribe((rd: RemoteData<Group>) => { .subscribe((rd: RemoteData<Group>) => {
const group: Group = rd.payload; const group: Group = rd.payload;
if (isUndefined(this.availableGroups.get(group.uuid))) { if (isUndefined(this.availableGroups.get(group.uuid))) {
@@ -161,12 +162,12 @@ export class UploadSectionComponent extends SectionModelComponent {
}) })
}) })
, ,
Observable.combineLatest(this.configMetadataForm$, combineLatest(this.configMetadataForm$,
this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id)) this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id)).pipe(
.filter(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => { filter(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => {
return isNotEmpty(configMetadataForm) && isNotUndefined(fileList) return isNotEmpty(configMetadataForm) && isNotUndefined(fileList)
}) }),
.distinctUntilChanged() distinctUntilChanged())
.subscribe(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => { .subscribe(([configMetadataForm, fileList]:[SubmissionFormsModel, any[]]) => {
this.fileList = []; this.fileList = [];
this.fileIndexes = []; this.fileIndexes = [];
@@ -198,8 +199,8 @@ export class UploadSectionComponent extends SectionModelComponent {
} }
protected getSectionStatus(): Observable<boolean> { protected getSectionStatus(): Observable<boolean> {
return this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id) return this.bitstreamService.getUploadedFileList(this.submissionId, this.sectionData.id).pipe(
.map((fileList: any[]) => (isNotUndefined(fileList) && fileList.length > 0)); map((fileList: any[]) => (isNotUndefined(fileList) && fileList.length > 0)));
} }
/** /**

View File

@@ -1,12 +1,16 @@
import { Injectable } from '@angular/core'; 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 { Store } from '@ngrx/store';
import { SubmissionState } from '../../submission.reducers'; import { SubmissionState } from '../../submission.reducers';
import { DeleteUploadedFileAction, EditFileDataAction, NewUploadedFileAction } from '../../objects/submission-objects.actions';
import { import {
submissionUploadedFileFromUuidSelector, DeleteUploadedFileAction,
submissionUploadedFilesFromIdSelector EditFileDataAction,
} from '../../selectors'; NewUploadedFileAction
} from '../../objects/submission-objects.actions';
import { submissionUploadedFileFromUuidSelector, submissionUploadedFilesFromIdSelector } from '../../selectors';
import { isUndefined } from '../../../shared/empty.util'; import { isUndefined } from '../../../shared/empty.util';
import { WorkspaceitemSectionUploadFileObject } from '../../../core/submission/models/workspaceitem-section-upload-file.model'; import { WorkspaceitemSectionUploadFileObject } from '../../../core/submission/models/workspaceitem-section-upload-file.model';
@@ -16,28 +20,28 @@ export class SectionUploadService {
constructor(private store: Store<SubmissionState>) {} constructor(private store: Store<SubmissionState>) {}
public getUploadedFileList(submissionId: string, sectionId: string): Observable<any> { public getUploadedFileList(submissionId: string, sectionId: string): Observable<any> {
return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)) return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)).pipe(
.map((state) => state) map((state) => state),
.distinctUntilChanged(); distinctUntilChanged());
} }
public getFileData(submissionId: string, sectionId: string, fileUuid: string): Observable<any> { public getFileData(submissionId: string, sectionId: string, fileUuid: string): Observable<any> {
return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)) return this.store.select(submissionUploadedFilesFromIdSelector(submissionId, sectionId)).pipe(
.filter((state) => !isUndefined(state)) filter((state) => !isUndefined(state)),
.map((state) => { map((state) => {
let fileState; let fileState;
Object.keys(state) Object.keys(state)
.filter((key) => state[key].uuid === fileUuid) .filter((key) => state[key].uuid === fileUuid)
.forEach((key) => fileState = state[key]); .forEach((key) => fileState = state[key]);
return fileState; return fileState;
}) }),
.distinctUntilChanged(); distinctUntilChanged());
} }
public getDefaultPolicies(submissionId: string, sectionId: string, fileId: string): Observable<any> { public getDefaultPolicies(submissionId: string, sectionId: string, fileId: string): Observable<any> {
return this.store.select(submissionUploadedFileFromUuidSelector(submissionId, sectionId, fileId)) return this.store.select(submissionUploadedFileFromUuidSelector(submissionId, sectionId, fileId)).pipe(
.map((state) => state) map((state) => state),
.distinctUntilChanged(); distinctUntilChanged());
} }
public addUploadedFile(submissionId: string, sectionId: string, fileId: string, data: WorkspaceitemSectionUploadFileObject) { public addUploadedFile(submissionId: string, sectionId: string, fileId: string, data: WorkspaceitemSectionUploadFileObject) {

View File

@@ -1,17 +1,19 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, of as observableOf } from 'rxjs';
import { SubmissionService } from './submission.service'; import { SubmissionService } from './submission.service';
import { SubmissionObject } from '../core/submission/models/submission-object.model'; import { SubmissionObject } from '../core/submission/models/submission-object.model';
import { Observable } from 'rxjs/Observable';
@Injectable() @Injectable()
export class ServerSubmissionService extends SubmissionService { export class ServerSubmissionService extends SubmissionService {
createSubmission(): Observable<SubmissionObject> { createSubmission(): Observable<SubmissionObject> {
return Observable.of(null); return observableOf(null);
} }
retrieveSubmission(submissionId): Observable<SubmissionObject> { retrieveSubmission(submissionId): Observable<SubmissionObject> {
return Observable.of(null); return observableOf(null);
} }
startAutoSave(submissionId) { startAutoSave(submissionId) {

View File

@@ -1,11 +1,13 @@
import { Injectable } from '@angular/core'; 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 { Store } from '@ngrx/store';
import { ResponseCacheService } from '../core/cache/response-cache.service'; import { ResponseCacheService } from '../core/cache/response-cache.service';
import { RequestService } from '../core/data/request.service'; import { RequestService } from '../core/data/request.service';
import { ResponseCacheEntry } from '../core/cache/response-cache.reducer'; 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 { isNotEmpty } from '../shared/empty.util';
import { import {
ConfigRequest, ConfigRequest,
@@ -36,30 +38,55 @@ export class SubmissionRestService {
} }
protected submitData(request: RestRequest): Observable<SubmitDataResponseDefinitionObject> { 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) .map((entry: ResponseCacheEntry) => entry.response)
.partition((response: RestResponse) => response.isSuccessful); .partition((response: RestResponse) => response.isSuccessful);
return Observable.merge( return Observable.merge(
errorResponse.flatMap((response: ErrorResponse) => errorResponse.flatMap((response: ErrorResponse) =>
Observable.throw(new Error(`Couldn't send data to server`))), observableThrowError(new Error(`Couldn't send data to server`))),
successResponse successResponse
.filter((response: SubmissionSuccessResponse) => isNotEmpty(response)) .filter((response: SubmissionSuccessResponse) => isNotEmpty(response))
.map((response: SubmissionSuccessResponse) => response.dataDefinition) .map((response: SubmissionSuccessResponse) => response.dataDefinition)
.distinctUntilChanged()); .distinctUntilChanged());*/
} }
protected fetchRequest(request: RestRequest): Observable<SubmitDataResponseDefinitionObject> { 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) .map((entry: ResponseCacheEntry) => entry.response)
.do(() => this.responseCache.remove(request.href)) .do(() => this.responseCache.remove(request.href))
.partition((response: RestResponse) => response.isSuccessful); .partition((response: RestResponse) => response.isSuccessful);
return Observable.merge( return Observable.merge(
errorResponse.flatMap((response: ErrorResponse) => errorResponse.flatMap((response: ErrorResponse) =>
Observable.throw(new Error(`Couldn't retrieve the data`))), observableThrowError(new Error(`Couldn't retrieve the data`))),
successResponse successResponse
.filter((response: SubmissionSuccessResponse) => isNotEmpty(response)) .filter((response: SubmissionSuccessResponse) => isNotEmpty(response))
.map((response: SubmissionSuccessResponse) => response.dataDefinition) .map((response: SubmissionSuccessResponse) => response.dataDefinition)
.distinctUntilChanged()); .distinctUntilChanged());*/
} }
protected getEndpointByIDHref(endpoint, resourceID): string { protected getEndpointByIDHref(endpoint, resourceID): string {
@@ -67,14 +94,14 @@ export class SubmissionRestService {
} }
public deleteById(scopeId: string, linkName?: string): Observable<SubmitDataResponseDefinitionObject> { public deleteById(scopeId: string, linkName?: string): Observable<SubmitDataResponseDefinitionObject> {
return this.halService.getEndpoint(linkName || this.linkPath) return this.halService.getEndpoint(linkName || this.linkPath).pipe(
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.distinctUntilChanged() distinctUntilChanged(),
.map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)),
.map((endpointURL: string) => new SubmissionDeleteRequest(this.requestService.generateRequestId(), endpointURL)) map((endpointURL: string) => new SubmissionDeleteRequest(this.requestService.generateRequestId(), endpointURL)),
.do((request: DeleteRequest) => this.requestService.configure(request)) tap((request: DeleteRequest) => this.requestService.configure(request)),
.flatMap((request: DeleteRequest) => this.submitData(request)) flatMap((request: DeleteRequest) => this.submitData(request)),
.distinctUntilChanged(); distinctUntilChanged());
} }
public getDataByHref(href: string, options?: HttpOptions): Observable<any> { public getDataByHref(href: string, options?: HttpOptions): Observable<any> {
@@ -85,36 +112,36 @@ export class SubmissionRestService {
} }
public getDataById(linkName: string, id: string): Observable<any> { public getDataById(linkName: string, id: string): Observable<any> {
return this.halService.getEndpoint(linkName) return this.halService.getEndpoint(linkName).pipe(
.map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, id)) map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, id)),
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.distinctUntilChanged() distinctUntilChanged(),
.map((endpointURL: string) => new SubmissionRequest(this.requestService.generateRequestId(), endpointURL)) map((endpointURL: string) => new SubmissionRequest(this.requestService.generateRequestId(), endpointURL)),
.do((request: RestRequest) => this.requestService.configure(request, true)) tap((request: RestRequest) => this.requestService.configure(request, true)),
.flatMap((request: RestRequest) => this.fetchRequest(request)) flatMap((request: RestRequest) => this.fetchRequest(request)),
.distinctUntilChanged(); distinctUntilChanged());
} }
public postToEndpoint(linkName: string, body: any, scopeId?: string, options?: HttpOptions): Observable<SubmitDataResponseDefinitionObject> { public postToEndpoint(linkName: string, body: any, scopeId?: string, options?: HttpOptions): Observable<SubmitDataResponseDefinitionObject> {
return this.halService.getEndpoint(linkName) return this.halService.getEndpoint(linkName).pipe(
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)),
.distinctUntilChanged() distinctUntilChanged(),
.map((endpointURL: string) => new SubmissionPostRequest(this.requestService.generateRequestId(), endpointURL, body, options)) map((endpointURL: string) => new SubmissionPostRequest(this.requestService.generateRequestId(), endpointURL, body, options)),
.do((request: PostRequest) => this.requestService.configure(request, true)) tap((request: PostRequest) => this.requestService.configure(request, true)),
.flatMap((request: PostRequest) => this.submitData(request)) flatMap((request: PostRequest) => this.submitData(request)),
.distinctUntilChanged(); distinctUntilChanged());
} }
public patchToEndpoint(linkName: string, body: any, scopeId?: string): Observable<SubmitDataResponseDefinitionObject> { public patchToEndpoint(linkName: string, body: any, scopeId?: string): Observable<SubmitDataResponseDefinitionObject> {
return this.halService.getEndpoint(linkName) return this.halService.getEndpoint(linkName).pipe(
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)) map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)),
.distinctUntilChanged() distinctUntilChanged(),
.map((endpointURL: string) => new SubmissionPatchRequest(this.requestService.generateRequestId(), endpointURL, body)) map((endpointURL: string) => new SubmissionPatchRequest(this.requestService.generateRequestId(), endpointURL, body)),
.do((request: PostRequest) => this.requestService.configure(request, true)) tap((request: PostRequest) => this.requestService.configure(request, true)),
.flatMap((request: PostRequest) => this.submitData(request)) flatMap((request: PostRequest) => this.submitData(request)),
.distinctUntilChanged(); distinctUntilChanged());
} }
} }

View File

@@ -1,16 +1,21 @@
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable'; import { Observable, of as observableOf, Subscription, timer as observableTimer } from 'rxjs';
import { Subscription } from 'rxjs/Subscription'; import { catchError, distinctUntilChanged, filter, first, map, startWith } from 'rxjs/operators';
import { Store } from '@ngrx/store'; 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 { submissionSelector, SubmissionState } from './submission.reducers';
import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util'; import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util';
import { import {
CancelSubmissionFormAction, CancelSubmissionFormAction,
ChangeSubmissionCollectionAction, ChangeSubmissionCollectionAction,
DiscardSubmissionAction, InitSubmissionFormAction, ResetSubmissionFormAction, DiscardSubmissionAction,
InitSubmissionFormAction,
ResetSubmissionFormAction,
SaveAndDepositSubmissionAction, SaveAndDepositSubmissionAction,
SaveForLaterSubmissionFormAction, SaveForLaterSubmissionFormAction,
SaveSubmissionFormAction, SaveSubmissionFormAction,
@@ -18,13 +23,13 @@ import {
} from './objects/submission-objects.actions'; } from './objects/submission-objects.actions';
import { import {
SubmissionObjectEntry, SubmissionObjectEntry,
SubmissionSectionEntry, SubmissionSectionError, SubmissionSectionEntry,
SubmissionSectionError,
SubmissionSectionObject SubmissionSectionObject
} from './objects/submission-objects.reducer'; } from './objects/submission-objects.reducer';
import { submissionObjectFromIdSelector } from './selectors'; import { submissionObjectFromIdSelector } from './selectors';
import { GlobalConfig } from '../../config/global-config.interface'; import { GlobalConfig } from '../../config/global-config.interface';
import { GLOBAL_CONFIG } from '../../config'; import { GLOBAL_CONFIG } from '../../config';
import { HttpHeaders } from '@angular/common/http';
import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service'; import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service';
import { SubmissionRestService } from './submission-rest.service'; import { SubmissionRestService } from './submission-rest.service';
import { SectionDataObject } from './sections/models/section-data.model'; 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 { SubmissionObject } from '../core/submission/models/submission-object.model';
import { RouteService } from '../shared/services/route.service'; import { RouteService } from '../shared/services/route.service';
import { SectionsType } from './sections/sections-type'; import { SectionsType } from './sections/sections-type';
import { TranslateService } from '@ngx-translate/core';
import { NotificationsService } from '../shared/notifications/notifications.service'; 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 { SubmissionDefinitionsModel } from '../core/config/models/config-submission-definitions.model';
import { WorkspaceitemSectionsObject } from '../core/submission/models/workspaceitem-sections.model'; import { WorkspaceitemSectionsObject } from '../core/submission/models/workspaceitem-sections.model';
@@ -59,9 +62,9 @@ export class SubmissionService {
} }
createSubmission(): Observable<SubmissionObject> { createSubmission(): Observable<SubmissionObject> {
return this.restService.postToEndpoint('workspaceitems', {}) return this.restService.postToEndpoint('workspaceitems', {}).pipe(
.map((workspaceitem: SubmissionObject) => workspaceitem[0]) map((workspaceitem: SubmissionObject) => workspaceitem[0]),
.catch(() => Observable.of({})) catchError(() => observableOf({})))
} }
depositSubmission(selfUrl: string): Observable<any> { depositSubmission(selfUrl: string): Observable<any> {
@@ -107,21 +110,21 @@ export class SubmissionService {
} }
getActiveSectionId(submissionId: string): Observable<string> { getActiveSectionId(submissionId: string): Observable<string> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.map((submission: SubmissionObjectEntry) => submission.activeSection); map((submission: SubmissionObjectEntry) => submission.activeSection));
} }
getSubmissionObject(submissionId: string): Observable<SubmissionObjectEntry> { getSubmissionObject(submissionId: string): Observable<SubmissionObjectEntry> {
return this.store.select(submissionObjectFromIdSelector(submissionId)) return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
.filter((submission: SubmissionObjectEntry) => isNotUndefined(submission)) filter((submission: SubmissionObjectEntry) => isNotUndefined(submission)));
} }
getSubmissionSections(submissionId: string): Observable<SectionDataObject[]> { getSubmissionSections(submissionId: string): Observable<SectionDataObject[]> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading) filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
.take(1) first(),
.map((submission: SubmissionObjectEntry) => submission.sections) map((submission: SubmissionObjectEntry) => submission.sections),
.map((sections: SubmissionSectionEntry) => { map((sections: SubmissionSectionEntry) => {
const availableSections: SectionDataObject[] = []; const availableSections: SectionDataObject[] = [];
Object.keys(sections) Object.keys(sections)
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject)) .filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
@@ -137,16 +140,16 @@ export class SubmissionService {
availableSections.push(sectionObject); availableSections.push(sectionObject);
}); });
return availableSections; return availableSections;
}) }),
.startWith([]) startWith([]),
.distinctUntilChanged(); distinctUntilChanged());
} }
getDisabledSectionsList(submissionId: string): Observable<SectionDataObject[]> { getDisabledSectionsList(submissionId: string): Observable<SectionDataObject[]> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading) filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
.map((submission: SubmissionObjectEntry) => submission.sections) map((submission: SubmissionObjectEntry) => submission.sections),
.map((sections: SubmissionSectionEntry) => { map((sections: SubmissionSectionEntry) => {
const disabledSections: SectionDataObject[] = []; const disabledSections: SectionDataObject[] = [];
Object.keys(sections) Object.keys(sections)
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject)) .filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
@@ -158,9 +161,9 @@ export class SubmissionService {
disabledSections.push(sectionObject); disabledSections.push(sectionObject);
}); });
return disabledSections; return disabledSections;
}) }),
.startWith([]) startWith([]),
.distinctUntilChanged(); distinctUntilChanged());
} }
getSubmissionObjectLinkName(): string { getSubmissionObjectLinkName(): string {
@@ -191,11 +194,11 @@ export class SubmissionService {
} }
getSubmissionStatus(submissionId: string): Observable<boolean> { getSubmissionStatus(submissionId: string): Observable<boolean> {
return this.store.select(submissionSelector) return this.store.select(submissionSelector).pipe(
.map((submissions: SubmissionState) => submissions.objects[submissionId]) map((submissions: SubmissionState) => submissions.objects[submissionId]),
.filter((item) => isNotUndefined(item) && isNotUndefined(item.sections)) filter((item) => isNotUndefined(item) && isNotUndefined(item.sections)),
.map((item) => item.sections) map((item) => item.sections),
.map((sections) => { map((sections) => {
const states = []; const states = [];
if (isNotUndefined(sections)) { if (isNotUndefined(sections)) {
@@ -210,23 +213,23 @@ export class SubmissionService {
} }
return !isEmpty(sections) && isEmpty(states); return !isEmpty(sections) && isEmpty(states);
}) }),
.distinctUntilChanged() distinctUntilChanged(),
.startWith(false); startWith(false));
} }
getSubmissionSaveProcessingStatus(submissionId: string): Observable<boolean> { getSubmissionSaveProcessingStatus(submissionId: string): Observable<boolean> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.map((state: SubmissionObjectEntry) => state.savePending) map((state: SubmissionObjectEntry) => state.savePending),
.distinctUntilChanged() distinctUntilChanged(),
.startWith(false); startWith(false));
} }
getSubmissionDepositProcessingStatus(submissionId: string): Observable<boolean> { getSubmissionDepositProcessingStatus(submissionId: string): Observable<boolean> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.map((state: SubmissionObjectEntry) => state.depositPending) map((state: SubmissionObjectEntry) => state.depositPending),
.distinctUntilChanged() distinctUntilChanged(),
.startWith(false); startWith(false));
} }
isSectionHidden(sectionData: SubmissionSectionObject) { isSectionHidden(sectionData: SubmissionSectionObject) {
@@ -237,14 +240,14 @@ export class SubmissionService {
} }
isSubmissionLoading(submissionId: string): Observable<boolean> { isSubmissionLoading(submissionId: string): Observable<boolean> {
return this.getSubmissionObject(submissionId) return this.getSubmissionObject(submissionId).pipe(
.map((submission: SubmissionObjectEntry) => submission.isLoading) map((submission: SubmissionObjectEntry) => submission.isLoading),
.distinctUntilChanged() distinctUntilChanged());
} }
notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) { notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) {
this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}) this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId}).pipe(
.take(1) first())
.subscribe((m) => { .subscribe((m) => {
this.notificationsService.info(null, m, null, true); this.notificationsService.info(null, m, null, true);
}); });
@@ -274,10 +277,10 @@ export class SubmissionService {
} }
retrieveSubmission(submissionId): Observable<SubmissionObject> { retrieveSubmission(submissionId): Observable<SubmissionObject> {
return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId) return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId).pipe(
.filter((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)) filter((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)),
.take(1) first(),
.map((submissionObjects: SubmissionObject[]) => submissionObjects[0]); map((submissionObjects: SubmissionObject[]) => submissionObjects[0]));
} }
setActiveSection(submissionId, sectionId) { setActiveSection(submissionId, sectionId) {
@@ -291,7 +294,7 @@ export class SubmissionService {
// Retrieve interval from config and convert to milliseconds // Retrieve interval from config and convert to milliseconds
const duration = this.EnvConfig.submission.autosave.timer * (1000 * 60); const duration = this.EnvConfig.submission.autosave.timer * (1000 * 60);
// Dispatch save action after given duration // Dispatch save action after given duration
this.timerObs = Observable.timer(duration, duration); this.timerObs = observableTimer(duration, duration);
this.autoSaveSub = this.timerObs this.autoSaveSub = this.timerObs
.subscribe(() => this.store.dispatch(new SaveSubmissionFormAction(submissionId))); .subscribe(() => this.store.dispatch(new SaveSubmissionFormAction(submissionId)));
} }

View File

@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewContainerRef } from '@angular/core'; import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewContainerRef } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs';
import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util'; import { hasValue, isEmpty, isNotNull } from '../../shared/empty.util';
import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model';