From 749e42bed47442f1c37b11ff67a69c3f25be8ace Mon Sep 17 00:00:00 2001 From: Ron Lucke <lucke@elan-ev.de> Date: Mon, 15 Jul 2024 11:28:44 +0000 Subject: [PATCH] fix #889 Closes #889 Merge request studip/studip!3206 --- app/controllers/course/courseware.php | 10 ++- app/views/course/courseware/index.php | 1 + app/views/course/courseware/tasks.php | 1 + .../JsonApi/Schemas/Courseware/Instance.php | 3 +- .../components/courseware/ActivitiesApp.vue | 7 +- resources/vue/courseware-activities-app.js | 1 - resources/vue/courseware-index-app.js | 1 - resources/vue/courseware-shelf-app.js | 6 +- resources/vue/courseware-tasks-app.js | 7 +- .../courseware/courseware-shelf.module.js | 53 +---------- .../vue/store/courseware/courseware.module.js | 87 ++++--------------- 11 files changed, 41 insertions(+), 136 deletions(-) diff --git a/app/controllers/course/courseware.php b/app/controllers/course/courseware.php index f0b873a2014..8ecff0a9e30 100644 --- a/app/controllers/course/courseware.php +++ b/app/controllers/course/courseware.php @@ -46,6 +46,11 @@ class Course_CoursewareController extends CoursewareController public function index_action(): void { + $this->isTeacher = $GLOBALS['perm']->have_studip_perm( + 'tutor', + Context::getId(), + $GLOBALS['user']->id + ); Navigation::activateItem('course/courseware/shelf'); $this->setIndexSidebar(); } @@ -88,12 +93,11 @@ class Course_CoursewareController extends CoursewareController public function tasks_action($route = null): void { - $this->is_teacher = $GLOBALS['perm']->have_studip_perm( + $this->isTeacher = $GLOBALS['perm']->have_studip_perm( 'tutor', Context::getId(), $GLOBALS['user']->id ); - Navigation::activateItem('course/courseware/tasks'); PageLayout::setTitle(_('Courseware: Aufgaben')); $this->setTasksSidebar(); @@ -101,8 +105,6 @@ class Course_CoursewareController extends CoursewareController public function activities_action(): void { - global $perm, $user; - $this->is_teacher = $perm->have_studip_perm('tutor', Context::getId(), $user->id); Navigation::activateItem('course/courseware/activities'); $this->setActivitiesSidebar(); } diff --git a/app/views/course/courseware/index.php b/app/views/course/courseware/index.php index eea40635c42..0152c372855 100644 --- a/app/views/course/courseware/index.php +++ b/app/views/course/courseware/index.php @@ -4,4 +4,5 @@ entry-id="<?= Context::getId() ?>" licenses='<?= $licenses ?>' feedback-settings='<?= htmlReady($feedback_settings) ?>' + is-teacher='<?= var_export($isTeacher) ?>' ></div> diff --git a/app/views/course/courseware/tasks.php b/app/views/course/courseware/tasks.php index 7ebd70a4166..9f0e8542b30 100644 --- a/app/views/course/courseware/tasks.php +++ b/app/views/course/courseware/tasks.php @@ -2,5 +2,6 @@ id="courseware-tasks-app" entry-type="courses" entry-id="<?= htmlReady(Context::getId()) ?>" + is-teacher='<?= var_export($isTeacher) ?>' > </div> diff --git a/lib/classes/JsonApi/Schemas/Courseware/Instance.php b/lib/classes/JsonApi/Schemas/Courseware/Instance.php index 114467a61b4..a30fbae007c 100644 --- a/lib/classes/JsonApi/Schemas/Courseware/Instance.php +++ b/lib/classes/JsonApi/Schemas/Courseware/Instance.php @@ -45,7 +45,8 @@ class Instance extends SchemaProvider 'certificate-settings' => $resource->getCertificateSettings(), 'reminder-settings' => $resource->getReminderSettings(), 'reset-progress-settings' => $resource->getResetProgressSettings(), - 'root-id' => $resource->getRoot()->id + 'root-id' => $resource->getRoot()->id, + 'is-teacher' => $GLOBALS['perm']->have_studip_perm($resource->getEditingPermissionLevel(), $resource->getRoot()->range_id) ]; } diff --git a/resources/vue/components/courseware/ActivitiesApp.vue b/resources/vue/components/courseware/ActivitiesApp.vue index cfbce77b433..10c605655af 100644 --- a/resources/vue/components/courseware/ActivitiesApp.vue +++ b/resources/vue/components/courseware/ActivitiesApp.vue @@ -21,11 +21,6 @@ export default { CoursewareActivities, CoursewareActivitiesWidgetFilterType, CoursewareActivitiesWidgetFilterUnit - }, - computed: { - ...mapGetters({ - userIsTeacher: 'userIsTeacher', - }), - }, + } } </script> \ No newline at end of file diff --git a/resources/vue/courseware-activities-app.js b/resources/vue/courseware-activities-app.js index ee2eb849de2..3122238c5a4 100644 --- a/resources/vue/courseware-activities-app.js +++ b/resources/vue/courseware-activities-app.js @@ -77,7 +77,6 @@ const mountApp = async (STUDIP, createApp, element) => { id: entry_id, type: entry_type, }); - await store.dispatch('loadTeacherStatus', STUDIP.USER_ID); await store.dispatch('loadCourseUnits', entry_id); const app = createApp({ diff --git a/resources/vue/courseware-index-app.js b/resources/vue/courseware-index-app.js index 59c0ebca225..6be42295dba 100644 --- a/resources/vue/courseware-index-app.js +++ b/resources/vue/courseware-index-app.js @@ -154,7 +154,6 @@ const mountApp = async (STUDIP, createApp, element) => { }); if (entry_type === 'courses') { - await store.dispatch('loadTeacherStatus', STUDIP.USER_ID); store.dispatch('loadProgresses'); await store.dispatch('setFeedbackSettings', feedbackSettings); } diff --git a/resources/vue/courseware-shelf-app.js b/resources/vue/courseware-shelf-app.js index a0e7f98c65f..82ece71b0e4 100644 --- a/resources/vue/courseware-shelf-app.js +++ b/resources/vue/courseware-shelf-app.js @@ -31,6 +31,7 @@ const mountApp = async (STUDIP, createApp, element) => { let entry_type = null; let licenses = null; let feedbackSettings = null; + let isTeacher = false; if ((elem = document.getElementById(element.substring(1))) !== undefined) { if (elem.attributes !== undefined) { @@ -48,6 +49,9 @@ const mountApp = async (STUDIP, createApp, element) => { if (elem.attributes['feedback-settings'] !== undefined) { feedbackSettings = JSON.parse(elem.attributes['feedback-settings'].value); } + if (elem.attributes['is-teacher'] !== undefined) { + isTeacher = JSON.parse(elem.attributes['is-teacher'].value); + } } } @@ -96,7 +100,7 @@ const mountApp = async (STUDIP, createApp, element) => { type: entry_type, }); if (entry_type === 'courses') { - await store.dispatch('loadTeacherStatus', STUDIP.USER_ID); + store.dispatch('setUserIsTeacher', isTeacher); await store.dispatch('loadCourseUnits', entry_id); await store.dispatch('setFeedbackSettings', feedbackSettings); } else { diff --git a/resources/vue/courseware-tasks-app.js b/resources/vue/courseware-tasks-app.js index 9c01b7190f2..fc7bf655f3b 100644 --- a/resources/vue/courseware-tasks-app.js +++ b/resources/vue/courseware-tasks-app.js @@ -92,6 +92,7 @@ const mountApp = async (STUDIP, createApp, element) => { }); let entry_id = null; let entry_type = null; + let isTeacher = false; let elem; if ((elem = document.getElementById(element.substring(1))) !== undefined) { @@ -103,17 +104,21 @@ const mountApp = async (STUDIP, createApp, element) => { if (elem.attributes['entry-id'] !== undefined) { entry_id = elem.attributes['entry-id'].value; } + + if (elem.attributes['is-teacher'] !== undefined) { + isTeacher = JSON.parse(elem.attributes['is-teacher'].value); + } } } store.dispatch('setUserId', STUDIP.USER_ID); await store.dispatch('users/loadById', { id: STUDIP.USER_ID }); + store.dispatch('setUserIsTeacherInCourse', isTeacher); store.dispatch('setHttpClient', httpClient); store.dispatch('coursewareContext', { id: entry_id, type: entry_type, }); - await store.dispatch('loadTeacherStatus', STUDIP.USER_ID); await store.dispatch('tasks/loadTasksOfCourse', { cid: entry_id }); const app = createApp({ diff --git a/resources/vue/store/courseware/courseware-shelf.module.js b/resources/vue/store/courseware/courseware-shelf.module.js index d907ee421c4..e5ea54c4837 100644 --- a/resources/vue/store/courseware/courseware-shelf.module.js +++ b/resources/vue/store/courseware/courseware-shelf.module.js @@ -176,10 +176,12 @@ export const actions = { setUrlHelper(context, urlHelper) { context.commit('setUrlHelper', urlHelper); }, - setFeedbackSettings(context, feedbackSettings) { context.commit('setFeedbackSettings', feedbackSettings); }, + setUserIsTeacher(context, isTeacher) { + context.commit('setUserIsTeacher', isTeacher); + }, // other actions loadCourseUnits({ dispatch }, cid) { @@ -546,54 +548,6 @@ export const actions = { return dispatch('courseware-instances/update', instance, { root: true }); }, - async loadTeacherStatus({ dispatch, rootGetters, state, commit, getters }, userId) { - const user = rootGetters['users/byId']({ id: userId }); - - if (user.attributes.permission === 'root') { - commit('setUserIsTeacher', true); - return; - } - if (user.attributes.permission === 'admin') { - await dispatch('courses/loadById', { id: state.context.id }); - const course = rootGetters['courses/byId']({id: state.context.id }); - const instituteId = course.relationships.institute.data.id; - - const parent = { type: 'users', id: `${userId}` }; - const relationship = 'institute-memberships'; - const options = {}; - await dispatch('institute-memberships/loadRelated', { parent, relationship, options }, { root: true }); - const instituteMemberships = rootGetters['institute-memberships/all']; - const instituteMembership = instituteMemberships.filter(membership => membership.relationships.institute.data.id === instituteId); - - if (instituteMembership.length > 0 && instituteMembership[0].attributes.permission === 'admin') { - commit('setUserIsTeacher', true); - return; - } - } - - const membershipId = `${state.context.id}_${userId}`; - try { - await dispatch('course-memberships/loadById', { id: membershipId }); - } catch (error) { - console.error(`Could not find course membership for ${membershipId}.`); - commit('setUserIsTeacher', false); - - return false; - } - const membership = rootGetters['course-memberships/byId']({ id: membershipId }); - if (membership) { - const membershipPermission = membership.attributes.permission; - commit('setUserIsTeacher', membershipPermission === 'dozent' || membershipPermission === 'tutor'); - - return true; - } else { - console.error(`Could not find course membership for ${membershipId}.`); - commit('setUserIsTeacher', false); - - return false; - } - }, - uploadImageForStructuralElement({ dispatch, state }, { structuralElement, file }) { const formData = new FormData(); formData.append('image', file); @@ -789,7 +743,6 @@ export const mutations = { state.exportProgress = exportProgress; }, setUserIsTeacher(state, isTeacher) { - state.teacherStatusLoaded = true; state.userIsTeacher = isTeacher; }, setUrlHelper(state, urlHelper) { diff --git a/resources/vue/store/courseware/courseware.module.js b/resources/vue/store/courseware/courseware.module.js index 784b75090df..aeea3c07cba 100644 --- a/resources/vue/store/courseware/courseware.module.js +++ b/resources/vue/store/courseware/courseware.module.js @@ -22,9 +22,7 @@ const getDefaultState = () => { userId: null, viewMode: 'read', dashboardViewMode: 'default', - userIsTeacher: false, - teacherStatusLoaded: false, - + userIsTeacherInCourse: false, showStructuralElementEditDialog: false, showStructuralElementAddDialog: false, showStructuralElementAddChooserDialog: false, @@ -181,11 +179,15 @@ const getters = { userId(state) { return state.userId; }, - userIsTeacher(state) { - return state.userIsTeacher; + userIsTeacherInCourse(state) { + return state.userIsTeacherInCourse; }, - teacherStatusLoaded(state) { - return state.teacherStatusLoaded; + userIsTeacher(state, getters) { + if (getters.courseware.attributes === undefined) { + return getters.userIsTeacherInCourse; + } + + return getters.courseware.attributes['is-teacher']; }, pluginManager(state) { return state.pluginManager; @@ -1086,6 +1088,10 @@ export const actions = { commit('setAssistiveLiveContents', state); }, + setUserIsTeacherInCourse({ commit }, state) { + commit('setUserIsTeacherInCourse', state); + }, + addBookmark({ dispatch, rootGetters }, structuralElement) { const cw = rootGetters['courseware']; @@ -1290,65 +1296,6 @@ export const actions = { ); }, - async loadTeacherStatus({ dispatch, rootGetters, state, commit, getters }, userId) { - const user = rootGetters['users/byId']({ id: userId }); - - if (user.attributes.permission === 'root') { - commit('setUserIsTeacher', true); - return; - } - if (user.attributes.permission === 'admin') { - await dispatch('courses/loadById', { id: state.context.id }); - const course = rootGetters['courses/byId']({id: state.context.id }); - const instituteId = course.relationships.institute.data.id; - - const parent = { type: 'users', id: `${userId}` }; - const relationship = 'institute-memberships'; - const options = {}; - await dispatch('institute-memberships/loadRelated', { parent, relationship, options }, { root: true }); - const instituteMemberships = rootGetters['institute-memberships/all']; - const instituteMembership = instituteMemberships.filter(membership => membership.relationships.institute.data.id === instituteId); - - if (instituteMembership.length > 0 && instituteMembership[0].attributes.permission === 'admin') { - commit('setUserIsTeacher', true); - return; - } - } - - const membershipId = `${state.context.id}_${userId}`; - try { - await dispatch('course-memberships/loadById', { id: membershipId }); - } catch (error) { - console.error(`Could not find course membership for ${membershipId}.`); - commit('setUserIsTeacher', false); - - return false; - } - const membership = rootGetters['course-memberships/byId']({ id: membershipId }); - if (membership) { - let editingLevel = 'tutor'; - if (getters.courseware.attributes) { - editingLevel = getters.courseware.attributes['editing-permission-level']; - } - const membershipPermission = membership.attributes.permission; - - let isTeacher = false; - if (editingLevel === 'dozent') { - isTeacher = membershipPermission === 'dozent'; - } else if (editingLevel === 'tutor') { - isTeacher = membershipPermission === 'dozent' || membershipPermission === 'tutor'; - } - commit('setUserIsTeacher', isTeacher); - - return true; - } else { - console.error(`Could not find course membership for ${membershipId}.`); - commit('setUserIsTeacher', false); - - return false; - } - }, - loadFeedback({ dispatch }, blockId) { const parent = { type: 'courseware-blocks', id: `${blockId}` }; const relationship = 'feedback'; @@ -1622,11 +1569,6 @@ export const mutations = { state.userId = userId; }, - setUserIsTeacher(state, isTeacher) { - state.teacherStatusLoaded = true; - state.userIsTeacher = isTeacher; - }, - setPluginManager(state, pluginManager) { state.pluginManager = pluginManager; }, @@ -1748,6 +1690,9 @@ export const mutations = { setAssistiveLiveContents(state, text) { state.assistiveLiveContents = text; }, + setUserIsTeacherInCourse(state, isTeacher) { + state.userIsTeacherInCourse = isTeacher; + }, setProgresses(state, data) { state.progresses = data; }, -- GitLab