From b2d8ef812f0c318e80ad7af966cc63a5bdeaddd1 Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Fri, 21 Jan 2022 14:48:56 +0100
Subject: [PATCH] [player] Fix restoring of drop lists

Change creation of the list of possible drop list values.
The values can be found at different hierarchy levels in the unit
definition, as they can be sub elements of cloze elements
---
 .../unit-state-element-mapper.service.ts      | 33 ++++++++++++++-----
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/projects/player/src/app/services/unit-state-element-mapper.service.ts b/projects/player/src/app/services/unit-state-element-mapper.service.ts
index 4f415a9e4..d255b81df 100644
--- a/projects/player/src/app/services/unit-state-element-mapper.service.ts
+++ b/projects/player/src/app/services/unit-state-element-mapper.service.ts
@@ -3,7 +3,6 @@ import { Unit } from '../../../../common/models/unit';
 import {
   DragNDropValueObject, InputElement, InputElementValue, UIElement
 } from '../../../../common/models/uI-element';
-import { Section } from '../../../../common/models/section';
 import { ImageElement } from '../../../../common/ui-elements/image/image-element';
 import { VideoElement } from '../../../../common/ui-elements/video/video-element';
 import { AudioElement } from '../../../../common/ui-elements/audio/audio-element';
@@ -18,16 +17,32 @@ export class UnitStateElementMapperService {
   dropListValueIds!: DragNDropValueObject[];
 
   registerDropListValueIds(unitDefinition: Unit): void {
-    this.dropListValueIds = unitDefinition.pages.reduce(
-      (accumulator: Section[], currentValue) => accumulator.concat(currentValue.sections), []
-    ).reduce(
-      (accumulator: UIElement[], currentValue) => accumulator.concat(currentValue.elements), []
-    ).filter(element => element.type === 'drop-list').reduce(
-      (accumulator: DragNDropValueObject[], currentValue: UIElement) => (
-        (currentValue.value && currentValue.value.length) ? accumulator.concat(currentValue.value) : accumulator), []
-    );
+    const dropListElements: UIElement[] = [];
+    this.findNestedDropLists(unitDefinition.pages, dropListElements);
+    this.dropListValueIds = dropListElements
+      .reduce(
+        (accumulator: DragNDropValueObject[], currentValue: UIElement) => (
+          (currentValue.value && currentValue.value.length) ? accumulator.concat(currentValue.value) : accumulator), []
+      );
   }
 
+  private findNestedDropLists(value: any | unknown[], dropListElements: UIElement[]): void {
+    if (this.isObject(value)) {
+      if (value.type === 'drop-list') {
+        dropListElements.push(value);
+      } else {
+        const keys = (Object.keys(value));
+        keys.forEach((key: string) => this.findNestedDropLists(value[key], dropListElements));
+      }
+    } else if (this.isArray(value)) {
+      value.forEach((element: unknown) => this.findNestedDropLists(element, dropListElements));
+    }
+  }
+
+  private isObject = (value: unknown) => !!(value && typeof value === 'object' && !Array.isArray(value));
+
+  private isArray = (value: unknown) => !!(value && typeof value === 'object' && Array.isArray(value));
+
   mapToElementValue(
     elementModel: UIElement,
     unitStateElement: UnitStateElementCode | undefined,
-- 
GitLab