223 lines
6.5 KiB
TypeScript
223 lines
6.5 KiB
TypeScript
import { Component, EventEmitter, Input, OnInit, Output, QueryList, SimpleChanges, ViewChildren } from '@angular/core';
|
|
import { UntypedFormGroup } from '@angular/forms';
|
|
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
|
|
import { Guid } from '@common/types/guid';
|
|
import { ToCEntry } from '../models/toc-entry';
|
|
import { ToCEntryType } from '../models/toc-entry-type.enum';
|
|
import { DescriptionFieldIndicator } from '../../description-editor.model';
|
|
|
|
@Component({
|
|
selector: 'table-of-contents-internal',
|
|
styleUrls: ['./table-of-contents-internal.scss'],
|
|
templateUrl: './table-of-contents-internal.html'
|
|
})
|
|
export class TableOfContentsInternal implements OnInit {
|
|
|
|
@Input() tocentries: ToCEntry[] = null;
|
|
@Input() selected: ToCEntry = null;
|
|
// @Input() visibilityRules:Rule[] = [];
|
|
@Output() entrySelected = new EventEmitter<ToCEntry>();
|
|
@Input() propertiesFormGroup: UntypedFormGroup;
|
|
|
|
expandChildren: boolean[];
|
|
tocEntryTypeEnum = ToCEntryType;
|
|
@Input() TOCENTRY_ID_PREFIX = "";
|
|
@Input() showErrors: boolean = false;
|
|
@Input() hiddenEntries: string[] = [];
|
|
@Input() visibilityRulesService: VisibilityRulesService;
|
|
@ViewChildren(TableOfContentsInternal) internalTables: QueryList<TableOfContentsInternal>;
|
|
|
|
@Input() parentId: string;
|
|
@Input() parentMap: Map<string, DescriptionFieldIndicator[]> = new Map<string, DescriptionFieldIndicator[]>();
|
|
@Input() updatedMap: Map<string, DescriptionFieldIndicator[]> = new Map<string, DescriptionFieldIndicator[]>();
|
|
|
|
constructor() {
|
|
}
|
|
ngOnInit(): void {
|
|
// console.log('component created' + JSON.stringify(this.tocentries));
|
|
if (this.tocentries) {
|
|
this.expandChildren = this.tocentries.map(() => false);
|
|
if (this.selected) {
|
|
for (let i = 0; i < this.tocentries.length; i++) {
|
|
if (this._findTocEntryById(this.selected.id, this.tocentries[i].subEntries)) {
|
|
if (this.expandChildren) {
|
|
this.expandChildren[i] = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.parentMap) {
|
|
this.updatedMap = this.updateMap(this.tocentries, this.parentMap);
|
|
}
|
|
}
|
|
}
|
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
if (changes.selected && this.selected) {
|
|
for (let i = 0; i < this.tocentries.length; i++) {
|
|
if (this._findTocEntryById(this.selected.id, this.tocentries[i].subEntries)) {
|
|
if (this.expandChildren) {
|
|
this.expandChildren[i] = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// if (!this.isActive && this.links && this.links.length > 0) {
|
|
// this.links.forEach(link => {
|
|
// link.selected = false;
|
|
// })
|
|
// this.links[0].selected = true;
|
|
// }
|
|
}
|
|
|
|
updateMap(entries: ToCEntry[], parentMap:Map<string, DescriptionFieldIndicator[]>): Map<string, DescriptionFieldIndicator[]> {
|
|
if (this.parentId == null) return parentMap;
|
|
|
|
let updatedMap = new Map<string, DescriptionFieldIndicator[]>();
|
|
|
|
parentMap.forEach((fields: DescriptionFieldIndicator[], parentId: string) => {
|
|
if (this.parentId === parentId) {
|
|
for (let entry of entries) {
|
|
let entryFields = fields.filter((field: DescriptionFieldIndicator) => field.sectionIds.includes(entry.id) || field.fieldSetId === entry.id || field.fieldId === entry.id )
|
|
|
|
updatedMap.set(entry.id, entryFields);
|
|
}
|
|
}
|
|
});
|
|
|
|
return updatedMap;
|
|
}
|
|
|
|
hasErrors(entryId: string): boolean {
|
|
if (this.updatedMap.size == 0) return true;
|
|
|
|
const fields: DescriptionFieldIndicator[] = this.updatedMap.get(entryId);
|
|
|
|
for (let field of fields) {
|
|
let formFieldName: string = `fieldSets.${field.fieldSetId}.items.0.fields.${field.fieldId}.${field.type}`;
|
|
if (this.isFormFieldValid(formFieldName) === false) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
isFormFieldValid(formFildName: string):boolean {
|
|
if (this.propertiesFormGroup?.get(formFildName) == null) return true;
|
|
|
|
if (this.propertiesFormGroup.get(formFildName).touched === false) return true;
|
|
|
|
return this.propertiesFormGroup.get(formFildName).valid;
|
|
}
|
|
|
|
toggleExpand(index) {
|
|
this.expandChildren[index] = !this.expandChildren[index];
|
|
// console.log(this.expandChildren);
|
|
}
|
|
|
|
navigateToFieldSet(entry: ToCEntry, event) {
|
|
if (entry.type === ToCEntryType.FieldSet) {
|
|
|
|
const fieldSetId = entry.id;
|
|
// const element = document.getElementById(this.TOCENTRY_ID_PREFIX + fieldSetId);
|
|
const element = document.getElementById(fieldSetId);
|
|
if (element) {
|
|
element.click();//open mat expansion panel
|
|
|
|
//scroll asyn in 200 ms so the expansion panel is expanded and the element coordinates are updated
|
|
setTimeout(() => {
|
|
const element = document.getElementById(fieldSetId);
|
|
if (element) {
|
|
element.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
}, 300);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
onEntrySelected(entry: ToCEntry) {
|
|
this.entrySelected.emit(entry);
|
|
}
|
|
|
|
|
|
calculateStyle(entry: ToCEntry) {
|
|
const style = {};
|
|
style['font-size'] = entry.type === this.tocEntryTypeEnum.FieldSet ? '.9em' : '1em';
|
|
return style;
|
|
}
|
|
|
|
calculateClass(entry: ToCEntry) {
|
|
const myClass = {};
|
|
|
|
if (this.selected && entry.id === this.selected.id) {
|
|
myClass['selected'] = true;
|
|
}
|
|
|
|
if (entry.type != this.tocEntryTypeEnum.FieldSet) {
|
|
myClass['section'] = true;
|
|
}
|
|
|
|
if(this.hasErrors(entry.id)) {
|
|
myClass['text-danger'] = true;
|
|
}
|
|
return myClass;
|
|
}
|
|
|
|
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry {
|
|
if (!tocentries || !tocentries.length) {
|
|
return null;
|
|
}
|
|
|
|
let tocEntryFound = tocentries.find(entry => entry.id === id);
|
|
|
|
if (tocEntryFound) {
|
|
return tocEntryFound;
|
|
}
|
|
|
|
for (let entry of tocentries) {
|
|
const result = this._findTocEntryById(id, entry.subEntries);
|
|
if (result) {
|
|
tocEntryFound = result;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tocEntryFound ? tocEntryFound : null;
|
|
}
|
|
public invalidChildsVisible(entry: ToCEntry): boolean {
|
|
if (!entry || !this.visibilityRulesService) {
|
|
return false;
|
|
}
|
|
|
|
if (entry.type != this.tocEntryTypeEnum.FieldSet) {
|
|
return entry.subEntries.some(_ => this.invalidChildsVisible(_));
|
|
}
|
|
if (entry.type === this.tocEntryTypeEnum.FieldSet) {
|
|
const id = entry.id;
|
|
if (!(this.visibilityRulesService.isVisibleMap[id.toString()])) {
|
|
return false;
|
|
}
|
|
// const fieldsArray = entry.form.get('fields') as UntypedFormArray;
|
|
const hasError = !entry.subEntries.every(field => {//every invalid field should be invisible
|
|
//TODO: check this
|
|
// if (field.invalid) {
|
|
// const id = field.id;
|
|
// const isVisible = this.visibilityRulesService.isVisibleMap[id);
|
|
// if (isVisible) {
|
|
// return false;
|
|
// }
|
|
// }
|
|
return true;
|
|
});
|
|
return hasError;
|
|
}
|
|
return false;
|
|
}
|
|
}
|