diff --git a/src/app/core/config/models/config-access-condition-option.model.ts b/src/app/core/config/models/config-access-condition-option.model.ts index 0c25d9aa0f..46bf1b60ce 100644 --- a/src/app/core/config/models/config-access-condition-option.model.ts +++ b/src/app/core/config/models/config-access-condition-option.model.ts @@ -13,6 +13,11 @@ export class AccessConditionOption { */ groupUUID: string; + /** + * The uuid of the Group that contains set of groups this Resource Policy applies to + */ + selectGroupUUID: string; + /** * A boolean representing if this Access Condition has a start date */ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts index fc2c788c02..b24f4a4865 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts @@ -180,9 +180,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo if (changes) { super.ngOnChanges(changes); if (this.model && this.model.placeholder) { - this.translateService.get(this.model.placeholder).subscribe((placeholder) => { - this.model.placeholder = placeholder; - }) + this.model.placeholder = this.translateService.instant(this.model.placeholder); } } } diff --git a/src/app/shared/mocks/mock-submission.ts b/src/app/shared/mocks/mock-submission.ts index 26f9c757ca..922e6ad02d 100644 --- a/src/app/shared/mocks/mock-submission.ts +++ b/src/app/shared/mocks/mock-submission.ts @@ -3,6 +3,7 @@ import { SubmissionDefinitionsModel } from '../../core/config/models/config-subm import { PaginatedList } from '../../core/data/paginated-list'; import { PageInfo } from '../../core/shared/page-info.model'; import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; +import { Group } from '../../core/eperson/models/group.model'; export const mockSectionsData = { traditionalpageone:{ @@ -1364,7 +1365,7 @@ export const mockAccessConditionOptions = [ } ]; -export const mockGroup = { +export const mockGroup = Object.assign(new Group(), { handle: null, permanent: true, self: 'https://rest.api/dspace-spring-rest/api/eperson/groups/123456-g1', @@ -1386,7 +1387,7 @@ export const mockGroup = { }, page: [] } -}; +}); export const mockUploadFiles = [ { diff --git a/src/app/submission/sections/upload/file/edit/file-edit.component.spec.ts b/src/app/submission/sections/upload/file/edit/file-edit.component.spec.ts index 46ed1a57af..3809730abe 100644 --- a/src/app/submission/sections/upload/file/edit/file-edit.component.spec.ts +++ b/src/app/submission/sections/upload/file/edit/file-edit.component.spec.ts @@ -30,6 +30,7 @@ import { FormService } from '../../../../../shared/form/form.service'; import { GLOBAL_CONFIG } from '../../../../../../config'; import { MOCK_SUBMISSION_CONFIG } from '../../../../../shared/testing/mock-submission-config'; import { getMockFormService } from '../../../../../shared/mocks/mock-form-service'; +import { Group } from '../../../../../core/eperson/models/group.model'; describe('UploadSectionFileEditComponent test suite', () => { @@ -44,7 +45,10 @@ describe('UploadSectionFileEditComponent test suite', () => { const sectionId = 'upload'; const collectionId = mockSubmissionCollectionId; const availableAccessConditionOptions = mockUploadConfigResponse.accessConditionOptions; - const availableGroupsMap = new Map([[mockGroup.id, { name: mockGroup.name, uuid: mockGroup.uuid }]]); + const availableGroupsMap: Map = new Map([ + [mockUploadConfigResponse.accessConditionOptions[1].name, [mockGroup as any]], + [mockUploadConfigResponse.accessConditionOptions[2].name, [mockGroup as any]], + ]); const collectionPolicyType = POLICY_DEFAULT_WITH_LIST; const configMetadataForm: any = mockUploadConfigResponse.metadata; const fileIndex = '0'; diff --git a/src/app/submission/sections/upload/file/edit/file-edit.component.ts b/src/app/submission/sections/upload/file/edit/file-edit.component.ts index c44383abc6..ed30b850ac 100644 --- a/src/app/submission/sections/upload/file/edit/file-edit.component.ts +++ b/src/app/submission/sections/upload/file/edit/file-edit.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, Input, OnChanges } from '@angular/core'; +import { ChangeDetectorRef, Component, Input, OnChanges, ViewChild } from '@angular/core'; import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model'; import { @@ -33,6 +33,10 @@ import { SubmissionFormsModel } from '../../../../../core/config/models/config-s import { FormFieldModel } from '../../../../../shared/form/builder/models/form-field.model'; import { AccessConditionOption } from '../../../../../core/config/models/config-access-condition-option.model'; import { SubmissionService } from '../../../../submission.service'; +import { FormService } from '../../../../../shared/form/form.service'; +import { FormComponent } from '../../../../../shared/form/form.component'; +import { FormControl } from '@angular/forms'; +import { Group } from '../../../../../core/eperson/models/group.model'; @Component({ selector: 'ds-submission-upload-section-file-edit', @@ -41,7 +45,7 @@ import { SubmissionService } from '../../../../submission.service'; export class UploadSectionFileEditComponent implements OnChanges { @Input() availableAccessConditionOptions: any[]; - @Input() availableAccessConditionGroups: Map; + @Input() availableAccessConditionGroups: Map; @Input() collectionId; @Input() collectionPolicyType; @Input() configMetadataForm: SubmissionFormsModel; @@ -54,8 +58,11 @@ export class UploadSectionFileEditComponent implements OnChanges { public formModel: DynamicFormControlModel[]; + @ViewChild('formRef') public formRef: FormComponent; + constructor(private cdr: ChangeDetectorRef, private formBuilderService: FormBuilderService, + private formService: FormService, private submissionService: SubmissionService) { } @@ -153,8 +160,8 @@ export class UploadSectionFileEditComponent implements OnChanges { .forEach((key) => { const metadataModel: any = this.formBuilderService.findById(key, formModel, index); if (metadataModel) { - if (key === 'groupUUID') { - this.availableAccessConditionGroups.forEach((group) => { + if (key === 'groupUUID' && this.availableAccessConditionGroups.get(accessCondition.name)) { + this.availableAccessConditionGroups.get(accessCondition.name).forEach((group) => { metadataModel.options.push({ label: group.name, value: group.uuid @@ -189,14 +196,20 @@ export class UploadSectionFileEditComponent implements OnChanges { if (isNotEmpty(accessCondition)) { const showGroups: boolean = accessCondition.hasStartDate === true || accessCondition.hasEndDate === true; - const groupControl = control.parent.get('groupUUID'); - const startDateControl = control.parent.get('startDate'); - const endDateControl = control.parent.get('endDate'); + const groupControl: FormControl = control.parent.get('groupUUID'); + const startDateControl: FormControl = control.parent.get('startDate'); + const endDateControl: FormControl = control.parent.get('endDate'); + + // Clear previous state + groupControl.markAsUntouched(); + startDateControl.markAsUntouched(); + endDateControl.markAsUntouched(); // Clear previous values if (showGroups) { groupControl.setValue(null); } else { + groupControl.clearValidators(); groupControl.setValue(accessCondition.groupUUID); } startDateControl.setValue(null); @@ -204,15 +217,15 @@ export class UploadSectionFileEditComponent implements OnChanges { endDateControl.setValue(null); if (showGroups) { - if (isNotUndefined(accessCondition.groupUUID)) { + if (isNotUndefined(accessCondition.groupUUID) || isNotUndefined(accessCondition.selectGroupUUID)) { const groupOptions = []; - if (isNotUndefined(this.availableAccessConditionGroups.get(accessCondition.groupUUID))) { + if (isNotUndefined(this.availableAccessConditionGroups.get(accessCondition.name))) { const groupModel = this.formBuilderService.findById( 'groupUUID', (model.parent as DynamicFormArrayGroupModel).group) as DynamicSelectModel; - this.availableAccessConditionGroups.forEach((group) => { + this.availableAccessConditionGroups.get(accessCondition.name).forEach((group) => { groupOptions.push({ label: group.name, value: group.uuid diff --git a/src/app/submission/sections/upload/section-upload.component.spec.ts b/src/app/submission/sections/upload/section-upload.component.spec.ts index 1c64d673d3..345b78d358 100644 --- a/src/app/submission/sections/upload/section-upload.component.spec.ts +++ b/src/app/submission/sections/upload/section-upload.component.spec.ts @@ -204,15 +204,17 @@ describe('UploadSectionComponent test suite', () => { comp.onSectionInit(); - const expectedGroupsMap = new Map(); - expectedGroupsMap.set(mockGroup.id, { name: mockGroup.name, uuid: mockGroup.uuid }); + const expectedGroupsMap = new Map([ + [mockUploadConfigResponse.accessConditionOptions[1].name, [mockGroup as any]], + [mockUploadConfigResponse.accessConditionOptions[2].name, [mockGroup as any]], + ]); expect(comp.collectionId).toBe(collectionId); expect(comp.collectionName).toBe(mockCollection.name); expect(comp.availableAccessConditionOptions.length).toBe(4); expect(comp.availableAccessConditionOptions).toEqual(mockUploadConfigResponse.accessConditionOptions as any); expect(compAsAny.subs.length).toBe(2); - expect(compAsAny.availableGroups.size).toBe(1); + expect(compAsAny.availableGroups.size).toBe(2); expect(compAsAny.availableGroups).toEqual(expectedGroupsMap); expect(compAsAny.fileList).toEqual([]); expect(compAsAny.fileIndexes).toEqual([]); @@ -248,15 +250,17 @@ describe('UploadSectionComponent test suite', () => { comp.onSectionInit(); - const expectedGroupsMap = new Map(); - expectedGroupsMap.set(mockGroup.id, { name: mockGroup.name, uuid: mockGroup.uuid }); + const expectedGroupsMap = new Map([ + [mockUploadConfigResponse.accessConditionOptions[1].name, [mockGroup as any]], + [mockUploadConfigResponse.accessConditionOptions[2].name, [mockGroup as any]], + ]); expect(comp.collectionId).toBe(collectionId); expect(comp.collectionName).toBe(mockCollection.name); expect(comp.availableAccessConditionOptions.length).toBe(4); expect(comp.availableAccessConditionOptions).toEqual(mockUploadConfigResponse.accessConditionOptions as any); expect(compAsAny.subs.length).toBe(2); - expect(compAsAny.availableGroups.size).toBe(1); + expect(compAsAny.availableGroups.size).toBe(2); expect(compAsAny.availableGroups).toEqual(expectedGroupsMap); expect(compAsAny.fileList).toEqual(mockUploadFiles); expect(compAsAny.fileIndexes).toEqual(['123456-test-upload']); diff --git a/src/app/submission/sections/upload/section-upload.component.ts b/src/app/submission/sections/upload/section-upload.component.ts index 1caff1b726..ff620cfa65 100644 --- a/src/app/submission/sections/upload/section-upload.component.ts +++ b/src/app/submission/sections/upload/section-upload.component.ts @@ -23,10 +23,16 @@ import { SubmissionService } from '../../submission.service'; import { Collection } from '../../../core/shared/collection.model'; import { ResourcePolicy } from '../../../core/shared/resource-policy.model'; import { AccessConditionOption } from '../../../core/config/models/config-access-condition-option.model'; +import { PaginatedList } from '../../../core/data/paginated-list'; export const POLICY_DEFAULT_NO_LIST = 1; // Banner1 export const POLICY_DEFAULT_WITH_LIST = 2; // Banner2 +export interface AccessConditionGroupsMapEntry { + accessCondition: string; + groups: Group[] +} + @Component({ selector: 'ds-submission-section-upload', styleUrls: ['./section-upload.component.scss'], @@ -62,7 +68,7 @@ export class UploadSectionComponent extends SectionModelComponent { /* * List of Groups available for every access condition */ - protected availableGroups: Map; // Groups for any policy + protected availableGroups: Map; // Groups for any policy protected subs = []; @@ -117,38 +123,47 @@ export class UploadSectionComponent extends SectionModelComponent { : POLICY_DEFAULT_NO_LIST; this.availableGroups = new Map(); - const groups$ = []; + const mapGroups$: Array> = []; // Retrieve Groups for accessConditionPolicies this.availableAccessConditionOptions.forEach((accessCondition: AccessConditionOption) => { if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) { - groups$.push( - this.groupService.findById(accessCondition.groupUUID).pipe( - find((rd: RemoteData) => !rd.isResponsePending && rd.hasSucceeded)) - ); + if (accessCondition.groupUUID) { + mapGroups$.push( + this.groupService.findById(accessCondition.groupUUID).pipe( + find((rd: RemoteData) => !rd.isResponsePending && rd.hasSucceeded), + map((rd: RemoteData) => ({ + accessCondition: accessCondition.name, + groups: [rd.payload] + } as AccessConditionGroupsMapEntry))) + ); + } else if (accessCondition.selectGroupUUID) { + mapGroups$.push( + this.groupService.findById(accessCondition.selectGroupUUID).pipe( + find((rd: RemoteData) => !rd.isResponsePending && rd.hasSucceeded), + tap((group: RemoteData) => console.log(group.payload.groups)), + flatMap((group: RemoteData) => group.payload.groups), + find((rd: RemoteData>) => !rd.isResponsePending && rd.hasSucceeded), + tap((group) => console.log(group)), + map((rd: RemoteData>) => ({ + accessCondition: accessCondition.name, + groups: rd.payload.page + } as AccessConditionGroupsMapEntry)) + )); + } } }); - return groups$; + return mapGroups$; }), - flatMap((group) => group), - reduce((acc: Group[], group: RemoteData) => { - acc.push(group.payload); + flatMap((entry) => entry), + reduce((acc: any[], entry: AccessConditionGroupsMapEntry) => { + acc.push(entry); return acc; }, []), - ).subscribe((groups: Group[]) => { - groups.forEach((group: Group) => { - if (isUndefined(this.availableGroups.get(group.uuid))) { - if (Array.isArray(group.groups)) { - const groupArrayData = []; - for (const groupData of group.groups) { - groupArrayData.push({ name: groupData.name, uuid: groupData.uuid }); - } - this.availableGroups.set(group.uuid, groupArrayData); - } else { - this.availableGroups.set(group.uuid, { name: group.name, uuid: group.uuid }); - } - } + ).subscribe((entries: AccessConditionGroupsMapEntry[]) => { + console.log(entries); + entries.forEach((entry: AccessConditionGroupsMapEntry) => { + this.availableGroups.set(entry.accessCondition, entry.groups); }); - this.changeDetectorRef.detectChanges(); }) ,