mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 19:43:04 +00:00

We could turn these rules off, but it seems that they indicate some important inconsistencies.
A few cases have been ignored inline because they should be investigated in more detail, which is out of scope for this PR:
- Metadata representation components compare `BrowseByDataType` to a `ResourceType`. Could be related to #2949.
- We assume that dynamic form dates are always represented by strings, but they can also be `Date` or `object` according to the library (see da1742ce05/projects/ng-dynamic-forms/core/src/lib/model/dynamic-date-control.model.ts (L5)
)
175 lines
5.8 KiB
TypeScript
175 lines
5.8 KiB
TypeScript
import {
|
|
Injectable,
|
|
Injector,
|
|
} from '@angular/core';
|
|
import {
|
|
DYNAMIC_FORM_CONTROL_TYPE_ARRAY,
|
|
DynamicFormGroupModelConfig,
|
|
} from '@ng-dynamic-forms/core';
|
|
import uniqueId from 'lodash/uniqueId';
|
|
|
|
import { SubmissionScopeType } from '../../../../core/submission/submission-scope-type';
|
|
import {
|
|
isEmpty,
|
|
isNotEmpty,
|
|
} from '../../../empty.util';
|
|
import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from '../ds-dynamic-form-ui/ds-dynamic-form-constants';
|
|
import { DynamicRowGroupModel } from '../ds-dynamic-form-ui/models/ds-dynamic-row-group-model';
|
|
import { FormFieldModel } from '../models/form-field.model';
|
|
import { SubmissionFieldScopeType } from './../../../../core/submission/submission-field-scope-type';
|
|
import { SectionVisibility } from './../../../../submission/objects/section-visibility.model';
|
|
import {
|
|
CONFIG_DATA,
|
|
FieldParser,
|
|
INIT_FORM_VALUES,
|
|
PARSER_OPTIONS,
|
|
SUBMISSION_ID,
|
|
} from './field-parser';
|
|
import { setLayout } from './parser.utils';
|
|
import { ParserFactory } from './parser-factory';
|
|
import { ParserOptions } from './parser-options';
|
|
import { ParserType } from './parser-type';
|
|
|
|
export const ROW_ID_PREFIX = 'df-row-group-config-';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
|
|
/**
|
|
* Parser the submission data for a single row
|
|
*/
|
|
export class RowParser {
|
|
constructor(private parentInjector: Injector) {
|
|
}
|
|
|
|
public parse(submissionId: string,
|
|
rowData,
|
|
scopeUUID,
|
|
initFormValues: any,
|
|
submissionScope,
|
|
readOnly: boolean,
|
|
typeField: string): DynamicRowGroupModel {
|
|
let fieldModel: any = null;
|
|
let parsedResult = null;
|
|
const config: DynamicFormGroupModelConfig = {
|
|
id: uniqueId(ROW_ID_PREFIX),
|
|
group: [],
|
|
};
|
|
|
|
const scopedFields: FormFieldModel[] = this.filterScopedFields(rowData.fields, submissionScope);
|
|
|
|
const layoutDefaultGridClass = ' col-sm-' + Math.trunc(12 / scopedFields.length);
|
|
const layoutClass = ' d-flex flex-column justify-content-start';
|
|
|
|
const parserOptions: ParserOptions = {
|
|
readOnly: readOnly,
|
|
submissionScope: submissionScope,
|
|
collectionUUID: scopeUUID,
|
|
typeField: typeField,
|
|
};
|
|
|
|
// Iterate over row's fields
|
|
scopedFields.forEach((fieldData: FormFieldModel) => {
|
|
|
|
const layoutFieldClass = (fieldData.style || layoutDefaultGridClass) + layoutClass;
|
|
const parserProvider = ParserFactory.getProvider(fieldData.input.type as ParserType);
|
|
if (parserProvider) {
|
|
const fieldInjector = Injector.create({
|
|
providers: [
|
|
parserProvider,
|
|
{ provide: SUBMISSION_ID, useValue: submissionId },
|
|
{ provide: CONFIG_DATA, useValue: fieldData },
|
|
{ provide: INIT_FORM_VALUES, useValue: initFormValues },
|
|
{ provide: PARSER_OPTIONS, useValue: parserOptions },
|
|
],
|
|
parent: this.parentInjector,
|
|
});
|
|
|
|
fieldModel = fieldInjector.get(FieldParser).parse();
|
|
} else {
|
|
throw new Error(`unknown form control model type "${fieldData.input.type}" defined for Input field with label "${fieldData.label}".`);
|
|
}
|
|
|
|
if (fieldModel) {
|
|
if (fieldModel.type === DYNAMIC_FORM_CONTROL_TYPE_ARRAY || fieldModel.type === DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP) {
|
|
if (rowData.fields.length > 1) {
|
|
setLayout(fieldModel, 'grid', 'host', layoutFieldClass);
|
|
config.group.push(fieldModel);
|
|
// if (isEmpty(parsedResult)) {
|
|
// parsedResult = [];
|
|
// }
|
|
// parsedResult.push(fieldModel);
|
|
} else {
|
|
parsedResult = fieldModel;
|
|
}
|
|
return;
|
|
} else {
|
|
if (Array.isArray(fieldModel)) {
|
|
fieldModel.forEach((model) => {
|
|
parsedResult = model;
|
|
return;
|
|
});
|
|
} else {
|
|
setLayout(fieldModel, 'grid', 'host', layoutFieldClass);
|
|
config.group.push(fieldModel);
|
|
}
|
|
}
|
|
fieldModel = null;
|
|
}
|
|
});
|
|
|
|
if (config && !isEmpty(config.group)) {
|
|
const clsGroup = {
|
|
element: {
|
|
control: 'form-row',
|
|
},
|
|
};
|
|
const groupModel = new DynamicRowGroupModel(config, clsGroup);
|
|
if (Array.isArray(parsedResult)) {
|
|
parsedResult.push(groupModel);
|
|
} else {
|
|
parsedResult = groupModel;
|
|
}
|
|
}
|
|
return parsedResult;
|
|
}
|
|
|
|
checksFieldScope(fieldScope, submissionScope, visibility: SectionVisibility) {
|
|
return (isEmpty(fieldScope) || !this.isHidden(visibility, fieldScope, submissionScope));
|
|
}
|
|
|
|
/**
|
|
* Check if the field is hidden or not.
|
|
* It is hidden when we do have the scope,
|
|
* but we do not have the visibility,
|
|
* also the field scope should be different from the submissionScope.
|
|
* @param visibility The visibility of the field
|
|
* @param scope the scope of the field
|
|
* @param submissionScope the scope of the submission
|
|
* @returns If the field is hidden or not
|
|
*/
|
|
private isHidden(visibility: SectionVisibility, scope: string, submissionScope: string): boolean {
|
|
return isNotEmpty(scope)
|
|
&& (
|
|
isEmpty(visibility)
|
|
&& (
|
|
submissionScope === SubmissionScopeType.WorkspaceItem.valueOf() && scope !== SubmissionFieldScopeType.WorkspaceItem.valueOf()
|
|
||
|
|
submissionScope === SubmissionScopeType.WorkflowItem.valueOf() && scope !== SubmissionFieldScopeType.WorkflowItem.valueOf()
|
|
)
|
|
);
|
|
}
|
|
|
|
filterScopedFields(fields: FormFieldModel[], submissionScope): FormFieldModel[] {
|
|
const filteredFields: FormFieldModel[] = [];
|
|
fields.forEach((field: FormFieldModel) => {
|
|
// Whether field scope doesn't match the submission scope, skip it
|
|
if (this.checksFieldScope(field.scope, submissionScope, field.visibility)) {
|
|
filteredFields.push(field);
|
|
}
|
|
});
|
|
return filteredFields;
|
|
}
|
|
}
|