From 6dbd486b3af083ba94e9a5c82a2fe47a08869d6c Mon Sep 17 00:00:00 2001
From: Ron Lucke <lucke@elan-ev.de>
Date: Tue, 19 Oct 2021 10:25:36 +0000
Subject: [PATCH] Biest #320

---
 .../courseware/CoursewareActionWidget.vue     | 30 +++++++++++++++-
 .../courseware/CoursewareDefaultBlock.vue     | 21 +++++++++--
 .../courseware/CoursewareDefaultContainer.vue | 35 +++++++++++++++++--
 .../CoursewareStructuralElement.vue           | 30 +++++++++++++++-
 4 files changed, 109 insertions(+), 7 deletions(-)

diff --git a/resources/vue/components/courseware/CoursewareActionWidget.vue b/resources/vue/components/courseware/CoursewareActionWidget.vue
index f2a443631c9..ca1859c9ff2 100644
--- a/resources/vue/components/courseware/CoursewareActionWidget.vue
+++ b/resources/vue/components/courseware/CoursewareActionWidget.vue
@@ -36,6 +36,7 @@ export default {
         ...mapGetters({
             oerEnabled: 'oerEnabled',
             oerTitle: 'oerTitle',
+            userId: 'userId',
         }),
         isRoot() {
             if (!this.structuralElement) {
@@ -53,6 +54,18 @@ export default {
         currentId() {
             return this.structuralElement?.id;
         },
+        blocked() {
+            return this.structuralElement?.relationships['edit-blocker'].data !== null;
+        },
+        blockerId() {
+            return this.blocked ? this.structuralElement?.relationships['edit-blocker'].data?.id : null;
+        },
+        blockedByThisUser() {
+            return this.blocked && this.userId === this.blockerId;
+        },
+        blockedByAnotherUser() {
+            return this.blocked && this.userId !== this.blockerId;
+        },
     },
     methods: {
         ...mapActions({
@@ -67,7 +80,22 @@ export default {
             lockObject: 'lockObject',
         }),
         async editElement() {
-            await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+
+                return false;
+            }
+            try {
+                await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
+            } catch(error) {
+                if (error.status === 409) {
+                    this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+                } else {
+                    console.log(error);
+                }
+
+                return false;
+            }
             this.showElementEditDialog(true);
         },
         async deleteElement() {
diff --git a/resources/vue/components/courseware/CoursewareDefaultBlock.vue b/resources/vue/components/courseware/CoursewareDefaultBlock.vue
index 341168784dd..486d6219f34 100755
--- a/resources/vue/components/courseware/CoursewareDefaultBlock.vue
+++ b/resources/vue/components/courseware/CoursewareDefaultBlock.vue
@@ -150,10 +150,10 @@ export default {
             return this.blocked ? this.block?.relationships['edit-blocker'].data?.id : null;
         },
         blockedByThisUser() {
-            return this.userId === this.blockerId;
+            return this.blocked && this.userId === this.blockerId;
         },
         blockedByAnotherUser() {
-            return this.userId !== this.blockerId;
+            return this.blocked && this.userId !== this.blockerId;
         },
         blockTitle() {
             const type = this.block.attributes['block-type'];
@@ -181,6 +181,9 @@ export default {
             loadContainer: 'loadContainer',
         }),
         async displayFeature(element) {
+            if (this.showEdit && element === 'Edit') {
+                return false;
+            }
             this.showFeatures = false;
             this.showFeedback = false;
             this.showComments = false;
@@ -190,8 +193,20 @@ export default {
             this.showContent = true;
             if (element) {
                 if (element === 'Edit') {
+                    await this.loadContainer(this.block.relationships.container.data.id);
                     if (!this.blocked) {
-                        await this.lockObject({ id: this.block.id, type: 'courseware-blocks' });
+                        try {
+                            await this.lockObject({ id: this.block.id, type: 'courseware-blocks' });
+                        } catch(error) {
+                            if (error.status === 403) {
+                                this.companionInfo({ info: this.$gettext('Dieser Block wird bereits bearbeitet.') });
+                            } else {
+                                console.log(error);
+                            }
+
+                            return false;
+                        }
+
                         if (!this.preview) {
                             this.showContent = false;
                         }
diff --git a/resources/vue/components/courseware/CoursewareDefaultContainer.vue b/resources/vue/components/courseware/CoursewareDefaultContainer.vue
index a1d41c3e355..53acc421c2c 100755
--- a/resources/vue/components/courseware/CoursewareDefaultContainer.vue
+++ b/resources/vue/components/courseware/CoursewareDefaultContainer.vue
@@ -50,7 +50,7 @@
 <script>
 import CoursewareContainerActions from './CoursewareContainerActions.vue';
 import StudipDialog from '../StudipDialog.vue';
-import { mapActions } from 'vuex';
+import { mapGetters, mapActions } from 'vuex';
 
 export default {
     name: 'courseware-default-container',
@@ -76,12 +76,27 @@ export default {
         };
     },
     computed: {
+        ...mapGetters({
+            userId: 'userId',
+        }),
         showEditMode() {
             return this.$store.getters.viewMode === 'edit';
         },
         colSpan() {
             return this.container.attributes.payload.colspan ? this.container.attributes.payload.colspan : 'full';
         },
+        blocked() {
+            return this.container?.relationships['edit-blocker'].data !== null;
+        },
+        blockerId() {
+            return this.blocked ? this.container?.relationships['edit-blocker'].data?.id : null;
+        },
+        blockedByThisUser() {
+            return this.blocked && this.userId === this.blockerId;
+        },
+        blockedByAnotherUser() {
+            return this.blocked && this.userId !== this.blockerId;
+        },
     },
     methods: {
         ...mapActions({
@@ -90,7 +105,23 @@ export default {
             unlockObject: 'unlockObject',
         }),
         async displayEditDialog() {
-            await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
+            if (this.blockedByAnotherUser) {
+                this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
+
+                return false;
+            }
+            try {
+                await this.lockObject({ id: this.container.id, type: 'courseware-containers' });
+            } catch(error) {
+                if (error.status === 409) {
+                    this.companionInfo({ info: this.$gettext('Dieser Abschnitt wird bereits bearbeitet.') });
+                } else {
+                    console.log(error);
+                }
+
+                return false;
+            }
+
             this.showEditDialog = true;
         },
         async closeEdit() {
diff --git a/resources/vue/components/courseware/CoursewareStructuralElement.vue b/resources/vue/components/courseware/CoursewareStructuralElement.vue
index 564bff692c2..d52358a001c 100755
--- a/resources/vue/components/courseware/CoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/CoursewareStructuralElement.vue
@@ -555,6 +555,7 @@ export default {
             licenses: 'licenses',
             exportState: 'exportState',
             exportProgress: 'exportProgress',
+            userId: 'userId',
         }),
 
         currentId() {
@@ -907,6 +908,18 @@ export default {
 
             return '';
         },
+        blocked() {
+            return this.structuralElement?.relationships['edit-blocker'].data !== null;
+        },
+        blockerId() {
+            return this.blocked ? this.structuralElement?.relationships['edit-blocker'].data?.id : null;
+        },
+        blockedByThisUser() {
+            return this.blocked && this.userId === this.blockerId;
+        },
+        blockedByAnotherUser() {
+            return this.blocked && this.userId !== this.blockerId;
+        },
     },
 
     methods: {
@@ -936,7 +949,22 @@ export default {
         async menuAction(action) {
             switch (action) {
                 case 'editCurrentElement':
-                    await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
+                    if (this.blockedByAnotherUser) {
+                        this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+
+                        return false;
+                    }
+                    try {
+                        await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
+                    } catch(error) {
+                        if (error.status === 409) {
+                            this.companionInfo({ info: this.$gettext('Diese Seite wird bereits bearbeitet.') });
+                        } else {
+                            console.log(error);
+                        }
+
+                        return false;
+                    }
                     this.showElementEditDialog(true);
                     break;
                 case 'addElement':
-- 
GitLab