From 133c2db70ffc1efb153c820a292d98a615d7eb4b Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Fri, 30 Jul 2021 16:23:33 +0200
Subject: [PATCH] [player] Adapt structure of form to unit definition

* Create `FormGroups` without ids
* Add `FormArray` for elements
---
 projects/common/form.ts                       |  3 +--
 .../components/element-overlay.component.ts   | 19 ++++++++++++++++---
 .../src/app/components/form.component.ts      | 10 ++++------
 .../src/app/components/page.component.ts      |  5 ++---
 .../src/app/components/section.component.ts   | 10 +++++-----
 5 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/projects/common/form.ts b/projects/common/form.ts
index 90d911e85..804e44d11 100644
--- a/projects/common/form.ts
+++ b/projects/common/form.ts
@@ -18,8 +18,7 @@ export interface FormControlValidators {
 }
 
 export interface ChildFormGroup {
-  id: string;
   formGroup: FormGroup;
   parentForm: FormGroup;
-  parentArray: 'pages' | 'sections'
+  parentArray: 'pages' | 'sections' | 'elements'
 }
diff --git a/projects/player/src/app/components/element-overlay.component.ts b/projects/player/src/app/components/element-overlay.component.ts
index d88d4ab2c..3ac1a797b 100644
--- a/projects/player/src/app/components/element-overlay.component.ts
+++ b/projects/player/src/app/components/element-overlay.component.ts
@@ -3,7 +3,7 @@ import {
   ComponentFactory, ComponentFactoryResolver, ComponentRef,
   ViewChild, ViewContainerRef
 } from '@angular/core';
-import { FormGroup } from '@angular/forms';
+import { FormBuilder, FormGroup } from '@angular/forms';
 import { Subject } from 'rxjs';
 import { takeUntil } from 'rxjs/operators';
 import { UnitUIElement } from '../../../../common/unit';
@@ -27,6 +27,7 @@ import { FormService } from '../../../../common/form.service';
 export class ElementOverlayComponent implements OnInit, OnDestroy {
   @Input() elementModel!: UnitUIElement;
   @Input() parentForm!: FormGroup;
+  private elementForm!: FormGroup;
 
   @ViewChild('elementComponentContainer',
     { read: ViewContainerRef, static: true }) private elementComponentContainer!: ViewContainerRef;
@@ -37,6 +38,7 @@ export class ElementOverlayComponent implements OnInit, OnDestroy {
   private ngUnsubscribe = new Subject<void>();
 
   constructor(private formService: FormService,
+              private formBuilder: FormBuilder,
               private componentFactoryResolver: ComponentFactoryResolver) { }
 
   ngOnInit(): void {
@@ -46,7 +48,9 @@ export class ElementOverlayComponent implements OnInit, OnDestroy {
     elementComponent.elementModel = this.elementModel;
 
     if (elementComponent instanceof FormElementComponent) {
-      elementComponent.parentForm = this.parentForm;
+      this.registerFormGroup();
+
+      elementComponent.parentForm = this.elementForm;
       elementComponent.formValueChanged
         .pipe(takeUntil(this.ngUnsubscribe))
         .subscribe((changeElement: ValueChangeElement) => {
@@ -58,11 +62,20 @@ export class ElementOverlayComponent implements OnInit, OnDestroy {
       const validationMessageComponentRef: ComponentRef<ValidationMessageComponent> =
         this.validationMessageComponentContainer.createComponent(validationMessageComponentFactory);
 
-      validationMessageComponentRef.instance.parentForm = this.parentForm;
+      validationMessageComponentRef.instance.parentForm = this.elementForm;
       validationMessageComponentRef.instance.elementModel = this.elementModel;
     }
   }
 
+  private registerFormGroup() {
+    this.elementForm = this.formBuilder.group({});
+    this.formService.registerFormGroup({
+      formGroup: this.elementForm,
+      parentForm: this.parentForm,
+      parentArray: 'elements'
+    });
+  }
+
   ngOnDestroy(): void {
     this.ngUnsubscribe.next();
     this.ngUnsubscribe.complete();
diff --git a/projects/player/src/app/components/form.component.ts b/projects/player/src/app/components/form.component.ts
index fa972b3fa..6e2823d73 100644
--- a/projects/player/src/app/components/form.component.ts
+++ b/projects/player/src/app/components/form.component.ts
@@ -84,7 +84,7 @@ export class FormComponent implements OnDestroy {
 
   private addGroup = (group: ChildFormGroup): void => {
     const formArray: FormArray = group.parentForm.get(group.parentArray) as FormArray;
-    formArray.push(new FormGroup({ [group.id]: group.formGroup }));
+    formArray.push(group.formGroup);
   };
 
   private onElementValueChanges = (value: ValueChangeElement): void => {
@@ -96,11 +96,9 @@ export class FormComponent implements OnDestroy {
     // eslint-disable-next-line no-console
     console.log('player: onFormChanges', formValues);
     const unitState: UnitState = {
-      dataParts: formValues.pages
-        .reduce((obj, page): Record<string, string> => {
-          obj[Object.keys(page)[0]] = JSON.stringify(page[Object.keys(page)[0]]);
-          return obj;
-        }, {})
+      dataParts: {
+        pages: JSON.stringify(formValues.pages)
+      }
     };
     this.veronaPostService.sendVopStateChangedNotification({ unitState });
   }
diff --git a/projects/player/src/app/components/page.component.ts b/projects/player/src/app/components/page.component.ts
index aeeb420fb..f29014b5b 100644
--- a/projects/player/src/app/components/page.component.ts
+++ b/projects/player/src/app/components/page.component.ts
@@ -8,8 +8,7 @@ import { FormService } from '../../../../common/form.service';
 @Component({
   selector: 'app-page',
   template: `
-      <app-section *ngFor="let section of page.sections; let i = index"
-                   [id]="'section'+i"
+      <app-section *ngFor="let section of page.sections"
                    [parentForm]="pageForm"
                    [section]="section"
                    [ngStyle]="{
@@ -32,10 +31,10 @@ export class PageComponent implements OnInit {
 
   ngOnInit(): void {
     this.pageForm = this.formBuilder.group({
+      id: this.page.id,
       sections: this.formBuilder.array([])
     });
     this.formService.registerFormGroup({
-      id: this.page.id,
       formGroup: this.pageForm,
       parentForm: this.parentForm,
       parentArray: 'pages'
diff --git a/projects/player/src/app/components/section.component.ts b/projects/player/src/app/components/section.component.ts
index 02e3d74dc..ae7879810 100644
--- a/projects/player/src/app/components/section.component.ts
+++ b/projects/player/src/app/components/section.component.ts
@@ -1,7 +1,7 @@
 import {
   Component, Input, OnInit
 } from '@angular/core';
-import { FormGroup } from '@angular/forms';
+import { FormBuilder, FormGroup } from '@angular/forms';
 import { UnitPageSection } from '../../../../common/unit';
 import { FormService } from '../../../../common/form.service';
 
@@ -17,16 +17,16 @@ import { FormService } from '../../../../common/form.service';
 })
 export class SectionComponent implements OnInit {
   @Input() parentForm!: FormGroup;
-  @Input() id!: string;
   @Input() section!: UnitPageSection;
   @Input() sectionForm!: FormGroup;
 
-  constructor(private formService: FormService) {}
+  constructor(private formService: FormService, private formBuilder: FormBuilder) {}
 
   ngOnInit(): void {
-    this.sectionForm = new FormGroup({});
+    this.sectionForm = new FormGroup({
+      elements: this.formBuilder.array([])
+    });
     this.formService.registerFormGroup({
-      id: this.id,
       formGroup: this.sectionForm,
       parentForm: this.parentForm,
       parentArray: 'sections'
-- 
GitLab