From 46b412166d4f8525464932a59e207a09f310a838 Mon Sep 17 00:00:00 2001
From: Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>
Date: Fri, 15 Jul 2022 10:32:35 +0000
Subject: [PATCH] Fixes #1130.

Closes #1130

Merge request studip/studip!821
---
 .../courseware/CoursewareFolderChooser.vue    | 103 ++++++++++--------
 1 file changed, 57 insertions(+), 46 deletions(-)

diff --git a/resources/vue/components/courseware/CoursewareFolderChooser.vue b/resources/vue/components/courseware/CoursewareFolderChooser.vue
index 7e7463c5c12..339d644f68e 100644
--- a/resources/vue/components/courseware/CoursewareFolderChooser.vue
+++ b/resources/vue/components/courseware/CoursewareFolderChooser.vue
@@ -17,6 +17,56 @@
 <script>
 import { mapActions, mapGetters } from 'vuex';
 
+function filterCourseFolders(folders, { allowHomeworkFolders }) {
+    const validatedParents = new Map();
+
+    return folders.filter((folder) => {
+        if (validateParentFolder(folder)) {
+            switch (folder.attributes['folder-type']) {
+                case 'HiddenFolder':
+                    if (folder.attributes['data-content']['download_allowed'] === 1) {
+                        return true;
+                    }
+                    break;
+                case 'HomeworkFolder':
+                    if (allowHomeworkFolders) {
+                        return true;
+                    }
+                    break;
+                default:
+                    return true;
+            }
+        }
+    });
+
+    function validateParentFolder(folder) {
+        let isValid = true;
+        if (folder?.relationships?.parent) {
+            let parentId = folder.relationships.parent.data.id;
+            if (validatedParents.has(parentId)) {
+                isValid = validatedParents.get(parentId);
+            } else {
+                let parent = folders.find((f) => f.id === parentId);
+                if (parent) {
+                    isValid = hiddenParentFolderValidation(parent);
+                    validatedParents.set(parentId, isValid);
+                }
+            }
+        }
+        return isValid;
+    }
+
+    function hiddenParentFolderValidation(parentFolder) {
+        if (parentFolder.attributes['folder-type'] === 'HiddenFolder') {
+            return false;
+        } else if (parentFolder?.relationships?.parent) {
+            // Recursively validating the parents.
+            return validateParentFolder(parentFolder);
+        } else {
+            return true;
+        }
+    }
+}
 export default {
     name: 'courseware-folder-chooser',
     props: {
@@ -45,32 +95,17 @@ export default {
             return { type: 'users', id: `${this.userId}` };
         },
         loadedCourseFolders() {
-            let loadedCourseFolders = [];
-            let CourseFolders = this.relatedFolders({ parent: this.courseObject, relationship: 'folders' }) ?? [];
-            CourseFolders.forEach(folder => {
-                if (this.validateParentFolder(folder)) {
-                    switch (folder.attributes['folder-type']) {
-                        case 'HiddenFolder':
-                            if (folder.attributes['data-content']['download_allowed'] === 1) {
-                                loadedCourseFolders.push(folder);
-                            }
-                            break;
-                        case 'HomeworkFolder':
-                            if(this.allowHomeworkFolders) {
-                                loadedCourseFolders.push(folder);
-                            }
-                            break;
-                        default:
-                            loadedCourseFolders.push(folder);
-                    }
+            return filterCourseFolders(
+                this.relatedFolders({ parent: this.courseObject, relationship: 'folders' }) ?? [],
+                {
+                    allowHomeworkFolders: this.allowHomeworkFolders,
                 }
-            });
-            return loadedCourseFolders;
+            );
         },
         loadedUserFolders() {
             let loadedUserFolders = [];
             let UserFolders = this.relatedFolders({ parent: this.userObject, relationship: 'folders' }) ?? [];
-            UserFolders.forEach(folder => {
+            UserFolders.forEach((folder) => {
                 if (folder.attributes['folder-type'] === 'PublicFolder') {
                     loadedUserFolders.push(folder);
                 }
@@ -81,7 +116,7 @@ export default {
     },
     methods: {
         ...mapActions({
-            loadRelatedFolders: 'folders/loadRelated'
+            loadRelatedFolders: 'folders/loadRelated',
         }),
 
         changeSelection() {
@@ -103,30 +138,6 @@ export default {
 
             return this.loadRelatedFolders({ parent, relationship, options });
         },
-
-        validateParentFolder(folder) {
-            let courseFolders = this.relatedFolders({ parent: this.courseObject, relationship: 'folders' }) ?? [];
-            let validation = true;
-            if (courseFolders.length > 0 && folder?.relationships?.parent) {
-                let parentId = folder.relationships.parent.data.id;
-                let parent = courseFolders.find(f => f.id === parentId);
-                if (parent) {
-                    validation = this.hiddenParentFolderValidation(parent);
-                }
-            }
-            return validation;
-        },
-
-        hiddenParentFolderValidation(parentFolder) {
-            if (parentFolder.attributes['folder-type'] === 'HiddenFolder') {
-                return false;
-            } else if (parentFolder?.relationships?.parent) {
-                // Recursively validating the parents.
-                return this.validateParentFolder(parentFolder);
-            } else {
-                return true;
-            }
-        }
     },
     mounted() {
         this.currentValue = this.value;
-- 
GitLab