>) => !collections.isResponsePending));
+ }
+
/**
* Find whether there is a collection whom user has authorization to submit to
*
diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts
index 775118dbc0..0980d48537 100644
--- a/src/app/core/data/request.service.ts
+++ b/src/app/core/data/request.service.ts
@@ -3,7 +3,7 @@ import { HttpHeaders } from '@angular/common/http';
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
import { Observable, race as observableRace } from 'rxjs';
-import { filter, find, map, mergeMap, take } from 'rxjs/operators';
+import { filter, map, mergeMap, take } from 'rxjs/operators';
import { cloneDeep, remove } from 'lodash';
import { AppState } from '../../app.reducer';
@@ -262,12 +262,13 @@ export class RequestService {
*/
private clearRequestsOnTheirWayToTheStore(request: GetRequest) {
this.getByHref(request.href).pipe(
- find((re: RequestEntry) => hasValue(re)))
- .subscribe((re: RequestEntry) => {
- if (!re.responsePending) {
- remove(this.requestsOnTheirWayToTheStore, (item) => item === request.href);
- }
- });
+ filter((re: RequestEntry) => hasValue(re)),
+ take(1)
+ ).subscribe((re: RequestEntry) => {
+ if (!re.responsePending) {
+ remove(this.requestsOnTheirWayToTheStore, (item) => item === request.href);
+ }
+ });
}
/**
diff --git a/src/app/core/submission/submission-response-parsing.service.ts b/src/app/core/submission/submission-response-parsing.service.ts
index a0811c8f2d..de7d683d91 100644
--- a/src/app/core/submission/submission-response-parsing.service.ts
+++ b/src/app/core/submission/submission-response-parsing.service.ts
@@ -128,7 +128,10 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
// Iterate over all workspaceitem's sections
Object.keys(item.sections)
.forEach((sectionId) => {
- if (typeof item.sections[sectionId] === 'object' && isNotEmpty(item.sections[sectionId])) {
+ if (typeof item.sections[sectionId] === 'object' && (isNotEmpty(item.sections[sectionId]) &&
+ // When Upload section is disabled, add to submission only if there are files
+ (!item.sections[sectionId].hasOwnProperty('files') || isNotEmpty((item.sections[sectionId] as any).files)))) {
+
const normalizedSectionData = Object.create({});
// Iterate over all sections property
Object.keys(item.sections[sectionId])
diff --git a/src/app/shared/auth-nav-menu/auth-nav-menu.component.html b/src/app/shared/auth-nav-menu/auth-nav-menu.component.html
index b560283ad5..4df07880d8 100644
--- a/src/app/shared/auth-nav-menu/auth-nav-menu.component.html
+++ b/src/app/shared/auth-nav-menu/auth-nav-menu.component.html
@@ -3,7 +3,8 @@
diff --git a/src/app/shared/chips/models/chips-item.model.ts b/src/app/shared/chips/models/chips-item.model.ts
index 540f94166f..913232fa71 100644
--- a/src/app/shared/chips/models/chips-item.model.ts
+++ b/src/app/shared/chips/models/chips-item.model.ts
@@ -2,6 +2,7 @@ import { isObject, uniqueId } from 'lodash';
import { hasValue, isNotEmpty } from '../../empty.util';
import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model';
import { ConfidenceType } from '../../../core/integration/models/confidence-type';
+import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
export interface ChipsItemIcon {
metadata: string;
@@ -62,7 +63,7 @@ export class ChipsItem {
if (this._item.hasOwnProperty(icon.metadata)
&& (((typeof this._item[icon.metadata] === 'string') && hasValue(this._item[icon.metadata]))
|| (this._item[icon.metadata] as FormFieldMetadataValueObject).hasValue())
- && !(this._item[icon.metadata] as FormFieldMetadataValueObject).hasPlaceholder()) {
+ && !this.hasPlaceholder(this._item[icon.metadata])) {
if ((icon.visibleWhenAuthorityEmpty
|| (this._item[icon.metadata] as FormFieldMetadataValueObject).confidence !== ConfidenceType.CF_UNSET)
&& isNotEmpty(icon.style)) {
@@ -109,4 +110,9 @@ export class ChipsItem {
this.display = value;
}
+
+ private hasPlaceholder(value: any) {
+ return (typeof value === 'string') ? (value === PLACEHOLDER_PARENT_METADATA) :
+ (value as FormFieldMetadataValueObject).hasPlaceholder()
+ }
}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
index 217f9e79cf..52a924604f 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
@@ -14,7 +14,8 @@
-
+
{{ message | translate:model.validators }}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model.ts
index fc618023f9..66bdf97dad 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model.ts
@@ -1,4 +1,7 @@
import { DynamicFormControlLayout, DynamicFormGroupModel, DynamicFormGroupModelConfig, serializable } from '@ng-dynamic-forms/core';
+
+import { Subject } from 'rxjs';
+
import { isNotEmpty } from '../../../../empty.util';
import { DsDynamicInputModel } from './ds-dynamic-input.model';
import { FormFieldMetadataValueObject } from '../../models/form-field-metadata-value.model';
@@ -16,12 +19,16 @@ export class DynamicConcatModel extends DynamicFormGroupModel {
@serializable() separator: string;
@serializable() hasLanguages = false;
isCustomGroup = true;
+ valueUpdates: Subject;
constructor(config: DynamicConcatModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout);
this.separator = config.separator + ' ';
+
+ this.valueUpdates = new Subject();
+ this.valueUpdates.subscribe((value: string) => this.value = value);
}
get value() {
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts
index 860c481820..4e4a944319 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts
@@ -28,6 +28,7 @@ export class DsDynamicInputModel extends DynamicInputModel {
constructor(config: DsDynamicInputModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout);
+ this.hint = config.hint;
this.readOnly = config.readOnly;
this.value = config.value;
this.language = config.language;
@@ -57,11 +58,7 @@ export class DsDynamicInputModel extends DynamicInputModel {
}
get hasLanguages(): boolean {
- if (this.languageCodes && this.languageCodes.length > 1) {
- return true;
- } else {
- return false;
- }
+ return this.languageCodes && this.languageCodes.length > 1;
}
get language(): string {
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model.ts
index 6bd5a604a0..5d2cbc58b7 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model.ts
@@ -1,5 +1,5 @@
-import { DynamicFormControlLayout, DynamicFormGroupModel, DynamicInputModelConfig, serializable } from '@ng-dynamic-forms/core';
-import { DsDynamicInputModel, DsDynamicInputModelConfig } from './ds-dynamic-input.model';
+import { DynamicFormControlLayout, DynamicFormGroupModel, serializable } from '@ng-dynamic-forms/core';
+import { DsDynamicInputModel } from './ds-dynamic-input.model';
import { Subject } from 'rxjs';
import { DynamicFormGroupModelConfig } from '@ng-dynamic-forms/core/src/model/form-group/dynamic-form-group.model';
import { LanguageCode } from '../../models/form-field-language-value.model';
@@ -12,6 +12,7 @@ export interface DsDynamicQualdropModelConfig extends DynamicFormGroupModelConfi
languageCodes?: LanguageCode[];
language?: string;
readOnly: boolean;
+ hint?: string;
}
export class DynamicQualdropModel extends DynamicFormGroupModel {
@@ -20,6 +21,7 @@ export class DynamicQualdropModel extends DynamicFormGroupModel {
@serializable() languageUpdates: Subject;
@serializable() hasLanguages = false;
@serializable() readOnly: boolean;
+ @serializable() hint: string;
isCustomGroup = true;
constructor(config: DsDynamicQualdropModelConfig, layout?: DynamicFormControlLayout) {
@@ -33,6 +35,8 @@ export class DynamicQualdropModel extends DynamicFormGroupModel {
this.languageUpdates.subscribe((lang: string) => {
this.language = lang;
});
+
+ this.hint = config.hint;
}
get value() {
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html
index cb2d1fe217..3cfb5980c6 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html
@@ -20,11 +20,10 @@
[disabled]="isInputDisabled()"
[placeholder]="model.placeholder | translate"
[readonly]="model.readOnly"
- (change)="$event.preventDefault()"
+ (change)="onChange($event)"
(blur)="onBlurEvent($event); $event.stopPropagation(); sdRef.close();"
(focus)="onFocusEvent($event); $event.stopPropagation(); sdRef.close();"
- (click)="$event.stopPropagation(); $event.stopPropagation(); sdRef.close();"
- (input)="onInput($event)">
+ (click)="$event.stopPropagation(); $event.stopPropagation(); sdRef.close();">
@@ -40,11 +39,10 @@
[disabled]="firstInputValue.length === 0 || isInputDisabled()"
[placeholder]="model.secondPlaceholder | translate"
[readonly]="model.readOnly"
- (change)="$event.preventDefault()"
+ (change)="onChange($event)"
(blur)="onBlurEvent($event); $event.stopPropagation(); sdRef.close();"
(focus)="onFocusEvent($event); $event.stopPropagation(); sdRef.close();"
- (click)="$event.stopPropagation(); sdRef.close();"
- (input)="onInput($event)">
+ (click)="$event.stopPropagation(); sdRef.close();">
Object.assign(new SearchResult
(), { indexableObject: collection }));
-const searchService = {
- search: () => {
- return observableOf(new RemoteData(true, true, true,
- undefined, new PaginatedList(new PageInfo(), collectionResults)))
- }
-};
+const mockCommunity = Object.assign(new Community(), {
+ name: 'Community 1',
+ id: '123456789-1',
+ metadata: [
+ {
+ key: 'dc.title',
+ language: 'en_US',
+ value: 'Community 1'
+ }],
+ collections: observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), [mockCommunity1Collection1, mockCommunity1Collection2]))),
+ subcommunities: observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), subcommunities))),
+});
+
+const mockCommunity2 = Object.assign(new Community(), {
+ name: 'Community 2',
+ id: '123456789-2',
+ metadata: [
+ {
+ key: 'dc.title',
+ language: 'en_US',
+ value: 'Community 2'
+ }],
+ collections: observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), [mockCommunity2Collection1, mockCommunity2Collection2]))),
+ subcommunities: observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), []))),
+});
+
+const mockCommunity1Collection1Rd = observableOf(new RemoteData(true, true, true,
+ undefined, mockCommunity1Collection1));
+
+const mockCommunityList = observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), [mockCommunity, mockCommunity2])));
+
+const mockCommunityCollectionList = observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), [mockCommunity1Collection1, mockCommunity1Collection2])));
+
+const mockCommunity2CollectionList = observableOf(new RemoteData(true, true, true,
+ undefined, new PaginatedList(new PageInfo(), [mockCommunity2Collection1, mockCommunity2Collection2])));
const mockCollectionList = [
{
communities: [
{
- id: 'c0e4de93-f506-4990-a840-d406f6f2ada7',
- name: 'Submission test'
+ id: '123456789-1',
+ name: 'Community 1'
}
],
collection: {
@@ -106,8 +151,8 @@ const mockCollectionList = [
{
communities: [
{
- id: 'c0e4de93-f506-4990-a840-d406f6f2ada7',
- name: 'Submission test'
+ id: '123456789-1',
+ name: 'Community 1'
}
],
collection: {
@@ -118,8 +163,8 @@ const mockCollectionList = [
{
communities: [
{
- id: 'c0e4de93-f506-4990-a840-d406f6f2ada7',
- name: 'Submission test'
+ id: '123456789-2',
+ name: 'Community 2'
}
],
collection: {
@@ -130,8 +175,8 @@ const mockCollectionList = [
{
communities: [
{
- id: 'c0e4de93-f506-4990-a840-d406f6f2ada7',
- name: 'Submission test'
+ id: '123456789-2',
+ name: 'Community 2'
}
],
collection: {
@@ -158,6 +203,12 @@ describe('SubmissionFormCollectionComponent Component', () => {
const communityDataService: any = jasmine.createSpyObj('communityDataService', {
findAll: jasmine.createSpy('findAll')
});
+
+ const collectionDataService: any = jasmine.createSpyObj('collectionDataService', {
+ findById: jasmine.createSpy('findById'),
+ getAuthorizedCollectionByCommunity: jasmine.createSpy('getAuthorizedCollectionByCommunity')
+ });
+
const store: any = jasmine.createSpyObj('store', {
dispatch: jasmine.createSpy('dispatch'),
select: jasmine.createSpy('select')
@@ -179,15 +230,12 @@ describe('SubmissionFormCollectionComponent Component', () => {
TestComponent
],
providers: [
- {
- provide: SubmissionJsonPatchOperationsService,
- useClass: SubmissionJsonPatchOperationsServiceStub
- },
+ { provide: CollectionDataService, useValue: collectionDataService },
+ { provide: SubmissionJsonPatchOperationsService, useClass: SubmissionJsonPatchOperationsServiceStub },
{ provide: SubmissionService, useClass: SubmissionServiceStub },
{ provide: CommunityDataService, useValue: communityDataService },
{ provide: JsonPatchOperationsBuilder, useValue: jsonPatchOpBuilder },
{ provide: Store, useValue: store },
- { provide: SearchService, useValue: searchService },
ChangeDetectorRef,
SubmissionFormCollectionComponent
],
@@ -252,17 +300,21 @@ describe('SubmissionFormCollectionComponent Component', () => {
});
it('should init collection list properly', () => {
+ communityDataService.findAll.and.returnValue(mockCommunityList);
+ collectionDataService.findById.and.returnValue(mockCommunity1Collection1Rd);
+ collectionDataService.getAuthorizedCollectionByCommunity.and.returnValues(mockCommunityCollectionList, mockCommunity2CollectionList);
+
comp.ngOnChanges({
currentCollectionId: new SimpleChange(null, collectionId, true)
});
- expect(comp.searchListCollection$).toBeObservable(cold('(b)', {
+ expect(comp.searchListCollection$).toBeObservable(cold('(ab)', {
+ a: [],
b: mockCollectionList
}));
- expect(comp.selectedCollectionName$).toBeObservable(cold('(ab|)', {
- a: '',
- b: 'Community 1-Collection 1'
+ expect(comp.selectedCollectionName$).toBeObservable(cold('(a|)', {
+ a: 'Community 1-Collection 1'
}));
});
@@ -394,8 +446,6 @@ class TestComponent {
definitionId = 'traditional';
submissionId = mockSubmissionId;
- onCollectionChange = () => {
- return;
- }
+ onCollectionChange = () => { return; }
}
diff --git a/src/app/submission/form/collection/submission-form-collection.component.ts b/src/app/submission/form/collection/submission-form-collection.component.ts
index e9832985fe..79d2f2a7bc 100644
--- a/src/app/submission/form/collection/submission-form-collection.component.ts
+++ b/src/app/submission/form/collection/submission-form-collection.component.ts
@@ -17,13 +17,16 @@ import {
distinctUntilChanged,
filter,
find,
+ flatMap,
map,
mergeMap,
+ reduce,
startWith
} from 'rxjs/operators';
import { Collection } from '../../../core/shared/collection.model';
import { CommunityDataService } from '../../../core/data/community-data.service';
+import { Community } from '../../../core/shared/community.model';
import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
import { RemoteData } from '../../../core/data/remote-data';
import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner';
@@ -32,12 +35,8 @@ import { PaginatedList } from '../../../core/data/paginated-list';
import { SubmissionService } from '../../submission.service';
import { SubmissionObject } from '../../../core/submission/models/submission-object.model';
import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service';
-import { SearchService } from '../../../+search-page/search-service/search.service';
-import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
-import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
-import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
-import { getSucceededRemoteData } from '../../../core/shared/operators';
-import { SearchResult } from '../../../+search-page/search-result.model';
+import { CollectionDataService } from '../../../core/data/collection-data.service';
+import { FindAllOptions } from '../../../core/data/request.models';
/**
* An interface to represent a collection entry
@@ -95,6 +94,12 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
*/
public disabled$ = new BehaviorSubject(true);
+ /**
+ * A boolean representing if a collection change operation is processing
+ * @type {BehaviorSubject}
+ */
+ public processingChange$ = new BehaviorSubject(false);
+
/**
* The search form control
* @type {FormControl}
@@ -148,17 +153,17 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
*
* @param {ChangeDetectorRef} cdr
* @param {CommunityDataService} communityDataService
+ * @param {CollectionDataService} collectionDataService
* @param {JsonPatchOperationsBuilder} operationsBuilder
* @param {SubmissionJsonPatchOperationsService} operationsService
* @param {SubmissionService} submissionService
- * @param {SearchService} searchService
*/
constructor(protected cdr: ChangeDetectorRef,
private communityDataService: CommunityDataService,
+ private collectionDataService: CollectionDataService,
private operationsBuilder: JsonPatchOperationsBuilder,
private operationsService: SubmissionJsonPatchOperationsService,
- private submissionService: SubmissionService,
- private searchService: SearchService) {
+ private submissionService: SubmissionService) {
}
/**
@@ -195,57 +200,55 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
&& hasValue(changes.currentCollectionId.currentValue)) {
this.selectedCollectionId = this.currentCollectionId;
- // // @TODO replace with search/top browse endpoint
- // // @TODO implement community/subcommunity hierarchy
- // const communities$ = this.communityDataService.findAll().pipe(
- // find((communities: RemoteData>) => isNotEmpty(communities.payload)),
- // mergeMap((communities: RemoteData>) => communities.payload.page));
+ this.selectedCollectionName$ = this.collectionDataService.findById(this.currentCollectionId).pipe(
+ find((collectionRD: RemoteData) => isNotEmpty(collectionRD.payload)),
+ map((collectionRD: RemoteData) => collectionRD.payload.name)
+ );
- const listCollection$: Observable = this.searchService.search(
- new PaginatedSearchOptions({
- dsoType: DSpaceObjectType.COLLECTION,
- pagination: new PaginationComponentOptions(),
- scope: 'c0e4de93-f506-4990-a840-d406f6f2ada7'
- })
- ).pipe(
- getSucceededRemoteData(),
- map((collections: RemoteData>>) => collections.payload.page),
- filter((collectionData: Array>) => isNotEmpty(collectionData)),
- map((collectionData: Array>) => {
- return collectionData.map((collection: SearchResult) => {
- return {
- communities: [{
- id: 'c0e4de93-f506-4990-a840-d406f6f2ada7',
- name: 'Submission test'
- }],
- collection: { id: collection.indexableObject.id, name: collection.indexableObject.name }
+ const findOptions: FindAllOptions = {
+ elementsPerPage: 1000
+ };
+
+ // Retrieve collection list only when is the first change
+ if (changes.currentCollectionId.isFirstChange()) {
+ // @TODO replace with search/top browse endpoint
+ // @TODO implement community/subcommunity hierarchy
+ const communities$ = this.communityDataService.findAll(findOptions).pipe(
+ find((communities: RemoteData>) => isNotEmpty(communities.payload)),
+ mergeMap((communities: RemoteData>) => communities.payload.page));
+
+ const listCollection$ = communities$.pipe(
+ flatMap((communityData: Community) => {
+ return this.collectionDataService.getAuthorizedCollectionByCommunity(communityData.uuid, findOptions).pipe(
+ find((collections: RemoteData>) => !collections.isResponsePending && collections.hasSucceeded),
+ mergeMap((collections: RemoteData>) => collections.payload.page),
+ filter((collectionData: Collection) => isNotEmpty(collectionData)),
+ map((collectionData: Collection) => ({
+ communities: [{ id: communityData.id, name: communityData.name }],
+ collection: { id: collectionData.id, name: collectionData.name }
+ }))
+ );
+ }),
+ reduce((acc: any, value: any) => [...acc, ...value], []),
+ startWith([])
+ );
+
+ const searchTerm$ = this.searchField.valueChanges.pipe(
+ debounceTime(200),
+ distinctUntilChanged(),
+ startWith('')
+ );
+
+ this.searchListCollection$ = combineLatest(searchTerm$, listCollection$).pipe(
+ map(([searchTerm, listCollection]) => {
+ this.disabled$.next(isEmpty(listCollection));
+ if (isEmpty(searchTerm)) {
+ return listCollection;
+ } else {
+ return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5);
}
- })
- })
- );
-
- this.selectedCollectionName$ = listCollection$.pipe(
- map((collectionData: CollectionListEntry[]) => collectionData.find((entry: CollectionListEntry) => entry.collection.id === this.selectedCollectionId)),
- filter((entry: CollectionListEntry) => hasValue(entry.collection)),
- map((entry: CollectionListEntry) => entry.collection.name),
- startWith('')
- );
-
- const searchTerm$ = this.searchField.valueChanges.pipe(
- debounceTime(200),
- distinctUntilChanged(),
- startWith('')
- );
-
- this.searchListCollection$ = combineLatest(searchTerm$, listCollection$).pipe(
- map(([searchTerm, listCollection]) => {
- this.disabled$.next(isEmpty(listCollection));
- if (isEmpty(searchTerm)) {
- return listCollection;
- } else {
- return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5);
- }
- }));
+ }));
+ }
}
}
@@ -271,7 +274,7 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
*/
onSelect(event) {
this.searchField.reset();
- this.disabled$.next(true);
+ this.processingChange$.next(true);
this.operationsBuilder.replace(this.pathCombiner.getPath(), event.collection.id, true);
this.subs.push(this.operationsService.jsonPatchByResourceID(
this.submissionService.getSubmissionObjectLinkName(),
@@ -283,7 +286,7 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
this.selectedCollectionName$ = observableOf(event.collection.name);
this.collectionChange.emit(submissionObject[0]);
this.submissionService.changeSubmissionCollection(this.submissionId, event.collection.id);
- this.disabled$.next(false);
+ this.processingChange$.next(false);
this.cdr.detectChanges();
})
);
diff --git a/src/app/submission/objects/submission-objects.reducer.ts b/src/app/submission/objects/submission-objects.reducer.ts
index 1a65783945..8c111dde67 100644
--- a/src/app/submission/objects/submission-objects.reducer.ts
+++ b/src/app/submission/objects/submission-objects.reducer.ts
@@ -361,7 +361,7 @@ const addError = (state: SubmissionObjectState, action: InertSectionErrorsAction
* @param state
* the current state
* @param action
- * an RemoveSectionErrorsAction
+ * a RemoveSectionErrorsAction
* @return SubmissionObjectState
* the new state, with the section's errors updated.
*/
@@ -416,7 +416,7 @@ function initSubmission(state: SubmissionObjectState, action: InitSubmissionForm
* @param state
* the current state
* @param action
- * an ResetSubmissionFormAction
+ * a ResetSubmissionFormAction
* @return SubmissionObjectState
* the new state, with the section removed.
*/
@@ -439,7 +439,7 @@ function resetSubmission(state: SubmissionObjectState, action: ResetSubmissionFo
* @param state
* the current state
* @param action
- * an CompleteInitSubmissionFormAction
+ * a CompleteInitSubmissionFormAction
* @return SubmissionObjectState
* the new state, with the section removed.
*/
@@ -461,7 +461,7 @@ function completeInit(state: SubmissionObjectState, action: CompleteInitSubmissi
* @param state
* the current state
* @param action
- * an SaveSubmissionFormAction | SaveSubmissionSectionFormAction
+ * a SaveSubmissionFormAction | SaveSubmissionSectionFormAction
* | SaveForLaterSubmissionFormAction | SaveAndDepositSubmissionAction
* @return SubmissionObjectState
* the new state, with the flag set to true.
@@ -491,7 +491,7 @@ function saveSubmission(state: SubmissionObjectState,
* @param state
* the current state
* @param action
- * an SaveSubmissionFormSuccessAction | SaveForLaterSubmissionFormSuccessAction
+ * a SaveSubmissionFormSuccessAction | SaveForLaterSubmissionFormSuccessAction
* | SaveSubmissionSectionFormSuccessAction | SaveSubmissionFormErrorAction
* | SaveForLaterSubmissionFormErrorAction | SaveSubmissionSectionFormErrorAction
* @return SubmissionObjectState
@@ -521,7 +521,7 @@ function completeSave(state: SubmissionObjectState,
* @param state
* the current state
* @param action
- * an DepositSubmissionAction
+ * a DepositSubmissionAction
* @return SubmissionObjectState
* the new state, with the deposit flag changed.
*/
@@ -544,7 +544,7 @@ function startDeposit(state: SubmissionObjectState, action: DepositSubmissionAct
* @param state
* the current state
* @param action
- * an DepositSubmissionSuccessAction or DepositSubmissionErrorAction
+ * a DepositSubmissionSuccessAction or a DepositSubmissionErrorAction
* @return SubmissionObjectState
* the new state, with the deposit flag changed.
*/
@@ -586,7 +586,7 @@ function changeCollection(state: SubmissionObjectState, action: ChangeSubmission
* @param state
* the current state
* @param action
- * an SetActiveSectionAction
+ * a SetActiveSectionAction
* @return SubmissionObjectState
* the new state, with the active section.
*/
@@ -676,7 +676,7 @@ function updateSectionData(state: SubmissionObjectState, action: UpdateSectionDa
* @param state
* the current state
* @param action
- * an DisableSectionAction
+ * a DisableSectionAction
* @param enabled
* enabled or disabled section.
* @return SubmissionObjectState
@@ -705,7 +705,7 @@ function changeSectionState(state: SubmissionObjectState, action: EnableSectionA
* @param state
* the current state
* @param action
- * an SectionStatusChangeAction
+ * a SectionStatusChangeAction
* @return SubmissionObjectState
* the new state, with the section new validity status.
*/
@@ -769,7 +769,7 @@ function newFile(state: SubmissionObjectState, action: NewUploadedFileAction): S
* @param state
* the current state
* @param action
- * a EditFileDataAction action
+ * an EditFileDataAction action
* @return SubmissionObjectState
* the new state, with the edited file.
*/
diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts
index ef817a7568..2269ccd5f1 100644
--- a/src/app/submission/sections/form/section-form.component.ts
+++ b/src/app/submission/sections/form/section-form.component.ts
@@ -64,6 +64,12 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
*/
public isLoading = true;
+ /**
+ * A map representing all field on their way to be removed
+ * @type {Map}
+ */
+ protected fieldsOnTheirWayToBeRemoved: Map = new Map();
+
/**
* The form config
* @type {SubmissionFormsModel}
@@ -295,6 +301,7 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
}),
distinctUntilChanged())
.subscribe((sectionState: SubmissionSectionObject) => {
+ this.fieldsOnTheirWayToBeRemoved = new Map();
this.updateForm(sectionState.data as WorkspaceitemSectionFormObject, sectionState.errors);
})
)
@@ -348,11 +355,24 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
* the [[DynamicFormControlEvent]] emitted
*/
onRemove(event: DynamicFormControlEvent): void {
+ const fieldId = this.formBuilderService.getId(event.model);
+ const fieldIndex = this.formOperationsService.getArrayIndexFromEvent(event);
+
+ // Keep track that this field will be removed
+ if (this.fieldsOnTheirWayToBeRemoved.has(fieldId)) {
+ const indexes = this.fieldsOnTheirWayToBeRemoved.get(fieldId);
+ indexes.push(fieldIndex);
+ this.fieldsOnTheirWayToBeRemoved.set(fieldId, indexes);
+ } else {
+ this.fieldsOnTheirWayToBeRemoved.set(fieldId, [fieldIndex]);
+ }
+
this.formOperationsService.dispatchOperationsFromEvent(
this.pathCombiner,
event,
this.previousValue,
- this.hasStoredValue(this.formBuilderService.getId(event.model), this.formOperationsService.getArrayIndexFromEvent(event)));
+ this.hasStoredValue(fieldId, fieldIndex));
+
}
/**
@@ -365,9 +385,23 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
*/
hasStoredValue(fieldId, index): boolean {
if (isNotEmpty(this.sectionData.data)) {
- return this.sectionData.data.hasOwnProperty(fieldId) && isNotEmpty(this.sectionData.data[fieldId][index]);
+ return this.sectionData.data.hasOwnProperty(fieldId) &&
+ isNotEmpty(this.sectionData.data[fieldId][index]) &&
+ !this.isFieldToRemove(fieldId, index);
} else {
return false;
}
}
+
+ /**
+ * Check if the specified field is on the way to be removed
+ *
+ * @param fieldId
+ * the section data retrieved from the serverù
+ * @param index
+ * the section data retrieved from the server
+ */
+ isFieldToRemove(fieldId, index) {
+ return this.fieldsOnTheirWayToBeRemoved.has(fieldId) && this.fieldsOnTheirWayToBeRemoved.get(fieldId).includes(index);
+ }
}
diff --git a/src/app/submission/sections/upload/section-upload.component.ts b/src/app/submission/sections/upload/section-upload.component.ts
index 826385af45..9dbd1079f4 100644
--- a/src/app/submission/sections/upload/section-upload.component.ts
+++ b/src/app/submission/sections/upload/section-upload.component.ts
@@ -155,14 +155,14 @@ export class SubmissionSectionUploadComponent extends SectionModelComponent {
filter((submissionObject: SubmissionObjectEntry) => isUndefined(this.collectionId) || this.collectionId !== submissionObject.collection),
tap((submissionObject: SubmissionObjectEntry) => this.collectionId = submissionObject.collection),
flatMap((submissionObject: SubmissionObjectEntry) => this.collectionDataService.findById(submissionObject.collection)),
- find((rd: RemoteData) => isNotUndefined((rd.payload))),
+ filter((rd: RemoteData) => isNotUndefined((rd.payload))),
tap((collectionRemoteData: RemoteData) => this.collectionName = collectionRemoteData.payload.name),
flatMap((collectionRemoteData: RemoteData) => {
return this.resourcePolicyService.findByHref(
(collectionRemoteData.payload as any)._links.defaultAccessConditions
);
}),
- find((defaultAccessConditionsRemoteData: RemoteData) =>
+ filter((defaultAccessConditionsRemoteData: RemoteData) =>
defaultAccessConditionsRemoteData.hasSucceeded),
tap((defaultAccessConditionsRemoteData: RemoteData) => {
if (isNotEmpty(defaultAccessConditionsRemoteData.payload)) {
@@ -171,7 +171,6 @@ export class SubmissionSectionUploadComponent extends SectionModelComponent {
}
}),
flatMap(() => config$),
- take(1),
flatMap((config: SubmissionUploadsModel) => {
this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : [];
diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts
index 0191b49e9b..7605f1c73a 100644
--- a/src/app/submission/submission.service.ts
+++ b/src/app/submission/submission.service.ts
@@ -197,7 +197,11 @@ export class SubmissionService {
* The submission id
*/
dispatchSave(submissionId) {
- this.store.dispatch(new SaveSubmissionFormAction(submissionId));
+ this.getSubmissionSaveProcessingStatus(submissionId).pipe(
+ find((isPending: boolean) => !isPending)
+ ).subscribe(() => {
+ this.store.dispatch(new SaveSubmissionFormAction(submissionId));
+ })
}
/**
diff --git a/src/modules/app/server-app.module.ts b/src/modules/app/server-app.module.ts
index 0c3046ba68..02abf6449b 100644
--- a/src/modules/app/server-app.module.ts
+++ b/src/modules/app/server-app.module.ts
@@ -64,7 +64,7 @@ export function createTranslateLoader() {
{
provide: SubmissionService,
useClass: ServerSubmissionService
- },
+ }
]
})
export class ServerAppModule {
diff --git a/src/server.ts b/src/server.ts
index 0526f196ba..de0f8082bb 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -67,7 +67,7 @@ export function startServer(bootstrap: Type<{}> | NgModuleFactory<{}>) {
function onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
if (!res._headerSent) {
- console.warn('Error in SSR, serving for direct CSR');
+ console.warn('Error in SSR, serving for direct CSR. Error details : ', error);
res.sendFile('index.csr.html', { root: './src' });
}
}
diff --git a/src/styles/_custom_variables.scss b/src/styles/_custom_variables.scss
index 8ca2067a2e..df193be91b 100644
--- a/src/styles/_custom_variables.scss
+++ b/src/styles/_custom_variables.scss
@@ -13,7 +13,7 @@ $drop-zone-area-inner-z-index: 1021;
$login-logo-height:72px;
$login-logo-width:72px;
$submission-header-z-index: 1001;
-$submission-footer-z-index: 1000;
+$submission-footer-z-index: 999;
$main-z-index: 0;
$nav-z-index: 10;