From 1d85e96d3afbcbcaa8c33667fd96011523ee0bf4 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <p.jentsch@uni-bielefeld.de>
Date: Thu, 23 Feb 2023 15:18:53 +0100
Subject: [PATCH] Let the Corpus owner change Roles of followers

---
 app/models.py                                 | 39 ++++++++++++++-----
 .../js/ResourceLists/CorpusFollowerList.js    |  7 ++--
 app/static/js/Utils.js                        | 27 ++-----------
 3 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/app/models.py b/app/models.py
index 2444589c..01e7c09a 100644
--- a/app/models.py
+++ b/app/models.py
@@ -37,6 +37,16 @@ class CorpusStatus(IntEnum):
     RUNNING_ANALYSIS_SESSION = 8
     CANCELING_ANALYSIS_SESSION = 9
 
+    @staticmethod
+    def get(corpus_status: Union['CorpusStatus', int, str]) -> 'CorpusStatus':
+        if isinstance(corpus_status, CorpusStatus):
+            return corpus_status
+        if isinstance(corpus_status, int):
+            return CorpusStatus(corpus_status)
+        if isinstance(corpus_status, str):
+            return CorpusStatus[corpus_status]
+        raise TypeError('corpus_status must be CorpusStatus, int, or str')
+
 
 class JobStatus(IntEnum):
     INITIALIZING = 1
@@ -48,6 +58,16 @@ class JobStatus(IntEnum):
     COMPLETED = 7
     FAILED = 8
 
+    @staticmethod
+    def get(job_status: Union['JobStatus', int, str]) -> 'JobStatus':
+        if isinstance(job_status, JobStatus):
+            return job_status
+        if isinstance(job_status, int):
+            return JobStatus(job_status)
+        if isinstance(job_status, str):
+            return JobStatus[job_status]
+        raise TypeError('job_status must be JobStatus, int, or str')
+
 
 class Permission(IntEnum):
     '''
@@ -68,6 +88,7 @@ class Permission(IntEnum):
             return Permission[permission]
         raise TypeError('permission must be Permission, int, or str')
 
+
 class UserSettingJobStatusMailNotificationLevel(IntEnum):
     NONE = 1
     END = 2
@@ -90,14 +111,14 @@ class CorpusFollowerPermission(IntEnum):
     UPDATE_FOLLOWER = 64
 
     @staticmethod
-    def get(permission: Union['CorpusFollowerPermission', int, str]) -> 'CorpusFollowerPermission':
-        if isinstance(permission, CorpusFollowerPermission):
-            return permission
-        if isinstance(permission, int):
-            return CorpusFollowerPermission(permission)
-        if isinstance(permission, str):
-            return CorpusFollowerPermission[permission]
-        raise TypeError('permission must be CorpusFollowerPermission, int, or str')
+    def get(corpus_follower_permission: Union['CorpusFollowerPermission', int, str]) -> 'CorpusFollowerPermission':
+        if isinstance(corpus_follower_permission, CorpusFollowerPermission):
+            return corpus_follower_permission
+        if isinstance(corpus_follower_permission, int):
+            return CorpusFollowerPermission(corpus_follower_permission)
+        if isinstance(corpus_follower_permission, str):
+            return CorpusFollowerPermission[corpus_follower_permission]
+        raise TypeError('corpus_follower_permission must be CorpusFollowerPermission, int, or str')
 # endregion enums
 
 
@@ -555,7 +576,7 @@ class User(HashidMixin, UserMixin, db.Model):
         cascade='all, delete-orphan',
         lazy='dynamic'
     )
-    
+
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
         if self.role is not None:
diff --git a/app/static/js/ResourceLists/CorpusFollowerList.js b/app/static/js/ResourceLists/CorpusFollowerList.js
index cc94c568..b0b621d2 100644
--- a/app/static/js/ResourceLists/CorpusFollowerList.js
+++ b/app/static/js/ResourceLists/CorpusFollowerList.js
@@ -41,9 +41,9 @@ class CorpusFollowerList extends ResourceList {
           <td>
             <div class="input-field disable-on-click list-action-trigger" data-list-action="update-role">
               <select>
-                <option value="Viewer" ${values['role.name'] === 'Viewer' ? 'selected' : ''}>Viewer</option>
-                <option value="Contributor" ${values['role.name'] === 'Contributor' ? 'selected' : ''}>Contributor</option>
-                <option value="Administrator" ${values['role.name'] === 'Administrator' ? 'selected' : ''}>Administrator</option>
+                <option value="Viewer" ${values['role-name'] === 'Viewer' ? 'selected' : ''}>Viewer</option>
+                <option value="Contributor" ${values['role-name'] === 'Contributor' ? 'selected' : ''}>Contributor</option>
+                <option value="Administrator" ${values['role-name'] === 'Administrator' ? 'selected' : ''}>Administrator</option>
               </select>
             </div>
           </td>
@@ -176,6 +176,7 @@ class CorpusFollowerList extends ResourceList {
         case 'replace': {
           let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/corpus_follower_associations/([A-Za-z0-9]*)/role$`);
           if (re.test(operation.path)) {
+            console.log('role updated');
             let [match, jobId, valueName] = operation.path.match(re);
             this.replace(jobId, valueName, operation.value);
           }
diff --git a/app/static/js/Utils.js b/app/static/js/Utils.js
index 354f0f63..f8dbf2d0 100644
--- a/app/static/js/Utils.js
+++ b/app/static/js/Utils.js
@@ -69,13 +69,13 @@ class Utils {
     return Utils.mergeObjectsDeep(mergedObject, ...objects.slice(2));
   }
 
-  static addCorpusFollowerPermissionRequest(corpusId, followerId, permission) {
+  static updateCorpusFollowerRole(corpusId, followerId, roleName) {
     return new Promise((resolve, reject) => {
-      fetch(`/corpora/${corpusId}/followers/${followerId}/permissions/${permission}/add`, {method: 'POST', headers: {Accept: 'application/json'}})
+      fetch(`/corpora/${corpusId}/followers/${followerId}/role`, {method: 'POST', headers: {Accept: 'application/json', 'Content-Type': 'application/json'}, body: JSON.stringify({role: roleName})})
         .then(
           (response) => {
             if (response.ok) {
-              app.flash(`Permission added`, 'corpus');
+              app.flash('Role updated', 'corpus');
               resolve(response);
               return;
             } else {
@@ -91,27 +91,6 @@ class Utils {
     });
   }
 
-  static removeCorpusFollowerPermissionRequest(corpusId, followerId, permission) {
-    return new Promise((resolve, reject) => {
-      fetch(`/corpora/${corpusId}/followers/${followerId}/permissions/${permission}/remove`, {method: 'POST', headers: {Accept: 'application/json'}})
-        .then(
-          (response) => {
-            if (response.ok) {
-              app.flash(`Permission removed`, 'corpus');
-              resolve(response);
-            } else {
-              app.flash(`${response.statusText}`, 'error');
-              reject(response);
-            }
-          },
-          (response) => {
-            app.flash('Something went wrong', 'error');
-            reject(response);
-          }
-        );
-    }); 
-  }
-
   static enableCorpusIsPublicRequest(userId, corpusId) {
     return new Promise((resolve, reject) => {
       let corpus;
-- 
GitLab