From b07addc5c3f86d16ed776c77d3a78c3c2ea7924f Mon Sep 17 00:00:00 2001
From: Inga Kirschnick <inga.kirschnick@uni-bielefeld.de>
Date: Fri, 5 May 2023 08:41:14 +0200
Subject: [PATCH] (Public-)Corpus List fix+highligting owner status

---
 app/corpora/routes.py                         |  3 ++-
 app/main/routes.py                            | 11 +++-----
 app/static/js/ResourceLists/CorpusList.js     | 19 ++++++-------
 .../js/ResourceLists/FollowedCorpusList.js    | 14 ----------
 .../js/ResourceLists/PublicCorpusList.js      |  1 +
 app/templates/corpora/corpus.html.j2          | 27 +++++++------------
 app/templates/main/dashboard.html.j2          | 20 +++++++++++++-
 app/templates/main/social_area.html.j2        |  2 +-
 app/templates/users/user.html.j2              | 12 ++++++---
 9 files changed, 51 insertions(+), 58 deletions(-)
 delete mode 100644 app/static/js/ResourceLists/FollowedCorpusList.js

diff --git a/app/corpora/routes.py b/app/corpora/routes.py
index 8ef108b4..a81734f8 100644
--- a/app/corpora/routes.py
+++ b/app/corpora/routes.py
@@ -51,7 +51,8 @@ def create_corpus():
 def corpus(corpus_id):
     corpus = Corpus.query.get_or_404(corpus_id)
     cfrs = CorpusFollowerRole.query.all()
-    users = User.query.filter(User.is_public == True, User.id != current_user.id).all()
+    # TODO: Better solution for filtering admin
+    users = User.query.filter(User.is_public == True, User.id != current_user.id, User.id != corpus.user.id, User.role_id < 4).all()
     cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first()
     if cfa is None:
         if corpus.user == current_user or current_user.is_administrator():
diff --git a/app/main/routes.py b/app/main/routes.py
index cda06da6..708262db 100644
--- a/app/main/routes.py
+++ b/app/main/routes.py
@@ -3,6 +3,7 @@ from flask_breadcrumbs import register_breadcrumb
 from flask_login import current_user, login_required, login_user
 from app.auth.forms import LoginForm
 from app.models import Corpus, User
+from sqlalchemy import or_
 from . import bp
 
 
@@ -38,8 +39,10 @@ def faq():
 @register_breadcrumb(bp, '.dashboard', '<i class="material-icons left">dashboard</i>Dashboard')
 @login_required
 def dashboard():
+    corpora = Corpus.query.filter(or_(Corpus.followers.any(id=current_user.id), Corpus.user == current_user)).all()
     return render_template(
         'main/dashboard.html.j2',
+        corpora=corpora,
         title='Dashboard'
     )
 
@@ -81,15 +84,7 @@ def terms_of_use():
 @register_breadcrumb(bp, '.social_area', '<i class="material-icons left">group</i>Social Area')
 @login_required
 def social_area():
-    # corpora = [
-    #     c.to_json_serializeable() for c
-    #     in Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
-    # ]
     corpora = Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
-    # users = [
-    #     u.to_json_serializeable(relationships=True, filter_by_privacy_settings=True,) for u
-    #     in User.query.filter(User.is_public == True, User.id != current_user.id).all()
-    # ]
     users = User.query.filter(User.is_public == True, User.id != current_user.id).all()
     return render_template(
         'main/social_area.html.j2',
diff --git a/app/static/js/ResourceLists/CorpusList.js b/app/static/js/ResourceLists/CorpusList.js
index a6207baf..bd92a206 100644
--- a/app/static/js/ResourceLists/CorpusList.js
+++ b/app/static/js/ResourceLists/CorpusList.js
@@ -16,15 +16,6 @@ class CorpusList extends ResourceList {
         if (this.isInitialized) {this.onPatch(patch);}
       });
     });
-    app.getUser(this.userId).then((user) => {
-      let followedCorpora = [];
-      for (let cfa of Object.values(user.corpus_follower_associations)) {
-        followedCorpora.push(cfa.corpus);
-      }
-      this.add(Object.values(user.corpora));
-      this.add(followedCorpora);
-      this.isInitialized = true;
-    });
   }
 
   // #region Mandatory getters and methods to implement
@@ -33,6 +24,7 @@ class CorpusList extends ResourceList {
       <tr class="list-item clickable hoverable">
         <td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
         <td><b class="title"></b><br><i class="description"></i></td>
+        <td><span class="owner"></span></td>
         <td><span class="status badge new corpus-status-color corpus-status-text" data-badge-caption=""></span></td>
         <td class="right-align">
           <a class="list-action-trigger btn-floating red waves-effect waves-light" data-list-action="delete-request"><i class="material-icons">delete</i></a>
@@ -48,7 +40,9 @@ class CorpusList extends ResourceList {
       {data: ['creation-date']},
       {name: 'status', attr: 'data-status'},
       'description',
-      'title'
+      'title',
+      'owner',
+      {data: ['is-owner']}
     ];
   }
 
@@ -68,6 +62,7 @@ class CorpusList extends ResourceList {
           <tr>
             <th></th>
             <th>Title and Description</th>
+            <th>Owner</th>
             <th>Status</th>
             <th></th>
           </tr>
@@ -84,7 +79,9 @@ class CorpusList extends ResourceList {
       'creation-date': corpus.creation_date,
       'description': corpus.description,
       'status': corpus.status,
-      'title': corpus.title
+      'title': corpus.title,
+      'owner': corpus.user.username,
+      'is-owner': corpus.user.id === currentUserId ? true : false
     };
   }
 
diff --git a/app/static/js/ResourceLists/FollowedCorpusList.js b/app/static/js/ResourceLists/FollowedCorpusList.js
deleted file mode 100644
index b48bfd76..00000000
--- a/app/static/js/ResourceLists/FollowedCorpusList.js
+++ /dev/null
@@ -1,14 +0,0 @@
-class FollowedCorpusList extends CorpusList {
-  get item() {
-    return `
-      <tr class="list-item clickable hoverable">
-        <td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
-        <td><b class="title"></b><br><i class="description"></i></td>
-        <td><span class="status badge new corpus-status-color corpus-status-text" data-badge-caption=""></span></td>
-        <td class="right-align">
-          <a class="list-action-trigger btn-floating service-color darken waves-effect waves-light" data-list-action="view" data-service="corpus-analysis"><i class="material-icons">send</i></a>
-        </td>
-      </tr>
-    `.trim();
-  }
-}
diff --git a/app/static/js/ResourceLists/PublicCorpusList.js b/app/static/js/ResourceLists/PublicCorpusList.js
index fdb2e9ed..c02d54f0 100644
--- a/app/static/js/ResourceLists/PublicCorpusList.js
+++ b/app/static/js/ResourceLists/PublicCorpusList.js
@@ -4,6 +4,7 @@ class PublicCorpusList extends CorpusList {
       <tr class="list-item clickable hoverable">
         <td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
         <td><b class="title"></b><br><i class="description"></i></td>
+        <td><span class="owner"></span></td>
         <td><span class="status badge new corpus-status-color corpus-status-text" data-badge-caption=""></span></td>
         <td class="right-align">
           <a class="list-action-trigger btn-floating service-color darken waves-effect waves-light" data-list-action="view" data-service="corpus-analysis"><i class="material-icons">send</i></a>
diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2
index 76ad584e..470274b5 100644
--- a/app/templates/corpora/corpus.html.j2
+++ b/app/templates/corpora/corpus.html.j2
@@ -110,8 +110,8 @@
               </table>
               <br>
               <p></p>
-              {% if not current_user.is_following_corpus(corpus) %}
-              <a class="waves-effect waves-light btn-small">Request Corpus</a>
+              {% if not current_user.is_following_corpus(corpus) and corpus.user.has_profile_privacy_setting('SHOW_EMAIL') %}
+              <a class="waves-effect waves-light btn-small" href="mailto:{{ corpus.user.email }}">Request Corpus</a>
               {% endif %}
               <a class="waves-effect waves-light btn-small" href="{{ url_for('users.user', user_id=corpus.user.id) }}">View profile</a>
             </div>
@@ -153,7 +153,7 @@
 {% block modals %}
 {{ super() }}
 
-{% if cfr.has_permission('MANAGE_FOLLOWERS') %}
+{% if current_user == corpus.user or current_user.is_administrator() %}
 <div class="modal" id="publishing-modal">
   <div class="modal-content">
     <h4>Change your Corpus publishing status</h4>
@@ -172,9 +172,7 @@
     <a class="modal-close waves-effect waves-green btn-flat">Close</a>
   </div>
 </div>
-{% endif %}
 
-{% if current_user == corpus.user or current_user.is_administrator() %}
 <div class="modal" id="delete-modal">
   <div class="modal-content">
     <h4>Confirm Corpus deletion</h4>
@@ -221,9 +219,9 @@
       You can set different roles via the link, you can also edit them later in the menu below. 
       It is recommended not to set the expiration date of the link too far.
     </p>
-    <h5>Please make sure that the invited users are legally allowed to view the included corpus files.</h5>
+    <p><b>Please make sure that the invited users are legally allowed to view the included corpus files.</b></p>
     <div class="row">
-      <div class="col s12 l3">
+      <div class="col s12 l2">
         <div class="input-field">
           <i class="material-icons prefix">badge</i>
           <select id="share-link-modal-corpus-follower-role-select">
@@ -241,12 +239,12 @@
           <label for="expiration-date">Expiration date</label>
         </div>
       </div>
-      <div class="col s12 l3">
+      <div class="col s12 l2">
         <br class="hide-on-med-and-down">
         <a class="btn waves-effect waves-light" id="share-link-modal-create-button">Create<i class="material-icons right">send</i></a>
       </div>
 
-      <div class="col s12 l6">
+      <div class="col s12 l5">
         <div class="row hide" id="share-link-modal-output-container">
           <div class="col s9">
             <div class="input-field">
@@ -275,13 +273,6 @@
 let corpusDisplay = new CorpusDisplay(document.querySelector('#corpus-display'));
 
 {% if current_user.is_following_corpus(corpus) %}
-  {% if cfr.has_permission('MANAGE_FILES') %}
-  let buildButton = document.querySelector('#build-button');
-  buildButton.addEventListener('click', () => {
-    Requests.corpora.entity.build({{ corpus.hashid|tojson }})
-  });
-  {% endif %}
-
   let unfollowRequestElement = document.querySelector('.action-button[data-action="unfollow-request"]');
   unfollowRequestElement.addEventListener('click', () => {
     Requests.corpora.entity.followers.entity.delete({{ corpus.hashid|tojson }}, {{ current_user.hashid|tojson }})
@@ -321,8 +312,8 @@ let inviteUserModalSearchElement = document.querySelector('#invite-user-modal-se
 let inviteUserModalInviteButtonElement = document.querySelector('#invite-user-modal-invite-button');
 let users = {
   {% for user in users %}
-  {{ user.username|tojson }}: {{ url_for('users.user_avatar', user_id=user.id)|tojson }}
-  {% if not loop.last %},{% endif %}
+    {{ user.username|tojson }}: {{ url_for('users.user_avatar', user_id=user.id)|tojson }}
+    {% if not loop.last %},{% endif %}
   {% endfor %}
 };
 
diff --git a/app/templates/main/dashboard.html.j2 b/app/templates/main/dashboard.html.j2
index 54f91eaa..5dd980fe 100644
--- a/app/templates/main/dashboard.html.j2
+++ b/app/templates/main/dashboard.html.j2
@@ -15,7 +15,7 @@
     <div class="col s12">
       <div class="card">
         <div class="card-content">
-          <div class="corpus-list" data-user-id="{{ current_user.hashid }}"></div>
+          <div class="corpus-list no-autoinit" data-user-id="{{ current_user.hashid }}"></div>
         </div>
         <div class="card-action right-align">
           <a class="btn disabled waves-effect waves-light" href="{{ url_for('corpora.import_corpus') }}">Import Corpus<i class="material-icons right">import_export</i></a>
@@ -135,3 +135,21 @@
   </div>
 </div>
 {% endblock modals %}
+
+{% block scripts %}
+{{ super() }}
+<script>
+  let corpusList = new CorpusList(document.querySelector('.corpus-list'));
+  corpusList.add(
+    [
+      {% for corpus in corpora %}
+      {{ corpus.to_json_serializeable(backrefs=True)|tojson }},
+      {% endfor %}
+    ]
+  );
+  corpusItems = document.querySelectorAll('[data-is-owner="false"]');
+  corpusItems.forEach((item) => {
+    item.classList.add('deep-purple', 'lighten-5');
+  });
+</script>
+{% endblock scripts %}
diff --git a/app/templates/main/social_area.html.j2 b/app/templates/main/social_area.html.j2
index bda0407e..ff57d371 100644
--- a/app/templates/main/social_area.html.j2
+++ b/app/templates/main/social_area.html.j2
@@ -74,7 +74,7 @@
   publicCorpusList.add(
     [
       {% for corpus in corpora %}
-      {{ corpus.to_json_serializeable()|tojson }},
+      {{ corpus.to_json_serializeable(backrefs=True)|tojson }},
       {% endfor %}
     ]
   );
diff --git a/app/templates/users/user.html.j2 b/app/templates/users/user.html.j2
index 25e1e442..bdd6ed75 100644
--- a/app/templates/users/user.html.j2
+++ b/app/templates/users/user.html.j2
@@ -122,19 +122,23 @@
 {% block scripts %}
 {{ super() }}
 <script>
-let followedCorpusList = new FollowedCorpusList(document.querySelector('.followed-corpus-list'));
+let followedCorpusList = new PublicCorpusList(document.querySelector('.followed-corpus-list'));
 followedCorpusList.add(
   [
     {% for corpus in user.followed_corpora %}
-    {{ corpus.to_json_serializeable()|tojson }},
+      {% if (corpus.is_public or corpus.user == current_user) %}
+      {{ corpus.to_json_serializeable(backrefs=True)|tojson }},
+      {% endif %}
     {% endfor %}
   ]
 );
 let publicCorpusList = new PublicCorpusList(document.querySelector('.public-corpus-list'));
 publicCorpusList.add(
   [
-    {% for corpus in user.corpora if corpus.is_public %}
-    {{ corpus.to_json_serializeable()|tojson }},
+    {% for corpus in user.corpora %}
+      {% if corpus.is_public %}
+      {{ corpus.to_json_serializeable(backrefs=True)|tojson }},
+      {% endif %}
     {% endfor %}
   ]
 );
-- 
GitLab