From 4494de247d20caa7cd64da7e90be82283751e6b2 Mon Sep 17 00:00:00 2001 From: Ron Lucke Date: Tue, 5 Apr 2022 11:49:30 +0200 Subject: fix #832 for v5.0 --- lib/classes/JsonApi/Schemas/Course.php | 22 +++++ lib/models/Courseware/Instance.php | 40 +++++++- .../courseware/CoursewareManagerCopySelector.vue | 101 +++++++++++++++------ .../vue/store/courseware/courseware.module.js | 13 +-- 4 files changed, 134 insertions(+), 42 deletions(-) diff --git a/lib/classes/JsonApi/Schemas/Course.php b/lib/classes/JsonApi/Schemas/Course.php index 47692da..e5904ba 100644 --- a/lib/classes/JsonApi/Schemas/Course.php +++ b/lib/classes/JsonApi/Schemas/Course.php @@ -10,6 +10,7 @@ class Course extends SchemaProvider const TYPE = 'courses'; const REL_BLUBBER = 'blubber-threads'; + const REL_COURSEWARE = 'courseware'; const REL_END_SEMESTER = 'end-semester'; const REL_EVENTS = 'events'; const REL_FEEDBACK = 'feedback-elements'; @@ -71,6 +72,7 @@ class Course extends SchemaProvider $relationships = $this->getFilesRelationship($relationships, $course); $relationships = $this->getForumCategoriesRelationship($relationships, $course, $includeList); $relationships = $this->getBlubberRelationship($relationships, $course, $includeList); + $relationships = $this->getCoursewareRelationship($relationships, $course, $includeList); $relationships = $this->getEventsRelationship($relationships, $course, $includeList); $relationships = $this->getFeedbackRelationship($relationships, $course, $includeList); $relationships = $this->getMembershipsRelationship($relationships, $course, $includeList); @@ -189,6 +191,26 @@ class Course extends SchemaProvider /** * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ + private function getCoursewareRelationship( + array $relationships, + \Course $course, + $includeData + ) { + if (\Courseware\Instance::existsForRange($course)) { + $relationships[self::REL_COURSEWARE] = [ + self::DATA => \Courseware\Instance::findForRange($course), + self::LINKS => [ + Link::RELATED => $this->getRelationshipRelatedLink($course, self::REL_COURSEWARE), + ], + ]; + } + + return $relationships; + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ private function getEventsRelationship( array $relationships, \Course $course, diff --git a/lib/models/Courseware/Instance.php b/lib/models/Courseware/Instance.php index c823a4e..9776ed1 100755 --- a/lib/models/Courseware/Instance.php +++ b/lib/models/Courseware/Instance.php @@ -13,7 +13,32 @@ namespace Courseware; */ class Instance { - public static function deleteForRange(\Range $range): void + /** + * @param \Range $range + * @return ?static + */ + public static function existsForRange(\Range $range) + { + switch ($range->getRangeType()) { + case 'course': + case 'user': + $result = \DBManager::get()->fetchOne( + 'SELECT COUNT(*) as count FROM cw_structural_elements WHERE range_id = ? AND range_type = ? AND parent_id IS NULL', + [$range->getRangeId(), $range->getRangeType()] + ); + + return ((int) $result['count']) == 1; + + default: + throw new \InvalidArgumentException('Only ranges of type "user" and "course" are currently supported.'); + } + } + + /** + * @param \Range $range + * @return ?static + */ + public static function findForRange(\Range $range) { $root = null; switch ($range->getRangeType()) { @@ -29,10 +54,18 @@ class Instance // there is no courseware for this course if (!$root) { - return; + return null; } - $instance = new self($root); + return new self($root); + } + + public static function deleteForRange(\Range $range): void + { + $instance = self::findForRange($range); + if (!$instance) { + return; + } $range->getConfiguration()->delete('COURSEWARE_SEQUENTIAL_PROGRESSION'); $range->getConfiguration()->delete('COURSEWARE_EDITING_PERMISSION'); @@ -54,6 +87,7 @@ class Instance \UserConfig::get($config->range_id)->store('COURSEWARE_LAST_ELEMENT', $arr); } + $root = self::getRoot(); $root->delete(); } diff --git a/resources/vue/components/courseware/CoursewareManagerCopySelector.vue b/resources/vue/components/courseware/CoursewareManagerCopySelector.vue index 01c2c36..fe03957 100755 --- a/resources/vue/components/courseware/CoursewareManagerCopySelector.vue +++ b/resources/vue/components/courseware/CoursewareManagerCopySelector.vue @@ -7,26 +7,33 @@
-
+

Veranstaltungen

+
+
import CoursewareManagerElement from './CoursewareManagerElement.vue'; -import { mapActions, mapGetters } from 'vuex'; import CoursewareCompanionBox from './CoursewareCompanionBox.vue'; - +import StudipProgressIndicator from '../StudipProgressIndicator.vue'; +import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-manager-copy-selector', components:{ CoursewareManagerElement, CoursewareCompanionBox, + StudipProgressIndicator, }, props: {}, - data() {return{ - source: '', - courses: [], - remoteCid: '', - remoteCoursewareInstance: {}, - remoteId: '', - remoteElement: {}, - ownCoursewareInstance: {}, - ownId: '', - ownElement: {}, - semesterMap: [], - - }}, + data() { + return { + source: '', + courses: [], + remoteCid: '', + remoteCoursewareInstance: {}, + remoteId: '', + remoteElement: {}, + ownCoursewareInstance: {}, + ownId: '', + ownElement: {}, + semesterMap: [], + loadingRemoteCourses: false + } + }, computed: { ...mapGetters({ userId: 'userId', @@ -116,6 +131,7 @@ export default { loadUsersCourses: 'loadUsersCourses', loadStructuralElement: 'loadStructuralElement', loadSemester: 'semesters/loadById', + loadRemoteCoursewareStructure: 'loadRemoteCoursewareStructure' }), selectSource(source) { this.source = source; @@ -196,11 +212,36 @@ export default { }, reloadElement() { this.$emit("reloadElement"); - } + }, + async loadCoursewareInstances() { + this.loadingRemoteCourses = true; + let filteredCourses = []; + + for (let course of this.courses) { + + if (course.userPermission === 'dozent') { + filteredCourses.push(course); + continue; + } + + const coursewareInstance = await this.loadRemoteCoursewareStructure({ + rangeId: course.id, + rangeType: course.type + }); + + if (coursewareInstance.attributes['editing-permission-level'] === 'tutor') { + filteredCourses.push(course); + } + }; + + this.loadingRemoteCourses = false; + this.courses = filteredCourses; + }, }, async mounted() { this.courses = await this.loadUsersCourses({ userId: this.userId, withCourseware: true }); this.loadSemesterMap(); + this.loadCoursewareInstances(); } } diff --git a/resources/vue/store/courseware/courseware.module.js b/resources/vue/store/courseware/courseware.module.js index 94d5378..7a89d14 100755 --- a/resources/vue/store/courseware/courseware.module.js +++ b/resources/vue/store/courseware/courseware.module.js @@ -866,15 +866,10 @@ export const actions = { courses.push(course); continue; } - const coursewareInstance = await dispatch('loadRemoteCoursewareStructure', { - rangeId: course.id, - rangeType: course.type - }); - if (coursewareInstance?.relationships?.root) { - if (membership.attributes.permission === 'dozent' || - coursewareInstance.attributes['editing-permission-level'] === 'tutor') { - courses.push(course); - } + + if (course.relationships.courseware) { + course['userPermission'] = membership.attributes.permission; + courses.push(course); } } } -- cgit v1.0