From 36f238ed6a8bf55e996d57ce0f53f7f0520c7188 Mon Sep 17 00:00:00 2001
From: dcz <dcz@ipipan.waw.pl>
Date: Thu, 30 Jun 2022 20:06:32 +0200
Subject: [PATCH] Reset db is adding 2 additional users
 Leksykografowie,Superleksykograf Correct switchable list (view only user
 LU/Frames, expect Admin/SuperLeksykograf)

---
 .../UnificationEntriesForFramesList.js        | 30 +++++++
 .../js/components/UnificationFramesList.js    |  5 +-
 .../components/UnificationSwitchableList.js   |  6 +-
 .../js/unification_entries_for_frames_list.js | 82 +++++++++++++++++++
 .../entries/js/unification_frames_list.js     |  6 +-
 entries/templates/unification.html            |  1 +
 entries/views.py                              | 22 ++++-
 reset_db.sh                                   |  3 +
 unifier/views.py                              |  6 +-
 9 files changed, 152 insertions(+), 9 deletions(-)
 create mode 100644 entries/static/entries/js/components/UnificationEntriesForFramesList.js
 create mode 100644 entries/static/entries/js/unification_entries_for_frames_list.js

diff --git a/entries/static/entries/js/components/UnificationEntriesForFramesList.js b/entries/static/entries/js/components/UnificationEntriesForFramesList.js
new file mode 100644
index 0000000..af93507
--- /dev/null
+++ b/entries/static/entries/js/components/UnificationEntriesForFramesList.js
@@ -0,0 +1,30 @@
+export default {
+  data () {
+    return {
+      gettext: window.gettext,
+      canViewAssignment: has_permission("users.view_assignment")
+    }
+  },
+  emits: ['unifiedFrameSelected'],
+  mounted () {
+    setup_entries_for_frames_list({
+      table: this.$refs.table,
+      lexicalUnitSelected: (lexicalUnitUnifiedFrameId) => { this.$emit('unifiedFrameSelected', lexicalUnitUnifiedFrameId); }
+    });
+  },
+  template: `
+    <table ref="table" class="table table-sm table-hover text-dark">
+      <thead>
+        <tr>
+          <th class="p-1">{{ gettext('Lemat') }}</th>
+          <th class="p-1">{{ gettext('Część mowy') }}</th>
+          <th class="p-1">{{ gettext('Do pobrania') }}</th>
+          <th v-if="canViewAssignment" class="p-1">{{ gettext('Semantyk') }}</th>
+          <th v-else class="p-1">{{ gettext('Moje (w opracowaniu)') }}</th>
+        </tr>
+      </thead>
+      <tbody id="entries">
+      </tbody>
+    </table>
+  `
+};
diff --git a/entries/static/entries/js/components/UnificationFramesList.js b/entries/static/entries/js/components/UnificationFramesList.js
index 0ed0502..693e30c 100644
--- a/entries/static/entries/js/components/UnificationFramesList.js
+++ b/entries/static/entries/js/components/UnificationFramesList.js
@@ -2,7 +2,7 @@ export default {
   data () {
     return {
       gettext: window.gettext,
-      canViewUser: has_permission("users.view_user")
+      canViewAssignment: has_permission("users.view_assignment")
     }
   },
   emits: ['unifiedFrameSelected'],
@@ -18,8 +18,7 @@ export default {
         <tr>
           <th class="p-1">{{ gettext('Rama') }}</th>
           <th class="p-1">{{ gettext('Status') }}</th>
-          <th v-if="canViewUser" class="p-1">{{ gettext('Leksykograf') }}</th>
-          <th v-else class="p-1">{{ gettext('Moje (w opracowaniu)') }}</th>
+          <th v-if="canViewAssignment" class="p-1">{{ gettext('Leksykograf') }}</th>
           <th class="p-1" hidden="true">{{ gettext('Id') }}</th>
         </tr>
       </thead>
diff --git a/entries/static/entries/js/components/UnificationSwitchableList.js b/entries/static/entries/js/components/UnificationSwitchableList.js
index d5601ad..1d58ffb 100644
--- a/entries/static/entries/js/components/UnificationSwitchableList.js
+++ b/entries/static/entries/js/components/UnificationSwitchableList.js
@@ -1,3 +1,4 @@
+import UnificationEntriesForFramesList from "./UnificationEntriesForFramesList.js";
 import UnificationEntriesList from "./UnificationEntriesList.js";
 import UnificationFramesList from "./UnificationFramesList.js";
 
@@ -17,10 +18,11 @@ export default {
       this.$emit('unifiedFrameSelected', unifiedFrameId);
     }
   },
-  components: {UnificationEntriesList, UnificationFramesList},
+  components: {UnificationEntriesList, UnificationEntriesForFramesList, UnificationFramesList},
   template: `
     <label class="float-left mt-2"><input type="checkbox" v-model="isFrameView" /> {{ gettext('RAMY') }}</label>
-    <div v-if="!isFrameView"><unification-entries-list @lexical-unit-selected="lexicalUnitSelected" /></div>
+<!--    <div v-if="!isFrameView"><unification-entries-list @lexical-unit-selected="lexicalUnitSelected" /></div>-->
+    <div v-if="!isFrameView"><unification-entries-for-frames-list @unified-frame-selected="unifiedFrameSelected" /></div>
     <div v-else><unification-frames-list @unified-frame-selected="unifiedFrameSelected" /></div>
   `
 };
diff --git a/entries/static/entries/js/unification_entries_for_frames_list.js b/entries/static/entries/js/unification_entries_for_frames_list.js
new file mode 100644
index 0000000..f1a1649
--- /dev/null
+++ b/entries/static/entries/js/unification_entries_for_frames_list.js
@@ -0,0 +1,82 @@
+function setup_entries_for_frames_list(options) {
+    const can_see_assignees = has_permission("users.view_assignment");
+
+    function is_assigned_to_user_renderer (data) {
+        return (
+            data
+            && data.lexical_units
+            && data.lexical_units.some(lu => lu.assignee_username === window.USER_USERNAME && lu.status == 'O')
+        ) ? gettext("tak") : gettext("nie");
+    }
+
+    const ajaxURL = can_see_assignees ? '/' + window.lang + '/entries/get_entries/?with_lexical_units=true' : '/' + window.lang + '/entries/get_entries/?with_lexical_units=true&exclude_status=N&restrict_to_user='+window.USER_USERNAME;
+
+    var datatable = setup_datatable({
+        element: options.table,
+        selectFirst: true,
+        url: ajaxURL,
+        columns: [
+            { data: 'lemma' },
+            { data: 'POS' },
+            { render: data => (data && data.lexical_units && data.lexical_units.some(lu => lu.assignee_username !== null)) ? gettext("nie") : gettext("tak") },
+            can_see_assignees ? { data: 'assignee_username' } : { render: is_assigned_to_user_renderer },
+        ],
+        hidden_columns: can_see_assignees ? [2] : [2,3]
+    });
+    datatable.on('click', 'tr.entry', function () {
+        var row = datatable.row(this);
+        var has_drilldown = row.child.isShown();
+        $('.drilldown:visible', options.table).each(function () { datatable.row($(this).data("row")).child.hide(); });
+        if (!has_drilldown) {
+            if (!row.data()) return;
+            var drilldown = $("<div>").addClass("drilldown").data("row", this);
+            row.child(drilldown).show();
+            setup_lexical_units_for_frames_table(drilldown, row.data().lexical_units, can_see_assignees, options);
+            drilldown.closest("td").addClass("p-0 pl-4");
+        }
+    });
+}
+
+function setup_lexical_units_for_frames_table(drilldown, lexical_units, can_see_assignees, options) {
+    if (!lexical_units.length) {
+        return '';
+    }
+
+    function get_lexical_unit_row(lexical_unit) {
+        const is_assigned_to_user = lexical_unit.assignee_username === window.USER_USERNAME;
+        return $(`
+            <tr class="lexical-unit">
+                <td class="p-1">${lexical_unit.display}</td>
+                <td class="p-1">${lexical_unit.status}</td>
+                ` + (
+                    can_see_assignees
+                        ? `<td class="p-1">${lexical_unit.assignee_username || ""}</td>`
+                        : ``
+                ) + `
+            </tr>
+        `).click(function () {
+            $(this).addClass('table-primary').siblings().removeClass("table-primary");
+            options.lexicalUnitSelected(lexical_unit.unified_frame_id);
+        });
+    }
+    var table = $(`
+        <table class="table">
+            <thead>
+                <tr>
+                    <th class="p-1">${gettext("Jednostka Leksykalna")}</th>
+                    <th class="p-1">${gettext("Status")}</th>
+                    ` + (
+                        can_see_assignees
+                            ? `<th class="p-1">${gettext("Leksykograf")}</th>`
+                            : ``
+                    ) + `
+                </tr>
+            </thead>
+            <tbody></tbody>
+        </table>
+    `);
+    drilldown.append(table);
+    lexical_units.map(function (lexical_unit) {
+        $("tbody", table).append(get_lexical_unit_row(lexical_unit));
+    });
+}
diff --git a/entries/static/entries/js/unification_frames_list.js b/entries/static/entries/js/unification_frames_list.js
index 8a31ff6..3efb6c6 100644
--- a/entries/static/entries/js/unification_frames_list.js
+++ b/entries/static/entries/js/unification_frames_list.js
@@ -8,16 +8,18 @@ function setup_frames_list(options) {
         ) ? gettext("tak") : gettext("nie");
     }
 
+    const ajaxURL = can_see_assignees ? '/' + lang + '/unifier/get_unified_frames/' : '/' + lang + '/unifier/get_unified_frames/?exclude_status=N&restrict_to_user='+window.USER_USERNAME;
+
     var datatable = setup_datatable({
         element: options.table,
-        url: '/' + lang + '/unifier/get_unified_frames/',
+        url: ajaxURL,
         columns: [
             { data: 'title' },
             { data: 'status' },
             can_see_assignees ? { data: 'assignee_username' } : { render: is_assigned_to_user_renderer },
             { data: 'id' },
         ],
-        hidden_columns: [3]
+        hidden_columns: can_see_assignees ? [3] : [2,3]
     });
     datatable.on('click', 'tr.entry', function () {
         var data = datatable.row(this).data();
diff --git a/entries/templates/unification.html b/entries/templates/unification.html
index b8d024e..2a73f0a 100644
--- a/entries/templates/unification.html
+++ b/entries/templates/unification.html
@@ -10,6 +10,7 @@
     <link rel="stylesheet" type="text/css" href="{% static 'entries/css/unification_frames.css' %}">
     <script src="{% static 'entries/js/unification_entries_list.js' %}"></script>
     <script src="{% static 'entries/js/unification_frames_list.js' %}"></script>
+    <script src="{% static 'entries/js/unification_entries_for_frames_list.js' %}"></script>
     <script src="{% static 'entries/js/unification.js' %}"></script>
     <script src="{% static 'entries/js/selectional_preference.js' %}"></script>
     <script src="{% static 'entries/js/jquery-impromptu.min.js' %}"></script>
diff --git a/entries/views.py b/entries/views.py
index 5495459..e506a5e 100644
--- a/entries/views.py
+++ b/entries/views.py
@@ -354,6 +354,8 @@ def get_entries(request):
         assert(not errors_dict)
         scroller_params = get_scroller_params(request.POST)
         with_lexical_units = request.GET.get('with_lexical_units') == 'true'
+        exclude_status = request.GET.get('exclude_status')
+        restrict_to_user = request.GET.get('restrict_to_user')
         entries = get_filtered_objects(forms).filter(import_error=False)
         
         # TODO restrictions for testing – remove!!!
@@ -387,6 +389,7 @@ def get_entries(request):
             entries = entries.prefetch_related("lexical_units")
         status_names = STATUS()
         POS_names = POS()
+        entriesList = list(entries)
         result = {
             'draw' : scroller_params['draw'],
             'recordsTotal': total,
@@ -409,14 +412,31 @@ def get_entries(request):
                                         assignment.user.username if (frame := lu.frames.first()) and (assignment := frame.assignments.first()) else None
                                     ),
                                     'status': frame.status if (frame := lu.frames.first()) else "",
+                                    'unified_frame_id': frame.slowal_frame_2_unified_frame.unified_frame_id if (frame := lu.frames.first()) and hasattr(frame, 'slowal_frame_2_unified_frame') else -1,
                                 } for lu in e.lexical_units.all()
                             ]
                         }
                         if with_lexical_units else {}
                     ),
-                } for e in list(entries)[first_index:last_index]
+                } for e in entriesList[first_index:last_index]
             ],
         }
+
+        if with_lexical_units:
+            filteredData = []
+            for entry in result['data']:
+                lexicalUnits = entry['lexical_units']
+                filteredLexicalUnits = []
+                for lexicalUnit in lexicalUnits:
+                    if (exclude_status == None or lexicalUnit['status'] != exclude_status) and \
+                            (restrict_to_user == None or lexicalUnit['assignee_username'] == restrict_to_user):
+                        filteredLexicalUnits.append(lexicalUnit)
+                entry['lexical_units'] = filteredLexicalUnits
+                if len(filteredLexicalUnits) > 0:
+                    filteredData.append(entry)
+
+            result['data'] = filteredData
+
         return JsonResponse(result)
     return JsonResponse({})
 
diff --git a/reset_db.sh b/reset_db.sh
index 74c1326..1e129cc 100755
--- a/reset_db.sh
+++ b/reset_db.sh
@@ -28,3 +28,6 @@ wc import.log
 
 # TODO dev only!!!
 python manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('shell', '', 'valier')"
+python manage.py shell -c "from django.contrib.auth.models import User; from django.contrib.auth.models import Group; user = User.objects.create_user('Leksykograf', '', 'valier111'); group = Group.objects.get(name='Leksykografowie'); user.groups.add(group); user.save();"
+python manage.py shell -c "from django.contrib.auth.models import User; from django.contrib.auth.models import Group; user = User.objects.create_user('Superleksykograf', '', 'valier111'); group = Group.objects.get(name='Super Leksykografowie'); user.groups.add(group); user.save();"
+
diff --git a/unifier/views.py b/unifier/views.py
index cae2193..6e7f95b 100644
--- a/unifier/views.py
+++ b/unifier/views.py
@@ -59,6 +59,8 @@ def save_relational_selectional_preference(request):
 def get_unified_frames(request):
     if request.method == 'POST':
         scroller_params = get_scroller_params(request.POST)
+        exclude_status = request.GET.get('exclude_status')
+        restrict_to_user = request.GET.get('restrict_to_user')
 
         res = {}
         unifiedFrames = UnifiedFrame.objects.all();
@@ -81,7 +83,9 @@ def get_unified_frames(request):
 
         resProcessed = []
         for key, value in res.items():
-            resProcessed.append(value)
+            if (exclude_status == None or value['status'] != exclude_status) and \
+                    (restrict_to_user == None or value['assignee_username'] == restrict_to_user):
+                resProcessed.append(value)
 
         ret = {
                 'draw' : scroller_params['draw'],
-- 
GitLab