[Port dspace-8_x] Fix issue with submission sections visibility (#3761)

* Removing position-fixed bootstrap class so that navbar links are available again

(cherry picked from commit 351abaa5c2)
(cherry picked from commit 5c4df8765e)

* A new approach so that the elements of the ds-file-dropzone-no-uploader component don't overlap the navbar and make it inaccessible

(cherry picked from commit 2c259f5ae9)
(cherry picked from commit ee5af8f7d1)

* [DURACOM-291] fix submission section visibility in order to rely on the configured section scope

(cherry picked from commit 8e8979a27a)

* Removing position-fixed bootstrap class so that navbar links are available again

(cherry picked from commit 351abaa5c2)
(cherry picked from commit 3ecec3af51)

* A new approach so that the elements of the ds-file-dropzone-no-uploader component don't overlap the navbar and make it inaccessible

(cherry picked from commit 2c259f5ae9)
(cherry picked from commit 25e2c763be)

---------

Co-authored-by: root <root@TI-03.OHB.LOCAL>
Co-authored-by: Giuseppe Digilio <giuseppe.digilio@4science.com>
This commit is contained in:
DSpace Bot
2024-12-18 15:57:30 -06:00
committed by GitHub
parent 6380f132af
commit 819e693cfc
13 changed files with 534 additions and 86 deletions

View File

@@ -4,20 +4,16 @@ import {
inheritSerialization, inheritSerialization,
} from 'cerialize'; } from 'cerialize';
import {
SectionScope,
SectionVisibility,
} from '../../../submission/objects/section-visibility.model';
import { SectionsType } from '../../../submission/sections/sections-type'; import { SectionsType } from '../../../submission/sections/sections-type';
import { typedObject } from '../../cache/builders/build-decorators'; import { typedObject } from '../../cache/builders/build-decorators';
import { HALLink } from '../../shared/hal-link.model'; import { HALLink } from '../../shared/hal-link.model';
import { ConfigObject } from './config.model'; import { ConfigObject } from './config.model';
import { SUBMISSION_SECTION_TYPE } from './config-type'; import { SUBMISSION_SECTION_TYPE } from './config-type';
/**
* An interface that define section visibility and its properties.
*/
export interface SubmissionSectionVisibility {
main: any;
other: any;
}
@typedObject @typedObject
@inheritSerialization(ConfigObject) @inheritSerialization(ConfigObject)
export class SubmissionSectionModel extends ConfigObject { export class SubmissionSectionModel extends ConfigObject {
@@ -35,6 +31,12 @@ export class SubmissionSectionModel extends ConfigObject {
@autoserialize @autoserialize
mandatory: boolean; mandatory: boolean;
/**
* The submission scope for this section
*/
@autoserialize
scope: SectionScope;
/** /**
* A string representing the kind of section object * A string representing the kind of section object
*/ */
@@ -42,10 +44,10 @@ export class SubmissionSectionModel extends ConfigObject {
sectionType: SectionsType; sectionType: SectionsType;
/** /**
* The [SubmissionSectionVisibility] object for this section * The [SectionVisibility] object for this section
*/ */
@autoserialize @autoserialize
visibility: SubmissionSectionVisibility; visibility: SectionVisibility;
/** /**
* The {@link HALLink}s for this SubmissionSectionModel * The {@link HALLink}s for this SubmissionSectionModel

View File

@@ -22,10 +22,7 @@ import {
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model';
import { import { SubmissionSectionModel } from '../../core/config/models/config-submission-section.model';
SubmissionSectionModel,
SubmissionSectionVisibility,
} from '../../core/config/models/config-submission-section.model';
import { Collection } from '../../core/shared/collection.model'; import { Collection } from '../../core/shared/collection.model';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
@@ -38,6 +35,7 @@ import {
} from '../../shared/empty.util'; } from '../../shared/empty.util';
import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component';
import { UploaderOptions } from '../../shared/upload/uploader/uploader-options.model'; import { UploaderOptions } from '../../shared/upload/uploader/uploader-options.model';
import { SectionVisibility } from '../objects/section-visibility.model';
import { SubmissionError } from '../objects/submission-error.model'; import { SubmissionError } from '../objects/submission-error.model';
import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer';
import { SubmissionSectionContainerComponent } from '../sections/container/section-container.component'; import { SubmissionSectionContainerComponent } from '../sections/container/section-container.component';
@@ -233,7 +231,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
/** /**
* Returns the visibility object of the collection section * Returns the visibility object of the collection section
*/ */
private getCollectionVisibility(): SubmissionSectionVisibility { private getCollectionVisibility(): SectionVisibility {
const submissionSectionModel: SubmissionSectionModel = const submissionSectionModel: SubmissionSectionModel =
this.submissionDefinition.sections.page.find( this.submissionDefinition.sections.page.find(
(section) => isEqual(section.sectionType, SectionsType.Collection), (section) => isEqual(section.sectionType, SectionsType.Collection),

View File

@@ -5,3 +5,9 @@ export interface SectionVisibility {
main: any; main: any;
other: any; other: any;
} }
export enum SectionScope {
Submission = 'SUBMISSION',
Workflow = 'WORKFLOW',
}

View File

@@ -11,7 +11,10 @@ import {
} from '../../core/submission/models/workspaceitem-sections.model'; } from '../../core/submission/models/workspaceitem-sections.model';
import { type } from '../../shared/ngrx/type'; import { type } from '../../shared/ngrx/type';
import { SectionsType } from '../sections/sections-type'; import { SectionsType } from '../sections/sections-type';
import { SectionVisibility } from './section-visibility.model'; import {
SectionScope,
SectionVisibility,
} from './section-visibility.model';
import { SubmissionError } from './submission-error.model'; import { SubmissionError } from './submission-error.model';
import { SubmissionSectionError } from './submission-section-error.model'; import { SubmissionSectionError } from './submission-section-error.model';
@@ -120,6 +123,7 @@ export class InitSectionAction implements Action {
header: string; header: string;
config: string; config: string;
mandatory: boolean; mandatory: boolean;
scope: SectionScope;
sectionType: SectionsType; sectionType: SectionsType;
visibility: SectionVisibility; visibility: SectionVisibility;
enabled: boolean; enabled: boolean;
@@ -140,6 +144,8 @@ export class InitSectionAction implements Action {
* the section's config * the section's config
* @param mandatory * @param mandatory
* the section's mandatory * the section's mandatory
* @param scope
* the section's scope
* @param sectionType * @param sectionType
* the section's type * the section's type
* @param visibility * @param visibility
@@ -156,12 +162,13 @@ export class InitSectionAction implements Action {
header: string, header: string,
config: string, config: string,
mandatory: boolean, mandatory: boolean,
scope: SectionScope,
sectionType: SectionsType, sectionType: SectionsType,
visibility: SectionVisibility, visibility: SectionVisibility,
enabled: boolean, enabled: boolean,
data: WorkspaceitemSectionDataType, data: WorkspaceitemSectionDataType,
errors: SubmissionSectionError[]) { errors: SubmissionSectionError[]) {
this.payload = { submissionId, sectionId, header, config, mandatory, sectionType, visibility, enabled, data, errors }; this.payload = { submissionId, sectionId, header, config, mandatory, scope, sectionType, visibility, enabled, data, errors };
} }
} }

View File

@@ -167,6 +167,7 @@ describe('SubmissionObjectEffects test suite', () => {
sectionDefinition.header, sectionDefinition.header,
config, config,
sectionDefinition.mandatory, sectionDefinition.mandatory,
sectionDefinition.scope,
sectionDefinition.sectionType, sectionDefinition.sectionType,
sectionDefinition.visibility, sectionDefinition.visibility,
enabled, enabled,

View File

@@ -116,6 +116,7 @@ export class SubmissionObjectEffects {
sectionDefinition.header, sectionDefinition.header,
config, config,
sectionDefinition.mandatory, sectionDefinition.mandatory,
sectionDefinition.scope,
sectionDefinition.sectionType, sectionDefinition.sectionType,
sectionDefinition.visibility, sectionDefinition.visibility,
enabled, enabled,

View File

@@ -237,6 +237,7 @@ describe('submissionReducer test suite', () => {
header: 'submit.progressbar.describe.stepone', header: 'submit.progressbar.describe.stepone',
config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone', config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone',
mandatory: true, mandatory: true,
scope: null,
sectionType: 'submission-form', sectionType: 'submission-form',
visibility: undefined, visibility: undefined,
collapsed: false, collapsed: false,
@@ -257,6 +258,7 @@ describe('submissionReducer test suite', () => {
'submit.progressbar.describe.stepone', 'submit.progressbar.describe.stepone',
'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone', 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone',
true, true,
null,
SectionsType.SubmissionForm, SectionsType.SubmissionForm,
undefined, undefined,
true, true,

View File

@@ -565,6 +565,7 @@ function initSection(state: SubmissionObjectState, action: InitSectionAction): S
header: action.payload.header, header: action.payload.header,
config: action.payload.config, config: action.payload.config,
mandatory: action.payload.mandatory, mandatory: action.payload.mandatory,
scope: action.payload.scope,
sectionType: action.payload.sectionType, sectionType: action.payload.sectionType,
visibility: action.payload.visibility, visibility: action.payload.visibility,
collapsed: false, collapsed: false,

View File

@@ -1,6 +1,9 @@
import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model'; import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model';
import { SectionsType } from '../sections/sections-type'; import { SectionsType } from '../sections/sections-type';
import { SectionVisibility } from './section-visibility.model'; import {
SectionScope,
SectionVisibility,
} from './section-visibility.model';
import { SubmissionSectionError } from './submission-section-error.model'; import { SubmissionSectionError } from './submission-section-error.model';
/** /**
@@ -22,6 +25,11 @@ export interface SubmissionSectionObject {
*/ */
mandatory: boolean; mandatory: boolean;
/**
* The submission scope for this section
*/
scope: SectionScope;
/** /**
* The section type * The section type
*/ */

View File

@@ -35,6 +35,7 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import { SubmissionServiceStub } from '../../shared/testing/submission-service.stub'; import { SubmissionServiceStub } from '../../shared/testing/submission-service.stub';
import { SectionScope } from '../objects/section-visibility.model';
import { import {
DisableSectionAction, DisableSectionAction,
EnableSectionAction, EnableSectionAction,
@@ -265,10 +266,28 @@ describe('SectionsService test suite', () => {
}); });
describe('isSectionReadOnly', () => { describe('isSectionReadOnly', () => {
it('should return an observable of true when it\'s a readonly section and scope is not workspace', () => { describe('when submission scope is workspace', () => {
describe('and section scope is workspace', () => {
it('should return an observable of true when visibility main is READONLY and visibility other is null', () => {
store.select.and.returnValue(observableOf({ store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: { visibility: {
main: null, main: 'READONLY',
other: null,
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
it('should return an observable of true when both visibility main and other are READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: {
main: 'READONLY',
other: 'READONLY', other: 'READONLY',
}, },
})); }));
@@ -277,11 +296,11 @@ describe('SectionsService test suite', () => {
b: true, b: true,
}); });
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected); expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
}); });
it('should return an observable of false when visibility main is null and visibility other is READONLY', () => {
it('should return an observable of false when it\'s a readonly section and scope is workspace', () => {
store.select.and.returnValue(observableOf({ store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: { visibility: {
main: null, main: null,
other: 'READONLY', other: 'READONLY',
@@ -294,9 +313,148 @@ describe('SectionsService test suite', () => {
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected); expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
}); });
it('should return an observable of false when visibility is null', () => {
it('should return an observable of false when it\'s not a readonly section', () => {
store.select.and.returnValue(observableOf({ store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: null,
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
});
describe('and section scope is workflow', () => {
it('should return an observable of false when visibility main is READONLY and visibility other is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: 'READONLY',
other: null,
},
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
it('should return an observable of true when both visibility main and other are READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: 'READONLY',
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
it('should return an observable of true when visibility main is null and visibility other is READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: null,
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
it('should return an observable of false when visibility is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: null,
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
});
describe('and section scope is null', () => {
it('should return an observable of false', () => {
store.select.and.returnValue(observableOf({
scope: null,
visibility: null,
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
});
});
});
describe('when submission scope is workflow', () => {
describe('and section scope is workspace', () => {
it('should return an observable of false when visibility main is READONLY and visibility other is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: {
main: 'READONLY',
other: null,
},
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of true when both visibility main and other are READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: {
main: 'READONLY',
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of true when visibility main is null and visibility other is READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: {
main: null,
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of false when visibility is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Submission,
visibility: null, visibility: null,
})); }));
@@ -306,6 +464,85 @@ describe('SectionsService test suite', () => {
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected); expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
}); });
});
describe('and section scope is workflow', () => {
it('should return an observable of true when visibility main is READONLY and visibility other is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: 'READONLY',
other: null,
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of true when both visibility main and other is READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: 'READONLY',
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: true,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of false when visibility main is null and visibility other is READONLY', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: {
main: null,
other: 'READONLY',
},
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
it('should return an observable of false when visibility is null', () => {
store.select.and.returnValue(observableOf({
scope: SectionScope.Workflow,
visibility: null,
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
});
describe('and section scope is null', () => {
it('should return an observable of false', () => {
store.select.and.returnValue(observableOf({
scope: null,
visibility: null,
}));
const expected = cold('(b|)', {
b: false,
});
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
});
});
});
}); });
describe('isSectionAvailable', () => { describe('isSectionAvailable', () => {

View File

@@ -36,6 +36,7 @@ import { FormClearErrorsAction } from '../../shared/form/form.actions';
import { FormError } from '../../shared/form/form.reducer'; import { FormError } from '../../shared/form/form.reducer';
import { FormService } from '../../shared/form/form.service'; import { FormService } from '../../shared/form/form.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { SectionScope } from '../objects/section-visibility.model';
import { import {
DisableSectionAction, DisableSectionAction,
EnableSectionAction, EnableSectionAction,
@@ -347,10 +348,14 @@ export class SectionsService {
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe( return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
filter((sectionObj) => hasValue(sectionObj)), filter((sectionObj) => hasValue(sectionObj)),
map((sectionObj: SubmissionSectionObject) => { map((sectionObj: SubmissionSectionObject) => {
return isNotEmpty(sectionObj.visibility) if (isEmpty(submissionScope) || isEmpty(sectionObj.visibility) || isEmpty(sectionObj.scope)) {
&& ((sectionObj.visibility.other === 'READONLY' && submissionScope !== SubmissionScopeType.WorkspaceItem) return false;
|| (sectionObj.visibility.main === 'READONLY' && submissionScope === SubmissionScopeType.WorkspaceItem) }
); const convertedSubmissionScope: SectionScope = submissionScope.valueOf() === SubmissionScopeType.WorkspaceItem.valueOf() ?
SectionScope.Submission : SectionScope.Workflow;
const visibility = convertedSubmissionScope.valueOf() === sectionObj.scope.valueOf() ?
sectionObj.visibility.main : sectionObj.visibility.other;
return visibility === 'READONLY';
}), }),
distinctUntilChanged()); distinctUntilChanged());
} }

View File

@@ -52,6 +52,7 @@ import { NotificationsService } from '../shared/notifications/notifications.serv
import { createFailedRemoteDataObject } from '../shared/remote-data.utils'; import { createFailedRemoteDataObject } from '../shared/remote-data.utils';
import { SubmissionJsonPatchOperationsServiceStub } from '../shared/testing/submission-json-patch-operations-service.stub'; import { SubmissionJsonPatchOperationsServiceStub } from '../shared/testing/submission-json-patch-operations-service.stub';
import { SubmissionRestServiceStub } from '../shared/testing/submission-rest-service.stub'; import { SubmissionRestServiceStub } from '../shared/testing/submission-rest-service.stub';
import { SectionScope } from './objects/section-visibility.model';
import { import {
CancelSubmissionFormAction, CancelSubmissionFormAction,
ChangeSubmissionCollectionAction, ChangeSubmissionCollectionAction,
@@ -82,6 +83,7 @@ describe('SubmissionService test suite', () => {
extraction: { extraction: {
config: '', config: '',
mandatory: true, mandatory: true,
scope: SectionScope.Submission,
sectionType: 'utils', sectionType: 'utils',
visibility: { visibility: {
main: 'HIDDEN', main: 'HIDDEN',
@@ -98,6 +100,7 @@ describe('SubmissionService test suite', () => {
collection: { collection: {
config: '', config: '',
mandatory: true, mandatory: true,
scope: SectionScope.Submission,
sectionType: 'collection', sectionType: 'collection',
visibility: { visibility: {
main: 'HIDDEN', main: 'HIDDEN',
@@ -237,6 +240,7 @@ describe('SubmissionService test suite', () => {
extraction: { extraction: {
config: '', config: '',
mandatory: true, mandatory: true,
scope: SectionScope.Submission,
sectionType: 'utils', sectionType: 'utils',
visibility: { visibility: {
main: 'HIDDEN', main: 'HIDDEN',
@@ -253,6 +257,7 @@ describe('SubmissionService test suite', () => {
collection: { collection: {
config: '', config: '',
mandatory: true, mandatory: true,
scope: SectionScope.Submission,
sectionType: 'collection', sectionType: 'collection',
visibility: { visibility: {
main: 'HIDDEN', main: 'HIDDEN',
@@ -590,6 +595,7 @@ describe('SubmissionService test suite', () => {
describe('getSubmissionSections', () => { describe('getSubmissionSections', () => {
it('should return submission form sections', () => { it('should return submission form sections', () => {
spyOn(service, 'getSubmissionScope').and.returnValue(SubmissionScopeType.WorkspaceItem);
spyOn((service as any).store, 'select').and.returnValue(hot('a|', { spyOn((service as any).store, 'select').and.returnValue(hot('a|', {
a: subState.objects[826], a: subState.objects[826],
})); }));
@@ -759,6 +765,7 @@ describe('SubmissionService test suite', () => {
describe('getSubmissionStatus', () => { describe('getSubmissionStatus', () => {
it('should return properly submission status', () => { it('should return properly submission status', () => {
spyOn(service, 'getSubmissionScope').and.returnValue(SubmissionScopeType.WorkspaceItem);
spyOn((service as any).store, 'select').and.returnValue(hot('-a-b', { spyOn((service as any).store, 'select').and.returnValue(hot('-a-b', {
a: subState, a: subState,
b: validSubState, b: validSubState,
@@ -818,41 +825,207 @@ describe('SubmissionService test suite', () => {
}); });
describe('isSectionHidden', () => { describe('isSectionHidden', () => {
it('should return true/false when section is hidden/visible', () => { describe('when submission scope is workspace', () => {
beforeEach(() => {
spyOn(service, 'getSubmissionScope').and.returnValue(SubmissionScopeType.WorkspaceItem);
});
describe('and section scope is workspace', () => {
it('should return true when visibility main is HIDDEN and visibility other is null', () => {
let section: any = { let section: any = {
config: '', scope: SectionScope.Submission,
header: '', visibility: {
mandatory: true, main: 'HIDDEN',
sectionType: 'collection' as any, other: null,
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return true when both visibility main and other are HIDDEN', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: { visibility: {
main: 'HIDDEN', main: 'HIDDEN',
other: 'HIDDEN', other: 'HIDDEN',
}, },
collapsed: false,
enabled: true,
data: {},
errorsToShow: [],
serverValidationErrors: [],
isLoading: false,
isValid: false,
}; };
expect(service.isSectionHidden(section)).toBeTruthy(); expect(service.isSectionHidden(section)).toBeTrue();
section = {
header: 'submit.progressbar.describe.keyinformation',
config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/keyinformation',
mandatory: true,
sectionType: 'submission-form',
collapsed: false,
enabled: true,
data: {},
errorsToShow: [],
serverValidationErrors: [],
isLoading: false,
isValid: false,
};
expect(service.isSectionHidden(section)).toBeFalsy();
}); });
it('should return false when visibility main is null and visibility other is HIDDEN', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: {
main: null,
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
it('should return false when visibility is null', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: null,
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
describe('and section scope is workflow', () => {
it('should return false when visibility main is HIDDEN and visibility other is null', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: 'HIDDEN',
other: null,
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
it('should return true when both visibility main and other are HIDDEN', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: 'HIDDEN',
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return true when visibility main is null and visibility other is HIDDEN', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: null,
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return false when visibility is null', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: null,
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
describe('and section scope is null', () => {
it('should return false', () => {
let section: any = {
scope: null,
visibility: {
main: 'HIDDEN',
other: null,
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
});
describe('when submission scope is workflow', () => {
beforeEach(() => {
spyOn(service, 'getSubmissionScope').and.returnValue(SubmissionScopeType.WorkflowItem);
});
describe('and section scope is workspace', () => {
it('should return false when visibility main is HIDDEN and visibility other is null', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: {
main: 'HIDDEN',
other: null,
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
it('should return true when both visibility main and other are HIDDEN', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: {
main: 'HIDDEN',
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return true when visibility main is null and visibility other is HIDDEN', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: {
main: null,
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return false when visibility is null', () => {
let section: any = {
scope: SectionScope.Submission,
visibility: null,
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
describe('and section scope is workflow', () => {
it('should return true when visibility main is HIDDEN and visibility other is null', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: 'HIDDEN',
other: null,
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return true when both visibility main and other are HIDDEN', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: 'HIDDEN',
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeTrue();
});
it('should return false when visibility main is null and visibility other is HIDDEN', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: {
main: null,
other: 'HIDDEN',
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
it('should return false when visibility is null', () => {
let section: any = {
scope: SectionScope.Workflow,
visibility: null,
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
describe('and section scope is null', () => {
it('should return false', () => {
let section: any = {
scope: null,
visibility: {
main: 'HIDDEN',
other: null,
},
};
expect(service.isSectionHidden(section)).toBeFalse();
});
});
});
}); });
describe('isSubmissionLoading', () => { describe('isSubmissionLoading', () => {

View File

@@ -50,6 +50,7 @@ import {
createFailedRemoteDataObject$, createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject,
} from '../shared/remote-data.utils'; } from '../shared/remote-data.utils';
import { SectionScope } from './objects/section-visibility.model';
import { SubmissionError } from './objects/submission-error.model'; import { SubmissionError } from './objects/submission-error.model';
import { import {
CancelSubmissionFormAction, CancelSubmissionFormAction,
@@ -504,9 +505,15 @@ export class SubmissionService {
* true if section is hidden, false otherwise * true if section is hidden, false otherwise
*/ */
isSectionHidden(sectionData: SubmissionSectionObject): boolean { isSectionHidden(sectionData: SubmissionSectionObject): boolean {
return (isNotUndefined(sectionData.visibility) const submissionScope: SubmissionScopeType = this.getSubmissionScope();
&& sectionData.visibility.main === 'HIDDEN' if (isEmpty(submissionScope) || isEmpty(sectionData.visibility) || isEmpty(sectionData.scope)) {
&& sectionData.visibility.other === 'HIDDEN'); return false;
}
const convertedSubmissionScope: SectionScope = submissionScope.valueOf() === SubmissionScopeType.WorkspaceItem.valueOf() ?
SectionScope.Submission : SectionScope.Workflow;
const visibility = convertedSubmissionScope.valueOf() === sectionData.scope.valueOf() ?
sectionData.visibility.main : sectionData.visibility.other;
return visibility === 'HIDDEN';
} }
/** /**