Dataset Profile editor. Drag and drop navigation table of contents.
This commit is contained in:
parent
da7f91df96
commit
081995e243
|
@ -1,5 +1,5 @@
|
|||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
||||
import { FormArray, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { FieldEditorModel } from '../../../admin/field-editor-model';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { RuleEditorModel } from '../../../admin/rule-editor-model';
|
||||
|
@ -184,6 +184,8 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
|
|||
field.ordinal = (this.form.get('fields') as FormArray).length;
|
||||
|
||||
const fieldForm = field.buildForm();
|
||||
fieldForm.setValidators(this.customFieldValidator());
|
||||
// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);
|
||||
|
||||
(<FormArray>this.form.get('fields')).push(fieldForm);
|
||||
this.setTargetField(fieldForm);
|
||||
|
@ -329,6 +331,8 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
|
|||
field.ordinal = (this.form.get('fields') as FormArray).length;
|
||||
|
||||
const fieldForm = field.buildForm();
|
||||
fieldForm.setValidators(this.customFieldValidator());
|
||||
// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);
|
||||
|
||||
|
||||
|
||||
|
@ -421,5 +425,51 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
|
|||
|
||||
}
|
||||
|
||||
private customFieldValidator(): ValidatorFn{
|
||||
return (control):ValidationErrors | null=>{
|
||||
DatasetProfileFieldViewStyle
|
||||
switch(control.get('viewStyle').get('renderStyle').value){
|
||||
|
||||
case DatasetProfileFieldViewStyle.TextArea:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.BooleanDecision:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.ComboBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.CheckBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.FreeText:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.RadioBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DatePicker:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.InternalDmpEntities:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.ExternalDatasets:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DataRepositories:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Registries:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Services:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Tags:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Researchers:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Organizations:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DatasetIdentifier:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Currency:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Validation:
|
||||
return null;
|
||||
default:
|
||||
return {inputTypeNotValid: true}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,9 +68,10 @@
|
|||
</mat-select> -->
|
||||
|
||||
<!-- NEW VERSION -->
|
||||
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.VIEW-STYLE' | translate}}" [(value)]="viewType" (selectionChange)="onInputTypeChange()"
|
||||
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.VIEW-STYLE' | translate}}" [(ngModel)]="viewType" (selectionChange)="onInputTypeChange()"
|
||||
[disabled]="viewOnly"
|
||||
required>
|
||||
required
|
||||
>
|
||||
<mat-option [value]="viewTypeEnum.TextArea">{{enumUtils.toDatasetProfileViewTypeString(viewTypeEnum.TextArea)}}</mat-option>
|
||||
<mat-option [value]="viewTypeEnum.FreeText">{{enumUtils.toDatasetProfileViewTypeString(viewTypeEnum.FreeText)}}</mat-option>
|
||||
<mat-divider></mat-divider>
|
||||
|
@ -107,6 +108,8 @@
|
|||
|
||||
</mat-select>
|
||||
<mat-error *ngIf="this.form.get('viewStyle').get('renderStyle').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
<mat-error *ngIf="this.form.hasError('inputTypeNotValid')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Combo Box -->
|
||||
|
@ -209,4 +212,5 @@
|
|||
</em>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
{{form.touched|json}}
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
||||
import { AbstractControl, AbstractControlOptions, FormArray, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
|
||||
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
|
||||
import { ValidationType } from '@app/core/common/enum/validation-type';
|
||||
import { DatasetProfileService } from '@app/core/services/dataset-profile/dataset-profile.service';
|
||||
|
@ -34,7 +34,7 @@ import { AutoCompleteFieldDataEditorModel } from '../../../admin/field-data/auto
|
|||
import { DatasetsAutoCompleteFieldDataEditorModel } from '../../../admin/field-data/datasets-autocomplete-field-data-editor-mode';
|
||||
import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { MatSlideToggleChange } from '@angular/material';
|
||||
import { ErrorStateMatcher, MatSlideToggleChange } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-profile-editor-field-component',
|
||||
|
@ -501,4 +501,5 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
|
|||
onDelete(){
|
||||
this.delete.emit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,8 @@
|
|||
</button>
|
||||
|
||||
|
||||
<ng-container *ngIf="stepper.selectedIndex === (steps.length-1)">
|
||||
<ng-container *ngIf="false">
|
||||
<!-- <ng-container *ngIf="stepper.selectedIndex === (steps.length-1)"> -->
|
||||
<ng-container *ngIf="!viewOnly">
|
||||
|
||||
<button mat-button class="navigate-btn ml-2"
|
||||
|
@ -350,11 +351,17 @@
|
|||
|
||||
</ng-container>
|
||||
|
||||
<!-- <div class="row">
|
||||
<div class="row">
|
||||
<button (click)="printForm()">
|
||||
console form
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<button (click)="printMyErrors()">
|
||||
print errors
|
||||
</button>
|
||||
</div>
|
||||
<!-- <div class="row">
|
||||
<button (click)="foo()">foo</button>
|
||||
</div> -->
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { AfterViewInit, Component, OnChanges, OnInit, QueryList, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { Form, FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { AbstractControl, Form, FormArray, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatHorizontalStepper, MatStep } from '@angular/material/stepper';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
|
@ -38,7 +38,7 @@ import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/vi
|
|||
import { CdkStep, StepperSelectionEvent } from '@angular/cdk/stepper';
|
||||
import { DatasetDescriptionCompositeFieldEditorModel, DatasetDescriptionFieldEditorModel, DatasetDescriptionFormEditorModel, DatasetDescriptionPageEditorModel, DatasetDescriptionSectionEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
|
||||
import { Rule } from '@app/core/model/dataset-profile-definition/rule';
|
||||
|
||||
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
|
||||
const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json');
|
||||
|
||||
@Component({
|
||||
|
@ -532,8 +532,6 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
if(this.selectedTocEntry){
|
||||
this.selectedTocEntry = this._findTocEntryById(this.selectedTocEntry.id, this.toCEntries);
|
||||
}
|
||||
|
||||
|
||||
this.updateOrdinals(this.toCEntries);
|
||||
return this.toCEntries;
|
||||
}
|
||||
|
@ -551,6 +549,22 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
});
|
||||
}
|
||||
|
||||
//sort tocentries based on their ordinality
|
||||
private _sortToCentries(entries: ToCEntry[]){
|
||||
if(!entries || !entries.length) return;
|
||||
entries.sort(this._compareOrdinals);
|
||||
entries.forEach(e=>{
|
||||
this._sortToCentries(e.subEntries)
|
||||
});
|
||||
}
|
||||
private _compareOrdinals(a, b){
|
||||
|
||||
const aValue = a.form.get('ordinal').value as number;
|
||||
const bValue = b.form.get('ordinal').value as number;
|
||||
|
||||
// if(!aValue || !bValue) return 0;
|
||||
return aValue - bValue;
|
||||
}
|
||||
|
||||
toCEntries:ToCEntry[];
|
||||
|
||||
|
@ -601,6 +615,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
pageToAdd.subEntries.push(item);
|
||||
|
||||
});
|
||||
this._sortToCentries(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -678,9 +693,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
}
|
||||
}
|
||||
|
||||
if(tocEntryFound) return tocEntryFound;
|
||||
|
||||
return null;
|
||||
return tocEntryFound? tocEntryFound: null;
|
||||
}
|
||||
addNewEntry(tce: Foo) {
|
||||
|
||||
|
@ -688,81 +701,83 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
|
||||
//define entry type
|
||||
switch (tce.childType) {
|
||||
case ToCEntryType.Page: //CALLED FROM PAGE
|
||||
//create section
|
||||
// this.addPage();
|
||||
// this.displayItem(child);
|
||||
case ToCEntryType.Page:
|
||||
|
||||
|
||||
//ceate page editor model and give ordinal
|
||||
const page: PageEditorModel = new PageEditorModel(this.dataModel.pages.length);
|
||||
this.dataModel.pages.push(page);
|
||||
(<FormArray>this.form.get('pages')).push(page.buildForm());
|
||||
const pageForm = page.buildForm();
|
||||
// this.dataModel.pages.push(page);
|
||||
|
||||
|
||||
//make new entry selected
|
||||
const pagesArray = (this.form.get('pages') as FormArray);
|
||||
const addedEntry = pagesArray.at(pagesArray.length-1) as FormGroup;
|
||||
pagesArray.push(pageForm);
|
||||
|
||||
this.selectedTocEntry = this._findTocEntryById(addedEntry.get('id').value, this.getTocEntries());
|
||||
this.refreshToCEntries();
|
||||
this.selectedTocEntry = this._findTocEntryById(pageForm.get('id').value, this.toCEntries);
|
||||
|
||||
break;
|
||||
case ToCEntryType.Section: //adding a section
|
||||
case ToCEntryType.Section:
|
||||
|
||||
const section: SectionEditorModel = new SectionEditorModel();
|
||||
//give id
|
||||
section.id = Guid.create().toString();
|
||||
let sectionsArray:FormArray;
|
||||
|
||||
//TODO CHECK FOR FORM.ROOT ERROR
|
||||
if (parent.type === ToCEntryType.Page) {
|
||||
//FIRST LEVEL SECTION
|
||||
|
||||
//give ordinal and link to parent
|
||||
section.page = parent.id;
|
||||
section.ordinal = (this.form.get('sections') as FormArray).length;
|
||||
(<FormArray>this.form.get('sections')).push(section.buildForm());
|
||||
|
||||
if (parent.type === ToCEntryType.Page) {//FIRST LEVEL SECTION
|
||||
sectionsArray = this.form.get('sections') as FormArray;
|
||||
} else if( parent.type == ToCEntryType.Section) { //subsection
|
||||
|
||||
section.page = parent.id;
|
||||
section.ordinal = sectionsArray.length;
|
||||
sectionsArray.push(section.buildForm());
|
||||
|
||||
} else if( parent.type == ToCEntryType.Section) { //SUBSECTION OF SECTION
|
||||
sectionsArray = parent.form.get('sections') as FormArray;
|
||||
|
||||
//adding page parent MAYBE NOT NEEDED
|
||||
section.page = parent.form.get('page').value;
|
||||
//MAYBE NOT NEEDED
|
||||
section.ordinal = (parent.form.get('sections') as FormArray).length;
|
||||
(<FormArray>parent.form.get('sections')).push(section.buildForm());
|
||||
section.ordinal = sectionsArray.length;
|
||||
sectionsArray.push(section.buildForm());
|
||||
// (child.form.parent as FormArray).push(section.buildForm());
|
||||
|
||||
sectionsArray = parent.form.get('sections') as FormArray;
|
||||
}else{
|
||||
console.error('BUg found');
|
||||
console.error('Section can only bee child of a page or another section');
|
||||
}
|
||||
|
||||
|
||||
const sectionAdded = sectionsArray.at(sectionsArray.length -1) as FormGroup;
|
||||
|
||||
this.selectedTocEntry = this._findTocEntryById(sectionAdded.get('id').value, this.getTocEntries());
|
||||
|
||||
this.refreshToCEntries();
|
||||
this.selectedTocEntry = this._findTocEntryById(sectionAdded.get('id').value, this.toCEntries);
|
||||
|
||||
break;
|
||||
case ToCEntryType.FieldSet:
|
||||
const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
|
||||
|
||||
|
||||
//create one field form fieldset
|
||||
const field: FieldEditorModel = new FieldEditorModel(); //to ask
|
||||
const field: FieldEditorModel = new FieldEditorModel();
|
||||
field.id = Guid.create().toString();
|
||||
field.ordinal = 0;//first filed in the fields list
|
||||
fieldSet.fields.push(field);
|
||||
const fieldForm = field.buildForm();
|
||||
fieldForm.setValidators(this.customFieldValidator());
|
||||
// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);
|
||||
|
||||
// fieldSet.fields.push(field);
|
||||
// field.ordinal = fieldSet.fields.length-1;
|
||||
|
||||
|
||||
const fieldSetsArray = parent.form.get('fieldSets') as FormArray
|
||||
|
||||
//give fieldset id and ordinal
|
||||
fieldSet.id = Guid.create().toString();
|
||||
fieldSet.ordinal = (parent.form.get('fieldSets') as FormArray).length;
|
||||
const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
|
||||
const fieldSetId = Guid.create().toString();
|
||||
fieldSet.id = fieldSetId;
|
||||
fieldSet.ordinal = fieldSetsArray.length;
|
||||
const fieldsetForm = fieldSet.buildForm();
|
||||
|
||||
|
||||
(<FormArray>parent.form.get('fieldSets')).push(fieldSet.buildForm());
|
||||
|
||||
const parentArray = parent.form.get('fieldSets') as FormArray;
|
||||
const addedFieldSet = parentArray.at(parentArray.length - 1);
|
||||
(fieldsetForm.get('fields') as FormArray).push(fieldForm);
|
||||
fieldSetsArray.push(fieldsetForm);
|
||||
|
||||
this.selectedTocEntry = this._findTocEntryById(addedFieldSet.get('id').value, this.getTocEntries());
|
||||
this.refreshToCEntries();
|
||||
this.selectedTocEntry = this._findTocEntryById(fieldSetId, this.toCEntries);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -770,10 +785,57 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
break;
|
||||
}
|
||||
|
||||
this.refreshToCEntries();
|
||||
// this.refreshToCEntries();
|
||||
}
|
||||
|
||||
|
||||
private customFieldValidator(): ValidatorFn{
|
||||
return (control):ValidationErrors | null=>{
|
||||
DatasetProfileFieldViewStyle
|
||||
switch(control.get('viewStyle').get('renderStyle').value){
|
||||
|
||||
case DatasetProfileFieldViewStyle.TextArea:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.BooleanDecision:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.ComboBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.CheckBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.FreeText:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.RadioBox:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DatePicker:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.InternalDmpEntities:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.ExternalDatasets:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DataRepositories:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Registries:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Services:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Tags:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Researchers:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Organizations:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.DatasetIdentifier:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Currency:
|
||||
return null;
|
||||
case DatasetProfileFieldViewStyle.Validation:
|
||||
return null;
|
||||
default:
|
||||
return {inputTypeNotValid: true};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onRemoveEntry(tce: ToCEntry){
|
||||
|
||||
|
@ -1282,7 +1344,6 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
}
|
||||
|
||||
cloneFieldSet(fieldset: FormGroup){
|
||||
//TODO
|
||||
const values = fieldset.getRawValue();
|
||||
const parentArray = fieldset.parent as FormArray;
|
||||
|
||||
|
@ -1332,4 +1393,124 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
|
|||
this.checkFormValidation();
|
||||
}
|
||||
}
|
||||
|
||||
getFormValidationErrors() {
|
||||
Object.keys(this.form.controls).forEach(key => {
|
||||
|
||||
const controlErrors: ValidationErrors = this.form.get(key).errors;
|
||||
if (controlErrors != null) {
|
||||
Object.keys(controlErrors).forEach(keyError => {
|
||||
console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if(this.form.invalid){
|
||||
console.log('this form is invalid!');
|
||||
console.log(this.form.errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
printMyErrors(){
|
||||
// this._printToCentriesErrrors(this.toCEntries);
|
||||
this._getErrors(this.form);
|
||||
}
|
||||
|
||||
|
||||
private _printToCentriesErrrors(entries: ToCEntry[]){
|
||||
|
||||
if(!entries || !entries.length) return;
|
||||
|
||||
entries.forEach(e=>{
|
||||
|
||||
|
||||
// if(e.form instanceof FormGroup) console.log('is Formgroup');
|
||||
// if(e.form instanceof FormControl) console.log('is formcontrols');
|
||||
// if(e.form instanceof FormArray) console.log('isForm array');
|
||||
|
||||
|
||||
const form = e.form as FormGroup;
|
||||
if(form.invalid){
|
||||
const controls = form.controls;
|
||||
const keys = Object.keys(controls);
|
||||
keys.forEach(key=>{
|
||||
const control = controls[key];
|
||||
|
||||
if(control.invalid){
|
||||
console.log('control ', key, 'is invalid');
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// console.log('keys,', keys);
|
||||
|
||||
|
||||
this._printToCentriesErrrors(e.subEntries);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private _getErrors(aControl: AbstractControl){
|
||||
|
||||
if(aControl instanceof FormGroup) console.log('is Formgroup');
|
||||
if(aControl instanceof FormControl)console.log( aControl.errors);
|
||||
if(aControl instanceof FormArray) console.log('isForm array');
|
||||
if(aControl.valid) return;
|
||||
|
||||
let controlType = 'control';
|
||||
|
||||
if(aControl instanceof FormGroup) controlType="fg"
|
||||
if(aControl instanceof FormControl) controlType="fc";
|
||||
if(aControl instanceof FormArray) controlType="fa";
|
||||
|
||||
|
||||
//invalid
|
||||
switch (controlType){
|
||||
case 'fg':
|
||||
|
||||
const controls = (aControl as FormGroup).controls;
|
||||
const keys = Object.keys(controls);
|
||||
keys.forEach(key=>{
|
||||
const control = controls[key];
|
||||
// if(control.invalid){
|
||||
this._getErrors(control);
|
||||
// }
|
||||
});
|
||||
|
||||
break;
|
||||
case 'fc':
|
||||
//form control print errors
|
||||
console.log(aControl.errors);
|
||||
break;
|
||||
case 'fa':
|
||||
const fa = (aControl as FormArray);
|
||||
fa.controls.forEach(control=>{
|
||||
this._getErrors(control);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// const controls = rootForm.controls;
|
||||
// const keys = Object.keys(controls);
|
||||
// keys.forEach(key=>{
|
||||
// const control = controls[key];
|
||||
|
||||
|
||||
// if(control.invalid){
|
||||
// console.log('control ', key, 'is invalid');
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,7 @@
|
|||
</div>
|
||||
<div class="col-auto d-flex align-items-center" >
|
||||
<span class="badge-ball"
|
||||
*ngIf="!(!((parentLink?.subEntriesType == tocEntryType.FieldSet) && !selectedItemInLinks) || itemSelected?.id == parentLink.id)">
|
||||
*ngIf="!(!((parentLink?.subEntriesType == tocEntryType.FieldSet) && !selectedItemInLinks) || itemSelected?.id == parentLink.id ||isDragging)">
|
||||
{{parentLink.subEntries?.length}}
|
||||
</span>
|
||||
|
||||
|
@ -48,98 +48,108 @@
|
|||
|
||||
<!-- When item is not selected then show only the pages (first level) -->
|
||||
<!-- <ng-container *ngIf="tocEntryIsChildOf(itemSelected,parentLink) || (!itemSelected && parentLink?.subEntriesType == tocEntryType.Page)"> -->
|
||||
<div cdkDropList class="ml-2" [ngClass]="{'border-left-active':itemSelected?.id == parentLink?.id, 'pl-1':itemSelected?.id == parentLink?.id}"
|
||||
[hidden]="!((parentLink?.subEntriesType!= tocEntryType.FieldSet) || selectedItemInLinks || parentLink?.id === itemSelected?.id || dragHoveringOver)"
|
||||
(cdkDropListDropped)="drop($event)"
|
||||
<div dragula="TABLEDRAG" class="ml-2"
|
||||
[ngClass]="{'border-left-active':itemSelected?.id == parentLink?.id, 'pl-1':itemSelected?.id == parentLink?.id, 'pb-4': isDragging && (parentLink?.type!= tocEntryType.FieldSet) && (parentLink?.id != draggingItemId) }"
|
||||
[hidden]="!((parentLink?.subEntriesType!= tocEntryType.FieldSet) || selectedItemInLinks || parentLink?.id === itemSelected?.id || dragHoveringOver ||isDragging)"
|
||||
class="cdk-link-list"
|
||||
[cdkDropListSortingDisabled]="viewOnly"
|
||||
[cdkDropListConnectedTo]="[]"
|
||||
(cdkDropListEntered)="hoveroverEnter()"
|
||||
(cdkDropListExited)="hoveroverLeft()"
|
||||
(cdkDropListDropped)="hoveroverLeft()"
|
||||
[id]="parentLink.id"
|
||||
[cdkDropListData]="links"
|
||||
[ngStyle]="{'border': overContainerId === parentLink?.id? '1px solid #129D99': '', 'min-height': ((!links?.length||(links.length ==1) ) && (parentLink?.type != tocEntryType.FieldSet) && (isDragging) && (draggingItemId != parentLink?.id)) ? '3em':'inherit'}"
|
||||
>
|
||||
|
||||
<ng-container *ngIf="draggingItemId != parentLink?.id">
|
||||
|
||||
<div *ngFor="let link of links; last as isLast"
|
||||
[ngClass]="{'mb-3': link.type === tocEntryType.Page}"
|
||||
cdkDrag
|
||||
[cdkDragStartDelay]="50"
|
||||
>
|
||||
<div class="docs-link mt-0">
|
||||
<!-- <div class="link-name"> -->
|
||||
|
||||
<!-- <div class="table-item row">
|
||||
<div class="col link-info">
|
||||
<span style="cursor: pointer;" [ngClass]="{'active': itemSelected?.id == link.id}" (click)="itemClicked(link)" >
|
||||
{{link.numbering}} {{link.label? link.label : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="table-item-actions col-auto" *ngIf="!viewOnly">
|
||||
<button class="mat-button" (click)="deleteEntry(link)"><mat-icon>delete</mat-icon></button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<!-- For dev purposes -->
|
||||
<!-- <ng-container [ngSwitch]="link.type">
|
||||
<div *ngSwitchCase="tocEntryType.FieldSet">
|
||||
<span style="background-color: yellow;"> Fieldset</span>
|
||||
</div>
|
||||
<div *ngSwitchCase="tocEntryType.Page">
|
||||
<span style="background-color: lightblue;"> Page</span>
|
||||
</div>
|
||||
<div *ngSwitchCase="tocEntryType.Section">
|
||||
<span style="background-color: lightgreen;"> Section</span>
|
||||
</div>
|
||||
</ng-container> -->
|
||||
<!-- </div> -->
|
||||
<!-- <button cdkDragHandle>drab</button> -->
|
||||
<div class="ml-3">
|
||||
<app-dataset-profile-table-of-contents-internal-section
|
||||
[links]="link.subEntries"
|
||||
(itemClick)="itemClicked($event)"
|
||||
(removeEntry)="deleteEntry($event)"
|
||||
[parentLink]="link"
|
||||
[itemSelected] = "itemSelected"
|
||||
(createFooEntry)="createNewEntry($event)"
|
||||
[viewOnly]="viewOnly"
|
||||
(dataNeedsRefresh)="onDataNeedsRefresh()"
|
||||
[dropListGroup]="dropListGroup"
|
||||
[dragHoveringOver]="dragHoveringOver"
|
||||
[dropListStruct]="dropListStruct"
|
||||
[depth]="depth+1">
|
||||
</app-dataset-profile-table-of-contents-internal-section>
|
||||
|
||||
|
||||
|
||||
<!-- <div *ngIf="links && !viewOnly && !(parentLink?.subEntriesType == tocEntryType.Page) " > -->
|
||||
<ng-container *ngIf="selectedItemInLinks && (link.type != tocEntryType.Page) && isLast && (!viewOnly) &&(link.type != tocEntryType.FieldSet)">
|
||||
<button class="mat-button add-new-entry" style="padding-left: 0px;" (click)="createNewEntry({childType:link.type,parent:parentLink})">
|
||||
<!-- <mat-icon>add</mat-icon> -->
|
||||
<ng-container [ngSwitch]="link.type">
|
||||
<ng-container *ngSwitchCase="tocEntryType.Section">
|
||||
Subsection +
|
||||
</ng-container>
|
||||
<!-- <ng-container *ngSwitchCase="tocEntryType.Page">
|
||||
Section
|
||||
</ng-container> -->
|
||||
<ng-container *ngSwitchCase="tocEntryType.FieldSet">
|
||||
Field +
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
</button>
|
||||
<!-- <button (click)="showDroplists()">show droplist</button> -->
|
||||
</ng-container>
|
||||
<div *ngFor="let link of links; last as isLast"
|
||||
[ngClass]="{'mb-3': link.type === tocEntryType.Page}"
|
||||
[id]="DRAGULA_ITEM_ID_PREFIX + link.id"
|
||||
>
|
||||
<div class="docs-link mt-0">
|
||||
<!-- <div class="link-name"> -->
|
||||
|
||||
<!-- <div class="table-item row">
|
||||
<div class="col link-info">
|
||||
<span style="cursor: pointer;" [ngClass]="{'active': itemSelected?.id == link.id}" (click)="itemClicked(link)" >
|
||||
{{link.numbering}} {{link.label? link.label : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="table-item-actions col-auto" *ngIf="!viewOnly">
|
||||
<button class="mat-button" (click)="deleteEntry(link)"><mat-icon>delete</mat-icon></button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<!-- For dev purposes -->
|
||||
<!-- <ng-container [ngSwitch]="link.type">
|
||||
<div *ngSwitchCase="tocEntryType.FieldSet">
|
||||
<span style="background-color: yellow;"> Fieldset</span>
|
||||
</div>
|
||||
<div *ngSwitchCase="tocEntryType.Page">
|
||||
<span style="background-color: lightblue;"> Page</span>
|
||||
</div>
|
||||
<div *ngSwitchCase="tocEntryType.Section">
|
||||
<span style="background-color: lightgreen;"> Section</span>
|
||||
</div>
|
||||
</ng-container> -->
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <button cdkDragHandle>drab</button> -->
|
||||
<div class="ml-3">
|
||||
<app-dataset-profile-table-of-contents-internal-section
|
||||
[links]="link.subEntries"
|
||||
(itemClick)="itemClicked($event)"
|
||||
(removeEntry)="deleteEntry($event)"
|
||||
[parentLink]="link"
|
||||
[itemSelected] = "itemSelected"
|
||||
(createFooEntry)="createNewEntry($event)"
|
||||
[viewOnly]="viewOnly"
|
||||
(dataNeedsRefresh)="onDataNeedsRefresh()"
|
||||
[dropListGroup]="dropListGroup"
|
||||
[dragHoveringOver]="dragHoveringOver"
|
||||
[dropListStruct]="dropListStruct"
|
||||
[depth]="depth+1"
|
||||
[DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX"
|
||||
[overContainerId]="overContainerId"
|
||||
[isDragging]="isDragging"
|
||||
[draggingItemId]="draggingItemId"
|
||||
[parentRootId]="parentRootId">
|
||||
</app-dataset-profile-table-of-contents-internal-section>
|
||||
|
||||
</div> <!-- END OF LOOP-->
|
||||
|
||||
|
||||
<ng-container *ngIf="!isDragging">
|
||||
|
||||
<!-- <div *ngIf="links && !viewOnly && !(parentLink?.subEntriesType == tocEntryType.Page) " > -->
|
||||
<ng-container *ngIf="selectedItemInLinks && (link.type != tocEntryType.Page) && isLast && (!viewOnly) &&(link.type != tocEntryType.FieldSet)">
|
||||
<button class="mat-button add-new-entry" style="padding-left: 0px;" (click)="createNewEntry({childType:link.type,parent:parentLink})">
|
||||
<!-- <mat-icon>add</mat-icon> -->
|
||||
<ng-container [ngSwitch]="link.type">
|
||||
<ng-container *ngSwitchCase="tocEntryType.Section">
|
||||
Subsection +
|
||||
</ng-container>
|
||||
<!-- <ng-container *ngSwitchCase="tocEntryType.Page">
|
||||
Section
|
||||
</ng-container> -->
|
||||
<ng-container *ngSwitchCase="tocEntryType.FieldSet">
|
||||
Field +
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
</button>
|
||||
<!-- <button (click)="showDroplists()">show droplist</button> -->
|
||||
</ng-container>
|
||||
<!-- </div> -->
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- END OF LOOP-->
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<ng-container *ngIf="!isDragging">
|
||||
|
||||
|
||||
|
||||
<!-- BUILD SUBENTRIES IF THEY DONT EXIST -- CURRENT ITEM DOES HAVE CHILDREN -->
|
||||
<div *ngIf="(!links && parentLink.type!= tocEntryType.FieldSet) && !viewOnly &&parentLink?.id == itemSelected?.id" class="docs-link mt-0">
|
||||
<div class="ml-3">
|
||||
|
@ -181,14 +191,16 @@
|
|||
</button>
|
||||
</ng-container>
|
||||
</div> -->
|
||||
<!-- </ng-container> -->
|
||||
<!-- </ng-container> -->
|
||||
|
||||
<!-- Only for the page -->
|
||||
<div *ngIf="parentLink?.subEntriesType == tocEntryType.Page && !viewOnly">
|
||||
<button class="mat-button ml-3 mt-2" (click)="createNewEntry({childType:parentLink.subEntriesType,parent:parentLink})" style="padding-left:0px">
|
||||
<!-- <mat-icon>add</mat-icon> -->
|
||||
Section +
|
||||
</button>
|
||||
<!-- <button (click)="showDroplists()">show droplist</button>
|
||||
<button (click)="showStructs()">structs</button> -->
|
||||
</div>
|
||||
<!-- Only for the page -->
|
||||
<div *ngIf="parentLink?.subEntriesType == tocEntryType.Page && !viewOnly">
|
||||
<button class="mat-button ml-3 mt-2" (click)="createNewEntry({childType:parentLink.subEntriesType,parent:parentLink})" style="padding-left:0px">
|
||||
<!-- <mat-icon>add</mat-icon> -->
|
||||
Section +
|
||||
</button>
|
||||
<!-- <button (click)="showDroplists()">show droplist</button>
|
||||
<button (click)="showStructs()">structs</button> -->
|
||||
</div>
|
||||
|
||||
</ng-container>
|
|
@ -25,6 +25,11 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
|
|||
|
||||
@Input() parentLink: ToCEntry;
|
||||
@Input() itemSelected: ToCEntry;
|
||||
@Input() DRAGULA_ITEM_ID_PREFIX;
|
||||
@Input() overContainerId: string;
|
||||
@Input() isDragging;
|
||||
@Input() draggingItemId: string;
|
||||
@Input() parentRootId: string;
|
||||
|
||||
@Input() viewOnly: boolean;
|
||||
// @Input() dropListGroup: Set<string> = new Set<string>();
|
||||
|
@ -193,4 +198,35 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
|
|||
onDataNeedsRefresh(){
|
||||
this.dataNeedsRefresh.emit();
|
||||
}
|
||||
|
||||
|
||||
get hoveringOverParent(){
|
||||
if(!this.overContainerId) return false;
|
||||
const child = this._findTocEntryById(this.overContainerId, this.parentLink.subEntries);
|
||||
if(!child) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
|
||||
if(!tocentries){
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -9,11 +9,16 @@
|
|||
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"
|
||||
(newEntry)="addNewEntry($event)" (removeEntry)="deleteEntry($event)"
|
||||
(createFooEntry)="createNewEntry($event)"
|
||||
[parentLink]="{ subEntriesType: tocEntryType.Page, subEntries : links , id: 'foo'}"
|
||||
[parentLink]="{ subEntriesType: tocEntryType.Page, subEntries : links , id: ROOT_ID}"
|
||||
[itemSelected]="itemSelected"
|
||||
[viewOnly]="viewOnly"
|
||||
(dataNeedsRefresh)="onDataNeedsRefresh()"
|
||||
[dropListGroup]="[]"
|
||||
[DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX"
|
||||
[overContainerId]="overcontainer"
|
||||
[isDragging]="isDragging"
|
||||
[draggingItemId]="draggingItemId"
|
||||
[parentRootId]="ROOT_ID"
|
||||
></app-dataset-profile-table-of-contents-internal-section>
|
||||
|
||||
<!-- <span *ngFor="let link of links; let i = index" (click)="toggle(link); goToStep(link);" class="docs-link mt-0">
|
||||
|
|
|
@ -6,6 +6,8 @@ import { distinctUntilChanged } from 'rxjs/operators';
|
|||
import { type } from 'os';
|
||||
import { SimpleChanges } from '@angular/core';
|
||||
import { Foo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
|
||||
import { DragulaService } from 'ng2-dragula';
|
||||
import { FormArray } from '@angular/forms';
|
||||
|
||||
export interface Link {
|
||||
/* id of the section*/
|
||||
|
@ -54,15 +56,420 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
|
|||
|
||||
@Input() isActive: boolean;
|
||||
show: boolean = false;
|
||||
isDragging: boolean = false;
|
||||
draggingItemId: string = null;
|
||||
|
||||
tocEntryType = ToCEntryType;
|
||||
|
||||
DRAGULA_ITEM_ID_PREFIX="table_item_id_";
|
||||
ROOT_ID: string = "ROOT_ID";//no special meaning
|
||||
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private _document: Document) {
|
||||
@Inject(DOCUMENT) private _document: Document,
|
||||
private dragulaService: DragulaService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
||||
if(this.dragulaService.find('TABLEDRAG')){
|
||||
this.dragulaService.destroy('TABLEDRAG');
|
||||
}
|
||||
|
||||
const dragula = this.dragulaService.createGroup('TABLEDRAG', {
|
||||
invalid: (el,handle)=>{
|
||||
// const elid = el.id;
|
||||
// if(!el.id) return true;
|
||||
|
||||
// const elementId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
||||
// const entry = this._findTocEntryById(elementId, this.links);
|
||||
// if(!entry) return true;
|
||||
// if(entry.type != this.tocEntryType.FieldSet) return true;
|
||||
// console.log(el);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
const drake = dragula.drake;
|
||||
|
||||
drake.on('drop', (el, target, source,sibling)=>{
|
||||
// console.log('el:', el);
|
||||
// console.log('target:', target);
|
||||
// console.log('source:', source);
|
||||
// console.log('sibling:', el);
|
||||
|
||||
const elementId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
||||
const targetId = target.id as string;
|
||||
const sourceId = source.id as string;
|
||||
|
||||
|
||||
if(!(elementId && targetId && sourceId)){
|
||||
console.error('Elements not have an id');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const element:ToCEntry = this._findTocEntryById(elementId, this.links);
|
||||
const targetContainer:ToCEntry = this._findTocEntryById(targetId , this.links);
|
||||
const sourceContainer:ToCEntry = this._findTocEntryById(sourceId, this.links);
|
||||
|
||||
if(!(element && (targetContainer ||((element.type===ToCEntryType.Page) && (targetId === this.ROOT_ID))) && (sourceContainer||((element.type===ToCEntryType.Page) && (sourceId === this.ROOT_ID))))){
|
||||
console.info('Could not find elements');
|
||||
this.dataNeedsRefresh.emit();
|
||||
drake.cancel(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch(element.type){
|
||||
case ToCEntryType.FieldSet:
|
||||
if(targetContainer.type != this.tocEntryType.Section){
|
||||
console.error('Fieldsets can only be childs of section');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
//check if target container has no sections
|
||||
if((targetContainer.form.get('sections') as FormArray).length){
|
||||
console.error('Fieldsets can only be childs of section thas has no section children');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldsetForm = element.form;
|
||||
const targetFieldsets = targetContainer.form.get('fieldSets') as FormArray;
|
||||
const sourceFieldsets = sourceContainer.form.get('fieldSets') as FormArray;
|
||||
|
||||
if(!targetFieldsets){
|
||||
console.error('Not target fieldsets container found');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
let sourceOrdinal=-1;
|
||||
let idx = -1;
|
||||
sourceFieldsets.controls.forEach((elem,index)=>{
|
||||
if(elem.get('id').value === elementId){
|
||||
sourceOrdinal = elem.get('ordinal').value;
|
||||
idx = index
|
||||
}
|
||||
});
|
||||
|
||||
if(sourceOrdinal>=0 && idx>=0){
|
||||
sourceFieldsets.removeAt(idx);
|
||||
|
||||
sourceFieldsets.controls.forEach(control=>{
|
||||
const ordinal = control.get('ordinal');
|
||||
if(ordinal.value>= sourceOrdinal){
|
||||
const updatedOrdinalVal = ordinal.value -1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let position:number = targetFieldsets.length;
|
||||
|
||||
if(!sibling ||!sibling.id){
|
||||
console.info('No sibling Id found');
|
||||
}else{
|
||||
const siblingId = (sibling.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
||||
let siblingIndex = -1;
|
||||
targetFieldsets.controls.forEach((e,idx)=>{
|
||||
if(e.get('id').value === siblingId){
|
||||
siblingIndex = idx;
|
||||
position = e.get('ordinal').value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if(siblingIndex>=0 && (position!=targetFieldsets.length)){
|
||||
|
||||
targetFieldsets.controls.filter(control=> control.get('ordinal').value >= position).forEach(control=>{
|
||||
const ordinal = control.get('ordinal');
|
||||
const updatedOrdinalVal = ordinal.value +1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fieldsetForm.get('ordinal').setValue(position);
|
||||
targetFieldsets.insert(position,fieldsetForm);
|
||||
|
||||
this.dataNeedsRefresh.emit();
|
||||
|
||||
break;
|
||||
case ToCEntryType.Section:
|
||||
|
||||
if(targetContainer.type == ToCEntryType.Section){
|
||||
if((targetContainer.form.get('fieldSets')as FormArray).length){
|
||||
console.info('Target container must only contain section children');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
const targetSections = targetContainer.form.get('sections') as FormArray;
|
||||
const elementSectionForm = element.form;
|
||||
const sourceSections = elementSectionForm.parent as FormArray;
|
||||
|
||||
if(!(targetSections && sourceSections && elementSectionForm)){
|
||||
console.info('Could not load sections');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
let idx = -1;
|
||||
sourceSections.controls.forEach((section,i)=>{
|
||||
if(section.get('id').value === elementId){
|
||||
idx = i;
|
||||
}
|
||||
});
|
||||
|
||||
if(!(idx>=0)){
|
||||
console.info('Could not find element in Parent container');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
sourceSections.controls.filter(control=>control.get('ordinal').value >= elementSectionForm.get('ordinal').value).forEach(control=>{
|
||||
const ordinal = control.get('ordinal');
|
||||
const updatedOrdinalVal = ordinal.value -1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
});
|
||||
|
||||
|
||||
sourceSections.removeAt(idx);
|
||||
|
||||
let targetOrdinal = targetSections.length;
|
||||
|
||||
if(sibling && sibling.id){
|
||||
const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
||||
|
||||
targetSections.controls.forEach((section,i)=>{
|
||||
if(section.get('id').value === siblingId){
|
||||
targetOrdinal = section.get('ordinal').value;
|
||||
}
|
||||
})
|
||||
|
||||
if(targetOrdinal!=targetSections.length){
|
||||
// section.get('ordinal').setValue(i+1);
|
||||
targetSections.controls.filter(control=> control.get('ordinal').value>=targetOrdinal).forEach(control=>{
|
||||
const ordinal = control.get('ordinal');
|
||||
const updatedOrdinalVal = ordinal.value+1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
});
|
||||
}
|
||||
|
||||
}else{
|
||||
console.info('no siblings found');
|
||||
}
|
||||
elementSectionForm.get('ordinal').setValue(targetOrdinal);
|
||||
targetSections.insert(targetOrdinal, elementSectionForm);
|
||||
|
||||
}else if(targetContainer.type === ToCEntryType.Page){
|
||||
const pageId = targetContainer.form.get('id').value;
|
||||
|
||||
const rootform = targetContainer.form.root;
|
||||
const sectionForm = element.form;
|
||||
const parentSections = sectionForm.parent as FormArray;
|
||||
|
||||
let parentIndex = -1;
|
||||
parentSections.controls.forEach((section,i )=>{
|
||||
if(section.get('id').value === elementId){
|
||||
parentIndex = i
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
if(parentIndex<0){
|
||||
console.info('could not locate section in parents array');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
//update parent sections ordinal
|
||||
parentSections.controls.filter(section=>section.get('ordinal').value >= sectionForm.get('ordinal').value).forEach(section=>{
|
||||
const ordinal = section.get('ordinal');
|
||||
const updatedOrdinalVal = ordinal.value -1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
})
|
||||
|
||||
parentSections.removeAt(parentIndex);
|
||||
|
||||
|
||||
|
||||
let position = 0;
|
||||
if(targetContainer.subEntries){
|
||||
position = targetContainer.subEntries.length;
|
||||
}
|
||||
//populate sections
|
||||
const targetSectionsArray = rootform.get('sections') as FormArray;
|
||||
|
||||
|
||||
if(sibling && sibling.id){
|
||||
const siblingId= sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
||||
let indx = -1;
|
||||
|
||||
targetContainer.subEntries.forEach((e,i)=>{//TOOD TO CHECK IF ORDINAL AND INDEX IS THE SAME
|
||||
if(e.form.get('id').value === siblingId){
|
||||
indx = i;
|
||||
position = e.form.get('ordinal').value;
|
||||
}
|
||||
});
|
||||
if(indx>=0 && position !=targetContainer.subEntries.length) {
|
||||
|
||||
// e.form.get('ordinal').setValue(i+1);
|
||||
targetContainer.subEntries.filter(e=>e.form.get('ordinal').value >= position).forEach(e=>{
|
||||
const ordinal = e.form.get('ordinal');
|
||||
const updatedOrdinalVal = ordinal.value +1;
|
||||
ordinal.setValue(updatedOrdinalVal);
|
||||
});
|
||||
}
|
||||
|
||||
}else{
|
||||
console.info('No sibling found');
|
||||
}
|
||||
|
||||
sectionForm.get('ordinal').setValue(position);
|
||||
sectionForm.get('page').setValue(targetContainer.id);
|
||||
targetSectionsArray.push(sectionForm);
|
||||
|
||||
}else{
|
||||
console.info('Drag not support to specific container');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.dataNeedsRefresh.emit();
|
||||
break;
|
||||
case ToCEntryType.Page:
|
||||
if(targetId != this.ROOT_ID){
|
||||
console.info('A page element can only be at top level');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
const rootForm = element.form.root;
|
||||
if(!rootForm){
|
||||
console.info('Could not find root!')
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const pages = rootForm.get('pages') as FormArray;
|
||||
const pageForm = element.form;
|
||||
|
||||
let index = -1;
|
||||
|
||||
pages.controls.forEach((page,i)=>{
|
||||
if(page.get('id').value === elementId){
|
||||
index =i;
|
||||
}
|
||||
});
|
||||
|
||||
if(index<0){
|
||||
console.info('Could not locate page on pages');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//ordinality
|
||||
pages.controls.filter(page=> page.get('ordinal').value> pageForm.get('ordinal').value).forEach(page=>{
|
||||
const ordinal = page.get('ordinal');
|
||||
const ordinalVal = ordinal.value - 1;
|
||||
ordinal.setValue(ordinalVal);
|
||||
});
|
||||
|
||||
pages.removeAt(index);
|
||||
|
||||
let targetPosition = pages.length;
|
||||
|
||||
if(sibling){
|
||||
const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
||||
|
||||
pages.controls.forEach((page,i)=>{
|
||||
if(page.get('id').value === siblingId){
|
||||
targetPosition = page.get('ordinal').value;
|
||||
}
|
||||
});
|
||||
}
|
||||
pageForm.get('ordinal').setValue(targetPosition);
|
||||
|
||||
//update ordinality
|
||||
pages.controls.filter(page=> page.get('ordinal').value>= targetPosition).forEach(page=>{
|
||||
const ordinal = page.get('ordinal');
|
||||
const ordinalVal = ordinal.value +1;
|
||||
ordinal.setValue(ordinalVal);
|
||||
});
|
||||
|
||||
|
||||
pages.insert(targetPosition, pageForm);
|
||||
this.dataNeedsRefresh.emit();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
console.error('Could not support moving objects for specific type of element');
|
||||
this.dataNeedsRefresh.emit();
|
||||
return;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
drake.on('drag',(el,source)=>{
|
||||
this.isDragging = true;
|
||||
this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
||||
});
|
||||
drake.on('over',(el, container, source)=>{
|
||||
try {
|
||||
this.overcontainer = container.id;
|
||||
} catch (error) {
|
||||
this.overcontainer = null;
|
||||
}
|
||||
});
|
||||
drake.on('dragend',(el)=>{
|
||||
this.isDragging = false;
|
||||
this.draggingItemId = null;
|
||||
this.overcontainer = null;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
overcontainer: string = null;
|
||||
|
||||
|
||||
|
||||
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
|
||||
if(!tocentries){
|
||||
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;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
//emit value every 500ms
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
/* added to the source element while its mirror is dragged */
|
||||
.gu-transit {
|
||||
opacity: 0;
|
||||
border: 1px dashed red;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
||||
filter: alpha(opacity=20);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue