From b022f52ae75d87d687ae34fc8eeeba52be7da481 Mon Sep 17 00:00:00 2001
From: Farbod Zamani <zamani@elan-ev.de>
Date: Wed, 4 Jan 2023 11:21:47 +0000
Subject: [PATCH] CW - More accurate unordered blocks checker

Closes #1852

Merge request studip/studip!1282
---
 .../CoursewareAccordionContainer.vue          | 18 +++++++++++------
 .../courseware/CoursewareTabsContainer.vue    | 20 ++++++++++++-------
 resources/vue/mixins/courseware/container.js  |  7 +++++++
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/resources/vue/components/courseware/CoursewareAccordionContainer.vue b/resources/vue/components/courseware/CoursewareAccordionContainer.vue
index 7d9f7626232..8b2c9880638 100755
--- a/resources/vue/components/courseware/CoursewareAccordionContainer.vue
+++ b/resources/vue/components/courseware/CoursewareAccordionContainer.vue
@@ -164,11 +164,15 @@ export default {
 
             const unallocated = new Set(this.blocks.map(({ id }) => id));
 
-            sections.forEach(section => {
+            for (let section of sections) {
                 section.locked = false;
                 section.blocks = section.blocks.map((id) =>  view.blockById({id})).filter(Boolean);
-                section.blocks.forEach(({ id }) => unallocated.delete(id));
-            });
+                for (let sectionBlock of section.blocks) {
+                    if (sectionBlock?.id && unallocated.has(sectionBlock.id)) {
+                        unallocated.delete(sectionBlock.id);
+                    }
+                }
+            }
 
             if (unallocated.size > 0) {
                 this.unallocatedBlocks = [...unallocated].map((id) => view.blockById({ id }));
@@ -247,9 +251,11 @@ export default {
         }
     },
     watch: {
-        blocks() {
-            if (!this.showEdit) {
-                this.initCurrentData();
+        blocks(newBlocks, oldBlocks) {
+            if (!this.showEdit && !this.checkSimpleArrayEquality(newBlocks, oldBlocks)) {
+                this.$nextTick(() => {
+                    setTimeout(() =>  this.initCurrentData(), 250);
+                });
             }
         }
     }
diff --git a/resources/vue/components/courseware/CoursewareTabsContainer.vue b/resources/vue/components/courseware/CoursewareTabsContainer.vue
index 15b3c87b574..de1d858f182 100755
--- a/resources/vue/components/courseware/CoursewareTabsContainer.vue
+++ b/resources/vue/components/courseware/CoursewareTabsContainer.vue
@@ -181,11 +181,15 @@ export default {
 
             const unallocated = new Set(this.blocks.map(({ id }) => id));
 
-            sections.forEach(section => {
+            for (let section of sections) {
                 section.locked = false;
-                section.blocks = section.blocks.map((id) =>  view.blockById({id})).filter((a) => a);
-                section.blocks.forEach(({ id }) => unallocated.delete(id));
-            });
+                section.blocks = section.blocks.map((id) =>  view.blockById({id})).filter(Boolean);
+                for (let sectionBlock of section.blocks) {
+                    if (sectionBlock?.id && unallocated.has(sectionBlock.id)) {
+                        unallocated.delete(sectionBlock.id);
+                    }
+                }
+            }
 
             if (unallocated.size > 0) {
                 this.unallocatedBlocks = [...unallocated].map((id) => view.blockById({ id }));
@@ -265,9 +269,11 @@ export default {
         }
     },
     watch: {
-        blocks() {
-            if (!this.showEdit) {
-                this.initCurrentData();
+        blocks(newBlocks, oldBlocks) {
+            if (!this.showEdit && !this.checkSimpleArrayEquality(newBlocks, oldBlocks)) {
+                this.$nextTick(() => {
+                    setTimeout(() =>  this.initCurrentData(), 250);
+                });
             }
         }
     }
diff --git a/resources/vue/mixins/courseware/container.js b/resources/vue/mixins/courseware/container.js
index fac1ea604ef..075137514ad 100755
--- a/resources/vue/mixins/courseware/container.js
+++ b/resources/vue/mixins/courseware/container.js
@@ -7,6 +7,13 @@ const containerMixin = {
     created: function () {
         this.pluginManager.registerComponentsLocally(this);
     },
+    methods: {
+        checkSimpleArrayEquality(firstSet, secondSet) {
+            return Array.isArray(firstSet) && Array.isArray(secondSet) &&
+                firstSet.length === secondSet.length &&
+                firstSet.every((val, index) => val === secondSet[index]);
+        }
+    }
 };
 
 export default containerMixin;
-- 
GitLab