diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 09f8616f9e..fdccbf82f6 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -2,11 +2,7 @@ import { CommonModule } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; -import { - DynamicFormLayoutService, - DynamicFormService, - DynamicFormValidationService -} from '@ng-dynamic-forms/core'; +import { DynamicFormLayoutService, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { EffectsModule } from '@ngrx/effects'; import { Action, StoreConfig, StoreModule } from '@ngrx/store'; @@ -163,7 +159,7 @@ import { RootDataService } from './data/root-data.service'; import { Root } from './data/root.model'; import { SearchConfig } from './shared/search/search-filters/search-config.model'; import { SequenceService } from './shared/sequence.service'; -import { SubmissionAccessesModel } from 'src/app/core/config/models/config-submission-accesses.model'; +import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; /** * When not in production, endpoint responses can be mocked for testing purposes diff --git a/src/app/core/submission/models/submission-accesses.model.ts b/src/app/core/submission/models/submission-accesses.model.ts index 2affe641f5..afad90b2ff 100644 --- a/src/app/core/submission/models/submission-accesses.model.ts +++ b/src/app/core/submission/models/submission-accesses.model.ts @@ -3,7 +3,7 @@ import { typedObject } from '../../cache/builders/build-decorators'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { ResourceType } from '../../shared/resource-type'; import { HALResource } from '../../shared/hal-resource.model'; -import { SUBMISSION_ACCESSES } from 'src/app/core/submission/models/submission-accesses.resource-type'; +import { SUBMISSION_ACCESSES } from './submission-accesses.resource-type'; @typedObject @inheritSerialization(HALResource) diff --git a/src/app/shared/mocks/section-accesses-config.service.mock.ts b/src/app/shared/mocks/section-accesses-config.service.mock.ts index d26420443e..0362493035 100644 --- a/src/app/shared/mocks/section-accesses-config.service.mock.ts +++ b/src/app/shared/mocks/section-accesses-config.service.mock.ts @@ -1,6 +1,6 @@ import { SubmissionFormsConfigService } from '../../core/config/submission-forms-config.service'; -import { SubmissionFormsModel } from 'src/app/core/config/models/config-submission-forms.model'; -import { createSuccessfulRemoteDataObject$ } from 'src/app/shared/remote-data.utils'; +import { SubmissionFormsModel } from '../../core/config/models/config-submission-forms.model'; +import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; const configRes = Object.assign(new SubmissionFormsModel(), { 'id': 'AccessConditionDefaultConfiguration', diff --git a/src/app/shared/mocks/section-accesses.service.mock.ts b/src/app/shared/mocks/section-accesses.service.mock.ts index 5f2f5defc1..5302b37a63 100644 --- a/src/app/shared/mocks/section-accesses.service.mock.ts +++ b/src/app/shared/mocks/section-accesses.service.mock.ts @@ -1,4 +1,4 @@ -import { SubmissionFormsModel } from 'src/app/core/config/models/config-submission-forms.model'; +import { SubmissionFormsModel } from '../../core/config/models/config-submission-forms.model'; import { of as observableOf } from 'rxjs'; const dataRes = Object.assign(new SubmissionFormsModel(), { diff --git a/src/app/submission/edit/submission-edit.component.ts b/src/app/submission/edit/submission-edit.component.ts index 5512d054dc..9a35c2dfe1 100644 --- a/src/app/submission/edit/submission-edit.component.ts +++ b/src/app/submission/edit/submission-edit.component.ts @@ -6,7 +6,6 @@ import { debounceTime, filter, switchMap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model'; -import { WorkspaceitemSectionAccessesObject } from '../../core/submission/models/workspaceitem-section-accesses.model'; import { hasValue, isEmpty, isNotEmptyOperator, isNotNull } from '../../shared/empty.util'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; import { SubmissionService } from '../submission.service'; @@ -97,13 +96,13 @@ export class SubmissionEditComponent implements OnDestroy, OnInit { * @param {SubmissionJsonPatchOperationsService} submissionJsonPatchOperationsService */ constructor(private changeDetectorRef: ChangeDetectorRef, - private notificationsService: NotificationsService, - private route: ActivatedRoute, - private router: Router, - private itemDataService: ItemDataService, - private submissionService: SubmissionService, - private translate: TranslateService, - private submissionJsonPatchOperationsService: SubmissionJsonPatchOperationsService) { + private notificationsService: NotificationsService, + private route: ActivatedRoute, + private router: Router, + private itemDataService: ItemDataService, + private submissionService: SubmissionService, + private translate: TranslateService, + private submissionJsonPatchOperationsService: SubmissionJsonPatchOperationsService) { } /** @@ -127,8 +126,6 @@ export class SubmissionEditComponent implements OnDestroy, OnInit { this.collectionId = (submissionObjectRD.payload.collection as Collection).id; this.selfUrl = submissionObjectRD.payload._links.self.href; this.sections = submissionObjectRD.payload.sections; - - this.itemLink$.next(submissionObjectRD.payload._links.item.href); this.item = submissionObjectRD.payload.item; this.submissionDefinition = (submissionObjectRD.payload.submissionDefinition as SubmissionDefinitionsModel); diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 2b14f5c8dd..4cbffbca78 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; import { Observable, of as observableOf, Subscription } from 'rxjs'; -import { distinctUntilChanged, filter, map, switchMap, tap } from 'rxjs/operators'; +import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; import { AuthService } from '../../core/auth/auth.service'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; import { Collection } from '../../core/shared/collection.model'; @@ -131,7 +131,6 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { if ((changes.collectionId && this.collectionId) && (changes.submissionId && this.submissionId)) { this.isActive = true; - // retrieve submission's section list this.submissionSections = this.submissionService.getSubmissionObject(this.submissionId).pipe( filter(() => this.isActive), @@ -144,9 +143,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { } else { return observableOf([]); } - }), - tap((res) => { console.log(res); })); - + })); this.uploadEnabled$ = this.sectionsService.isSectionTypeAvailable(this.submissionId, SectionsType.Upload); // check if is submission loading @@ -233,8 +230,6 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { protected getSectionsList(): Observable { return this.submissionService.getSubmissionSections(this.submissionId).pipe( filter((sections: SectionDataObject[]) => isNotEmpty(sections)), - map((sections: SectionDataObject[]) => sections - )); - + map((sections: SectionDataObject[]) => sections)); } } diff --git a/src/app/submission/sections/accesses/section-accesses.component.html b/src/app/submission/sections/accesses/section-accesses.component.html index db5f92013b..6ae8d9160b 100644 --- a/src/app/submission/sections/accesses/section-accesses.component.html +++ b/src/app/submission/sections/accesses/section-accesses.component.html @@ -1,2 +1,6 @@ - \ No newline at end of file + diff --git a/src/app/submission/sections/accesses/section-accesses.component.spec.ts b/src/app/submission/sections/accesses/section-accesses.component.spec.ts index 4c2c5e400b..669d905ec2 100644 --- a/src/app/submission/sections/accesses/section-accesses.component.spec.ts +++ b/src/app/submission/sections/accesses/section-accesses.component.spec.ts @@ -1,29 +1,34 @@ -import { FormService } from './../../../shared/form/form.service'; -import { ComponentFixture, TestBed, inject } from '@angular/core/testing'; +import { FormService } from '../../../shared/form/form.service'; +import { ComponentFixture, inject, TestBed } from '@angular/core/testing'; import { SubmissionSectionAccessesComponent } from './section-accesses.component'; -import { SectionsService } from 'src/app/submission/sections/sections.service'; -import { SectionsServiceStub } from 'src/app/shared/testing/sections-service.stub'; +import { SectionsService } from '../sections.service'; +import { SectionsServiceStub } from '../../../shared/testing/sections-service.stub'; -import { FormBuilderService } from 'src/app/shared/form/builder/form-builder.service'; -import { getMockFormBuilderService } from 'src/app/shared/mocks/form-builder-service.mock'; -import { SubmissionAccessesConfigService } from 'src/app/core/config/submission-accesses-config.service'; -import { getSubmissionAccessesConfigService } from 'src/app/shared/mocks/section-accesses-config.service.mock'; -import { SectionAccessesService } from 'src/app/submission/sections/accesses/section-accesses.service'; -import { SectionFormOperationsService } from 'src/app/submission/sections/form/section-form-operations.service'; -import { JsonPatchOperationsBuilder } from 'src/app/core/json-patch/builder/json-patch-operations-builder'; -import { TranslateService, TranslateModule } from '@ngx-translate/core'; -import { SubmissionJsonPatchOperationsService } from 'src/app/core/submission/submission-json-patch-operations.service'; -import { getSectionAccessesService } from 'src/app/shared/mocks/section-accesses.service.mock'; +import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; +import { getMockFormBuilderService } from '../../../shared/mocks/form-builder-service.mock'; +import { SubmissionAccessesConfigService } from '../../../core/config/submission-accesses-config.service'; +import { getSubmissionAccessesConfigService } from '../../../shared/mocks/section-accesses-config.service.mock'; +import { SectionAccessesService } from './section-accesses.service'; +import { SectionFormOperationsService } from '../form/section-form-operations.service'; +import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; +import { getSectionAccessesService } from '../../../shared/mocks/section-accesses.service.mock'; import { getMockFormOperationsService } from 'src/app/shared/mocks/form-operations-service.mock'; import { getMockTranslateService } from 'src/app/shared/mocks/translate.service.mock'; import { SubmissionJsonPatchOperationsServiceStub } from 'src/app/shared/testing/submission-json-patch-operations-service.stub'; -import { BrowserModule, By } from '@angular/platform-browser'; +import { BrowserModule } from '@angular/platform-browser'; -import { Observable, of as observableOf, observable } from 'rxjs'; -import { select, Store } from '@ngrx/store'; +import { of as observableOf } from 'rxjs'; +import { Store } from '@ngrx/store'; import { FormComponent } from 'src/app/shared/form/form.component'; -import { DynamicFormControlModel, DynamicCheckboxModel, DynamicFormArrayGroupModel, DynamicSelectModel, DynamicDatePickerModel, DynamicFormArrayModel } from '@ng-dynamic-forms/core'; +import { + DynamicCheckboxModel, + DynamicDatePickerModel, + DynamicFormArrayModel, + DynamicSelectModel +} from '@ng-dynamic-forms/core'; import { AppState } from 'src/app/app.reducer'; import { getMockFormService } from 'src/app/shared/mocks/form-service.mock'; import { mockAccessesFormData } from 'src/app/shared/mocks/submission.mock'; diff --git a/src/app/submission/sections/accesses/section-accesses.component.ts b/src/app/submission/sections/accesses/section-accesses.component.ts index abd2e2802a..a1113501ee 100644 --- a/src/app/submission/sections/accesses/section-accesses.component.ts +++ b/src/app/submission/sections/accesses/section-accesses.component.ts @@ -1,15 +1,25 @@ import { SectionAccessesService } from './section-accesses.service'; -import { Component, OnInit, ChangeDetectorRef, Inject, ViewChild } from '@angular/core'; -import { renderSectionFor } from 'src/app/submission/sections/sections-decorator'; -import { SectionsType } from 'src/app/submission/sections/sections-type'; -import { SubmissionService } from 'src/app/submission/submission.service'; -import { SectionDataObject } from 'src/app/submission/sections/models/section-data.model'; -import { SectionsService } from 'src/app/submission/sections/sections.service'; -import { SectionModelComponent } from 'src/app/submission/sections/models/section.model'; -import { Observable, of, Subscription, combineLatest as observableCombineLatest, BehaviorSubject, combineLatest } from 'rxjs'; -import { DynamicFormControlModel, MATCH_ENABLED, OR_OPERATOR, DynamicSelectModel, DynamicDatePickerModel, DynamicFormGroupModel, DynamicFormArrayModel, DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER, DynamicCheckboxModel, DynamicFormControlEvent } from '@ng-dynamic-forms/core'; -import { FormBuilderService } from 'src/app/shared/form/builder/form-builder.service'; -import { findIndex, isEqual } from 'lodash'; +import { Component, Inject, ViewChild } from '@angular/core'; +import { renderSectionFor } from '../sections-decorator'; +import { SectionsType } from '../sections-type'; +import { SectionDataObject } from '../models/section-data.model'; +import { SectionsService } from '../sections.service'; +import { SectionModelComponent } from '../models/section.model'; +import { BehaviorSubject, combineLatest, Observable, of, Subscription } from 'rxjs'; +import { + DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX, + DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER, + DynamicCheckboxModel, + DynamicDatePickerModel, + DynamicFormArrayModel, + DynamicFormControlEvent, + DynamicFormControlModel, + DynamicFormGroupModel, + DynamicSelectModel, + MATCH_ENABLED, + OR_OPERATOR +} from '@ng-dynamic-forms/core'; +import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { ACCESS_CONDITION_GROUP_CONFIG, @@ -21,26 +31,22 @@ import { FORM_ACCESS_CONDITION_START_DATE_CONFIG, FORM_ACCESS_CONDITION_START_DATE_LAYOUT, FORM_ACCESS_CONDITION_TYPE_CONFIG, - FORM_ACCESS_CONDITION_TYPE_LAYOUT, - ACCESS_FORM_CHECKBOX_LAYOUT + FORM_ACCESS_CONDITION_TYPE_LAYOUT } from './section-accesses.model'; -import { isNotEmpty, isNotUndefined, isUndefined, hasValue, isNotNull } from 'src/app/shared/empty.util'; +import { hasValue, isNotEmpty, isNotNull } from '../../../shared/empty.util'; import { WorkspaceitemSectionAccessesObject } from '../../../core/submission/models/workspaceitem-section-accesses.model'; -import { SubmissionAccessesConfigService } from 'src/app/core/config/submission-accesses-config.service'; -import { getFirstSucceededRemoteData } from 'src/app/core/shared/operators'; -import { map, take, filter, mergeMap } from 'rxjs/operators'; -import { FormComponent } from 'src/app/shared/form/form.component'; -import { FormService } from 'src/app/shared/form/form.service'; -import { JsonPatchOperationPathCombiner } from 'src/app/core/json-patch/builder/json-patch-operation-path-combiner'; -import { SectionFormOperationsService } from 'src/app/submission/sections/form/section-form-operations.service'; -import { JsonPatchOperationsBuilder } from 'src/app/core/json-patch/builder/json-patch-operations-builder'; -import { AccessesConditionOption } from 'src/app/core/config/models/config-accesses-conditions-options.model'; +import { SubmissionAccessesConfigService } from '../../../core/config/submission-accesses-config.service'; +import { getFirstSucceededRemoteData } from '../../../core/shared/operators'; +import { filter, map, mergeMap, take } from 'rxjs/operators'; +import { FormComponent } from '../../../shared/form/form.component'; +import { FormService } from '../../../shared/form/form.service'; +import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; +import { SectionFormOperationsService } from '../form/section-form-operations.service'; +import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; +import { AccessesConditionOption } from '../../../core/config/models/config-accesses-conditions-options.model'; import { TranslateService } from '@ngx-translate/core'; -import { FormFieldPreviousValueObject } from 'src/app/shared/form/builder/models/form-field-previous-value-object'; -import { environment } from 'src/environments/environment'; -import { SubmissionObject } from 'src/app/core/submission/models/submission-object.model'; -import { SubmissionJsonPatchOperationsService } from 'src/app/core/submission/submission-json-patch-operations.service'; -import { dateToISOFormat } from 'src/app/shared/date.util'; +import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; +import { dateToISOFormat } from '../../../shared/date.util'; @Component({ selector: 'ds-section-accesses', @@ -71,49 +77,41 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { * @type {WorkspaceitemSectionAccessesObject} */ public accessesData: WorkspaceitemSectionAccessesObject; - - /** - * Array to track all subscriptions and unsubscribe them onDestroy - * @type {Array} - */ - protected subs: Subscription[] = []; - - /** * The collection name this submission belonging to * @type {string} */ public collectionName: string; - /** * Is the upload required * @type {boolean} */ public required$ = new BehaviorSubject(true); - - /** - * The [[JsonPatchOperationPathCombiner]] object - * @type {JsonPatchOperationPathCombiner} - */ - protected pathCombiner: JsonPatchOperationPathCombiner; - - /** - * A map representing all field prevous values - * @type {Map} - */ - protected previousValue: Map = new Map(); - - /** - * A map representing all field on their way to be removed - * @type {Map} - */ - protected fieldsOnTheirWayToBeRemoved: Map = new Map(); - /** * The form model * @type {DynamicFormControlModel[]} */ formModel: DynamicFormControlModel[]; + /** + * Array to track all subscriptions and unsubscribe them onDestroy + * @type {Array} + */ + protected subs: Subscription[] = []; + /** + * The [[JsonPatchOperationPathCombiner]] object + * @type {JsonPatchOperationPathCombiner} + */ + protected pathCombiner: JsonPatchOperationPathCombiner; + /** + * A map representing all field prevous values + * @type {Map} + */ + protected previousValue: Map = new Map(); + /** + * A map representing all field on their way to be removed + * @type {Map} + */ + protected fieldsOnTheirWayToBeRemoved: Map = new Map(); /** * Initialize instance variables @@ -124,6 +122,7 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { * @param {JsonPatchOperationsBuilder} operationsBuilder * @param {SectionFormOperationsService} formOperationsService * @param {FormBuilderService} formBuilderService + * @param {TranslateService} translate * @param {SubmissionAccessesConfigService} accessesConfigService * @param {SectionAccessesService} accessesService * @param {SubmissionJsonPatchOperationsService} operationsService @@ -144,6 +143,129 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { super(undefined, injectedSectionData, injectedSubmissionId); } + /** + * Initialize form model values + * + * @param formModel + * The form model + */ + public initModelData(formModel: DynamicFormControlModel[]) { + this.accessesData.accessConditions.forEach((accessCondition, index) => { + Array.of('name', 'startDate', 'endDate') + .filter((key) => accessCondition.hasOwnProperty(key) && isNotEmpty(accessCondition[key])) + .forEach((key) => { + const metadataModel: any = this.formBuilderService.findById(key, formModel, index); + if (metadataModel) { + if (metadataModel.type === DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER) { + const date = new Date(accessCondition[key]); + metadataModel.value = { + year: date.getUTCFullYear(), + month: date.getUTCMonth() + 1, + day: date.getUTCDate() + }; + } else { + metadataModel.value = accessCondition[key]; + } + } + }); + }); + } + + /** + * Method called when a form dfChange event is fired. + * Dispatch form operations based on changes. + */ + onChange(event: DynamicFormControlEvent) { + if (event.model.type === DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX) { + const path = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); + const value = this.formOperationsService.getFieldValueFromChangeEvent(event); + this.operationsBuilder.replace(this.pathCombiner.getPath(path), value.value, true); + } else { + // validate form + this.formService.validateAllFormFields(this.formRef.formGroup); + this.formService.isValid(this.formId).pipe( + take(1), + filter((isValid) => isValid), + mergeMap(() => this.formService.getFormData(this.formId)), + take(1) + ).subscribe((formData: any) => { + const accessConditionsToSave = []; + formData.accessCondition + .map((accessConditions) => accessConditions.accessConditionGroup) + .filter((accessCondition) => isNotEmpty(accessCondition)) + .forEach((accessCondition) => { + let accessConditionOpt; + + this.availableAccessConditionOptions + .filter((element) => isNotNull(accessCondition.name) && element.name === accessCondition.name[0].value) + .forEach((element) => accessConditionOpt = element); + + if (accessConditionOpt) { + const currentAccessCondition = Object.assign({}, accessCondition); + currentAccessCondition.name = this.retrieveValueFromField(accessCondition.name); + + /* When start and end date fields are deactivated, their values may be still present in formData, + therefore it is necessary to delete them if they're not allowed by the current access condition option. */ + if (!accessConditionOpt.hasStartDate) { + delete currentAccessCondition.startDate; + } else if (accessCondition.startDate) { + const startDate = this.retrieveValueFromField(accessCondition.startDate); + currentAccessCondition.startDate = dateToISOFormat(startDate); + } + if (!accessConditionOpt.hasEndDate) { + delete currentAccessCondition.endDate; + } else if (accessCondition.endDate) { + const endDate = this.retrieveValueFromField(accessCondition.endDate); + currentAccessCondition.endDate = dateToISOFormat(endDate); + } + accessConditionsToSave.push(currentAccessCondition); + } + }); + + this.operationsBuilder.add(this.pathCombiner.getPath('accessConditions'), accessConditionsToSave, true); + }); + } + } + + /** + * Check if the specified form field has already a value stored + * + * @param fieldId + * the section data retrieved from the serverù + * @param index + * the section data retrieved from the server + */ + hasStoredValue(fieldId, index): boolean { + if (isNotEmpty(this.sectionData.data)) { + 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); + } + + /** + * Unsubscribe from all subscriptions + */ + onSectionDestroy() { + this.subs + .filter((subscription) => hasValue(subscription)) + .forEach((subscription) => subscription.unsubscribe()); + } + /** * Initialize all instance variables and retrieve collection default access conditions */ @@ -174,7 +296,6 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { * the section status */ protected getSectionStatus(): Observable { - console.log('Method not implemented.'); return of(true); } @@ -237,8 +358,12 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { const endDate = new DynamicDatePickerModel(endDateConfig, FORM_ACCESS_CONDITION_END_DATE_LAYOUT); const accessConditionGroupConfig = Object.assign({}, ACCESS_CONDITION_GROUP_CONFIG); accessConditionGroupConfig.group = [type]; - if (hasStart.length > 0) { accessConditionGroupConfig.group.push(startDate); } - if (hasEnd.length > 0) { accessConditionGroupConfig.group.push(endDate); } + if (hasStart.length > 0) { + accessConditionGroupConfig.group.push(startDate); + } + if (hasEnd.length > 0) { + accessConditionGroupConfig.group.push(endDate); + } return [new DynamicFormGroupModel(accessConditionGroupConfig, ACCESS_CONDITION_GROUP_LAYOUT)]; }; @@ -252,153 +377,8 @@ export class SubmissionSectionAccessesComponent extends SectionModelComponent { return formModel; } - /** - * Initialize form model values - * - * @param formModel - * The form model - */ - public initModelData(formModel: DynamicFormControlModel[]) { - this.accessesData.accessConditions.forEach((accessCondition, index) => { - Array.of('name', 'startDate', 'endDate') - .filter((key) => accessCondition.hasOwnProperty(key) && isNotEmpty(accessCondition[key])) - .forEach((key) => { - const metadataModel: any = this.formBuilderService.findById(key, formModel, index); - if (metadataModel) { - if (metadataModel.type === DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER) { - const date = new Date(accessCondition[key]); - metadataModel.value = { - year: date.getUTCFullYear(), - month: date.getUTCMonth() + 1, - day: date.getUTCDate() - }; - } else { - metadataModel.value = accessCondition[key]; - } - } - }); - }); - } - - onSubmit() { - // this.formService.validateAllFormFields(this.formRef.formGroup); - } - - /** - * Method called when a form dfChange event is fired. - * Dispatch form operations based on changes. - */ - onChange(event: DynamicFormControlEvent) { - if (event.model.type === 'CHECKBOX') { - const path = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); - const value = this.formOperationsService.getFieldValueFromChangeEvent(event); - this.operationsBuilder.replace(this.pathCombiner.getPath(path), value.value, true); - } else { - // validate form - this.formService.validateAllFormFields(this.formRef.formGroup); - this.formService.isValid(this.formId).pipe( - take(1), - filter((isValid) => isValid), - mergeMap(() => this.formService.getFormData(this.formId)), - take(1), - mergeMap((formData: any) => { - console.log(formData); - const accessConditionsToSave = []; - formData.accessCondition - .map((accessConditions) => accessConditions.accessConditionGroup) - .filter((accessCondition) => isNotEmpty(accessCondition)) - .forEach((accessCondition) => { - let accessConditionOpt; - - this.availableAccessConditionOptions - .filter((element) => isNotNull(accessCondition.name) && element.name === accessCondition.name[0].value) - .forEach((element) => accessConditionOpt = element); - - if (accessConditionOpt) { - const currentAccessCondition = Object.assign({}, accessCondition); - currentAccessCondition.name = this.retrieveValueFromField(accessCondition.name); - - /* When start and end date fields are deactivated, their values may be still present in formData, - therefore it is necessary to delete them if they're not allowed by the current access condition option. */ - if (!accessConditionOpt.hasStartDate) { - delete currentAccessCondition.startDate; - } else if (accessCondition.startDate) { - const startDate = this.retrieveValueFromField(accessCondition.startDate); - currentAccessCondition.startDate = dateToISOFormat(startDate); - } - if (!accessConditionOpt.hasEndDate) { - delete currentAccessCondition.endDate; - } else if (accessCondition.endDate) { - const endDate = this.retrieveValueFromField(accessCondition.endDate); - currentAccessCondition.endDate = dateToISOFormat(endDate); - } - accessConditionsToSave.push(currentAccessCondition); - } - }); - - this.operationsBuilder.add(this.pathCombiner.getPath('accessConditions'), accessConditionsToSave, true); - - return this.formService.getFormData(this.formId); - - }) - ).subscribe((result: SubmissionObject[]) => { - console.log(result); - }); - } - } - protected retrieveValueFromField(field: any) { const temp = Array.isArray(field) ? field[0] : field; return (temp) ? temp.value : undefined; } - /** - * Check if the specified form field has already a value stored - * - * @param fieldId - * the section data retrieved from the serverù - * @param index - * the section data retrieved from the server - */ - hasStoredValue(fieldId, index): boolean { - if (isNotEmpty(this.sectionData.data)) { - return this.sectionData.data.hasOwnProperty(fieldId) && - isNotEmpty(this.sectionData.data[fieldId][index]) && - !this.isFieldToRemove(fieldId, index); - } else { - return false; - } - } - - private hasRelatedCustomError(medatata): boolean { - const index = findIndex(this.sectionData.errorsToShow, { path: this.pathCombiner.getPath(medatata).path }); - if (index !== -1) { - const error = this.sectionData.errorsToShow[index]; - const validator = error.message.replace('error.validation.', ''); - return !environment.form.validatorMap.hasOwnProperty(validator); - } 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); - } - - - /** - * Unsubscribe from all subscriptions - */ - onSectionDestroy() { - this.subs - .filter((subscription) => hasValue(subscription)) - .forEach((subscription) => subscription.unsubscribe()); - } } diff --git a/src/app/submission/sections/accesses/section-accesses.service.ts b/src/app/submission/sections/accesses/section-accesses.service.ts index 04867bbd4b..3845f71871 100644 --- a/src/app/submission/sections/accesses/section-accesses.service.ts +++ b/src/app/submission/sections/accesses/section-accesses.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; -import { Observable, of } from 'rxjs'; -import { distinctUntilChanged, filter, map } from 'rxjs/operators'; +import { Observable } from 'rxjs'; +import { distinctUntilChanged, filter } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { SubmissionState } from '../../submission.reducers'; import { isUndefined } from 'util'; -import { submissionSectionFromIdSelector, submissionSectionDataFromIdSelector } from 'src/app/submission/selectors'; +import { submissionSectionDataFromIdSelector } from '../../selectors'; /** @@ -30,8 +30,6 @@ export class SectionAccessesService { * The submission id * @param sectionId * The section id - * @param fileUUID - * The bitstream UUID * @returns {Observable} * Emits bitstream's metadata */ diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index 218a91e0c4..1c98d9012e 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -37,9 +37,9 @@ import { ResearchEntitiesModule } from '../entity-groups/research-entities/resea import { ThemedSubmissionEditComponent } from './edit/themed-submission-edit.component'; import { ThemedSubmissionSubmitComponent } from './submit/themed-submission-submit.component'; import { ThemedSubmissionImportExternalComponent } from './import-external/themed-submission-import-external.component'; -import { SubmissionSectionAccessesComponent } from 'src/app/submission/sections/accesses/section-accesses.component'; -import { SubmissionAccessesConfigService } from 'src/app/core/config/submission-accesses-config.service'; -import { SectionAccessesService } from 'src/app/submission/sections/accesses/section-accesses.service'; +import { SubmissionSectionAccessesComponent } from './sections/accesses/section-accesses.component'; +import { SubmissionAccessesConfigService } from '../core/config/submission-accesses-config.service'; +import { SectionAccessesService } from './sections/accesses/section-accesses.service'; const DECLARATIONS = [ SubmissionSectionUploadAccessConditionsComponent, diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index eb3daaad46..e1c0fed2ca 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3801,6 +3801,8 @@ + "submission.sections.submit.progressbar.accessCondition": "Item access conditions", + "submission.sections.submit.progressbar.CClicense": "Creative commons license", "submission.sections.submit.progressbar.describe.recycle": "Recycle", @@ -3894,7 +3896,7 @@ "submission.sections.upload.upload-successful": "Upload successful", "submission.sections.accesses.form.discoverable-label": "Discoverable", - + "submission.submit.breadcrumbs": "New submission",