From 9eb2b7fb05332e1b4d911d1f2fdfce2bce89666a Mon Sep 17 00:00:00 2001
From: dcz <dcz@ipipan.waw.pl>
Date: Thu, 14 Jul 2022 16:18:48 +0200
Subject: [PATCH] App name change. Superleksykograf can delete unified frame.
 Superleksykograf can create new unified frame. Minor UIX corrections. Unified
 frame has also assigment to user. Schema tab is default in edit view.

---
 common/templates/base.html                    |  4 +-
 entries/static/entries/css/entries.css        |  6 ++
 .../js/components/LexicalUnitDisplay.js       |  6 +-
 .../entries/js/components/LexicalUnitEdit.js  | 83 ++++++++++++-------
 .../js/components/UnificationRightPane.js     |  2 +-
 entries/views.py                              |  1 +
 unifier/models.py                             |  4 +
 unifier/views.py                              | 17 ++--
 8 files changed, 77 insertions(+), 46 deletions(-)

diff --git a/common/templates/base.html b/common/templates/base.html
index c36d1fa..79b5451 100644
--- a/common/templates/base.html
+++ b/common/templates/base.html
@@ -9,7 +9,7 @@
 <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <title>{% block title %}{% endblock %} – Shell Unifier [BETA]</title>
+    <title>{% block title %}{% endblock %} – Val Unifier [BETA]</title>
     <link rel="icon" href="{% static 'common/favicon.ico' %}">
     <link rel="stylesheet" type="text/css" href="https://bootswatch.com/4/lux/bootstrap.min.css">
     <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@300;400;700&display=swap">
@@ -43,7 +43,7 @@
     
     <!--z-index 2 above sticky-top-->
     <nav id="page-nav" class="navbar navbar-expand-lg sticky-top navbar-dark bg-dark font-weight-bold p-2" style="z-index: 1022;">
-        <a class="navbar-brand" href="{% url 'dash' %}">Shell Unifier [BETA]</a>
+        <a class="navbar-brand" href="{% url 'dash' %}">Val Unifier [BETA]</a>
 
         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
             <span class="navbar-toggler-icon"></span>
diff --git a/entries/static/entries/css/entries.css b/entries/static/entries/css/entries.css
index 58732e3..94d3042 100644
--- a/entries/static/entries/css/entries.css
+++ b/entries/static/entries/css/entries.css
@@ -255,3 +255,9 @@ legend {
 .tr-hover {
     background-color: rgba(0,0,0,.075) !important;
 }
+
+.ok-checkbox {
+    width: 80px;
+    accent-color: green;
+    pointer-events: none;
+}
diff --git a/entries/static/entries/js/components/LexicalUnitDisplay.js b/entries/static/entries/js/components/LexicalUnitDisplay.js
index 498d6ad..99b3fcb 100644
--- a/entries/static/entries/js/components/LexicalUnitDisplay.js
+++ b/entries/static/entries/js/components/LexicalUnitDisplay.js
@@ -100,10 +100,10 @@ export default {
       this.statusChange('frame_reject_as_not_matching_unified_frame');
     },
     isReadyToProcess () {
-      return (!this.isLeksykograf() && this.unifiedFrame?.status === 'G') || (this.isLeksykograf() && this.frame?.status === 'O');
+      return (!this.isLeksykograf() && this.unifiedFrame?.status === 'G') || (this.frame?.status === 'O' && this.unifiedFrame.assignee_username === window.USER_USERNAME);
     },
     isReadyToGet () {
-      return this.isLeksykograf() && this.frame?.status === 'N';
+      return this.frame?.status === 'N';
     },
     isLeksykograf () {
       return !has_permission("users.view_assignment");
@@ -186,7 +186,7 @@ export default {
                   v-if="isReadyToProcess()"
                   @click="goToEdit(this.unifiedFrame.pk, this.entryId, this.lexicalUnitId)"
                 >
-                  {{ isLeksykograf() ? gettext('Obrabiaj') : gettext('Sprawdź') }}
+                  {{ this.frame?.status === 'O' ? gettext('Obrabiaj') : gettext('Sprawdź') }}
                 </a>
                 <a
                   class="btn btn-sm btn-outline-dark mr-2"
diff --git a/entries/static/entries/js/components/LexicalUnitEdit.js b/entries/static/entries/js/components/LexicalUnitEdit.js
index e66b6d9..2556cbb 100644
--- a/entries/static/entries/js/components/LexicalUnitEdit.js
+++ b/entries/static/entries/js/components/LexicalUnitEdit.js
@@ -31,7 +31,7 @@ const FramePreview = {
   mounted () {
     Split(['#frame-preview-left-pane', '#frame-preview-right-pane'], {
       sizes: [60, 40],
-      minSize: 10,
+      minSize: 20,
       gutterSize: 4,
       elementStyle: (dimension, size, gutterSize) => {
         return {
@@ -862,10 +862,14 @@ Object.assign(LexicalUnitEdit, {
       });
     },
     isReadOnlyForSuperLeksykograf () {
-      return this.isSuperLeksykograf() && this.unified_frame.status === 'O';
+      return (this.isSuperLeksykograf() && this.unified_frame.status === 'O') && this.unified_frame.assignee_username !== window.USER_USERNAME;
     },
     hideFrame (frame) {
       this.hidden_frames.push(frame);
+    },
+    getSlowalReadyFrameCnt () {
+      const readyFrames = this.frames.filter(frame => frame.status == 'G');
+      return readyFrames.length;
     }
   },
   mounted() {
@@ -909,7 +913,7 @@ Object.assign(LexicalUnitEdit, {
             <td id="change-title" @click="changeTitle" style="padding: 10px 15px 10px 15px; color: #000000;">Zmień nazwę</td>
             <td id="add-arg" @click="addArgument" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj argum.</td>
             <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="addSelectivePreference">Dodaj prefer.</td>
-            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeUnifiedFrameStatusToReady">Gotowe</td>
+            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeUnifiedFrameStatusToReady">{{isSuperLeksykograf() ? 'Sprawdzone' : 'Gotowe'}}</td>
             <td id="duplicates" @click="duplicate" style="padding: 10px 15px 10px 15px; color: #000000;">Duplikuj</td>
           </tr>
           <tr style="background-color: white;">
@@ -917,9 +921,16 @@ Object.assign(LexicalUnitEdit, {
             <td id="remove-arg" @click="removeArgument" style="padding: 10px 15px 10px 15px; color: #000000;">Usuń argum.</td>
             <td id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="removeSelectionalPreference">Usuń prefer.</td>
             <td id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="swapUnifiedFrames">Zamień okna</td>
-            <td v-if="frames.length == 0" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">Usuń</td>
+            <td v-if="frames.length == 0 || isSuperLeksykograf()" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">Usuń ramę</td>
+          </tr>
+        </table>
+        
+        <table v-if="!readOnly && isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" style="width: 100px;" cellspacing="1">
+          <tr style="background-color: white;">
+            <td v-if="frames.length == 0 || isSuperLeksykograf()" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">Usuń ramę</td>
           </tr>
         </table>
+        
         <spinner />
         <div align="center">
         <div align="left" style="display: table;">
@@ -958,7 +969,7 @@ Object.assign(LexicalUnitEdit, {
             </tr>
             <tr>
               <th scope="row" class="py-0 px-1 text-secondary role-header">Selectional preferences</th>
-              <td class="preferences py-0 px-0 border-top border-left border-secondary role-column"
+              <td class="preferences py-0 px-0 border-top border-left border-secondary role-column align-top"
                   v-for='argument in unified_frame_arguments'
                   :key='argument.id'
               >
@@ -1015,7 +1026,7 @@ Object.assign(LexicalUnitEdit, {
         <table v-if="!readOnly && unified_frame.id && !isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" cellspacing="1">
           <tr style="background-color: white;">
             <td id="wrong-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="change_slowal_frame_status('B')">Błędna</td>
-            <td id="hide-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;"  @click="changeShowVerifiedFrames(false)">Ukryj gotowe</td>
+            <td id="hide-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;"  @click="changeShowVerifiedFrames(false)">Ukryj gotowe {{showVerifiedFrames ? '' : getSlowalReadyFrameCnt() > 0 ? '(ukrytych: ' + getSlowalReadyFrameCnt() + ')' : ''}}</td>
             <td id="ready-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="slowal_frame_ready_rollback">{{ statusButtonTitle }}</td>
             <td id="filter-slowal-frames" style="padding: 10px 15px 10px 15px; color: #000000;">Filtruj</td>
           </tr>
@@ -1041,15 +1052,22 @@ Object.assign(LexicalUnitEdit, {
                     <tbody>
                     <tr>
                       <td>
-                        <div class="row">
-                          <div class="col close" style="
-                              cursor: pointer;
+                        <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="row">
+                          <div class="col" style="
                               display: flex;
                               justify-content: flex-end;"
-                              @click="hideFrame(frame)"
-                          >&times;</div>
+                          >
+                             <div class="close" style="
+                                width: 15px;
+                                cursor: pointer;
+                                text-align: end;"
+                                @click="hideFrame(frame)"
+                                title="Ukryj ramÄ™"
+                            >&times;</div>
+                          </div>
+                          <div class="col" style="max-width: 40px;"></div>
                         </div>
-                      <div class="row">
+                      <div class="row" style="flex-wrap: nowrap;">
                         <div
                           class="col"
                           @mouseenter="frame.hover=true"
@@ -1061,26 +1079,31 @@ Object.assign(LexicalUnitEdit, {
                             :frame="frame" :key="frame"
                             @frame-selection-changed="insideFrameSelectionChanged"
                          />
-                     </div>
+                         </div>
+                         <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="col pl-0 pt-4" style="max-width: 60px;">
+                            <div class="row">
+                                <div class="col">
+                               <button v-if="!isFrameVerified(frame)"
+                                class="btn btn-sm btn-dark px-2 py-0" role="button" 
+                                style="font-size: 20px; min-width: 35px"
+                                @click="change_slowal2unified_frame_argument_mapping(frame)"
+                                title="Zamień wybrane argumenty ramy"
+                                >Z</button>
+                                </div>
+                            </div>
+                            <div class="row">
+                              <div v-if="isFrameVerified(frame)" class="col pt-2" style="display: flex;">
+                                  <input
+                                    type="checkbox"
+                                    :checked="isFrameVerified(frame)"
+                                    class="custom-control custom-checkbox ok-checkbox"
+                                  >
+                              </div>
+                            </div>
+                          </div>
+                     
                     </div>
                   </td>
-                    <th scope="row">
-                      <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()">
-                        <div v-if="isFrameVerified(frame)">
-                          <input
-                            type="checkbox"
-                            :checked="isFrameVerified(frame)"
-                            class="custom-control custom-checkbox"
-                            disabled="disabled"
-                          >
-                        </div>
-                        <br><br>
-                        <button v-if="!isFrameVerified(frame)"
-                          class="btn btn-sm btn-dark" role="button" 
-                          @click="change_slowal2unified_frame_argument_mapping(frame)"
-                          >Z</button>
-                      </div>
-                    </th>
                 </tr>
                 </tbody>
               </table>
diff --git a/entries/static/entries/js/components/UnificationRightPane.js b/entries/static/entries/js/components/UnificationRightPane.js
index 5cb116a..9f99ede 100644
--- a/entries/static/entries/js/components/UnificationRightPane.js
+++ b/entries/static/entries/js/components/UnificationRightPane.js
@@ -68,7 +68,7 @@ export default {
         :readOnly="false"
         :unifiedFrameId="unifiedFrameId"
         :previewedUnifiedFrameId="previewedUnifiedFrameId"
-        :initialRightPaneTab="unifiedFrameId !== previewedUnifiedFrameId ? 'frame_preview' : null"
+        :initialRightPaneTab="previewedUnifiedFrameId && unifiedFrameId !== previewedUnifiedFrameId ? 'frame_preview' : 'schemata'"
         @go-to-display="goToDisplay"
         @swap-frames="swapFrames"
         @refresh-entries-list="refreshEntriesList"
diff --git a/entries/views.py b/entries/views.py
index 2a2d2f5..947632a 100644
--- a/entries/views.py
+++ b/entries/views.py
@@ -872,6 +872,7 @@ def get_entry(request):
                 unified_frame = {
                     'pk': unified_frame.pk,
                     'status': unified_frame.status,
+                    'assignee_username' : assignment.user.username if (assignment := unified_frame.assignments.first()) else None,
                 }
             # https://docs.djangoproject.com/en/2.2/topics/http/sessions/#when-sessions-are-saved
             if [entry.name, entry.id] in request.session['last_visited']:
diff --git a/unifier/models.py b/unifier/models.py
index 2fd744c..e31db9f 100644
--- a/unifier/models.py
+++ b/unifier/models.py
@@ -1,4 +1,6 @@
 from copy import deepcopy
+
+from django.contrib.contenttypes.fields import GenericRelation
 from typing import List, Optional
 
 from django.db import models, transaction
@@ -23,6 +25,8 @@ class UnifiedFrame(models.Model):
     )
     title = models.CharField(max_length=200, default=None, blank=True, null=True)
 
+    assignments = GenericRelation("users.Assignment", content_type_field="subject_ct", object_id_field="subject_id")
+
     objects = models.Manager.from_queryset(UnifiedFrameQueryset)()
 
     def sorted_arguments(self):  # TODO: zaimplementowac wlasciwe sortowanie
diff --git a/unifier/views.py b/unifier/views.py
index c7f3090..036dc00 100644
--- a/unifier/views.py
+++ b/unifier/views.py
@@ -79,18 +79,9 @@ def get_unified_frames(request):
                 'id': str(unifiedFrame.id),
                 'title': unifiedFrame.title,
                 'status': unifiedFrame.status,
-                'assignee_username': None,
+                'assignee_username': assignment.user.username if (assignment := unifiedFrame.assignments.first()) else None,
             }
 
-        unifiedFrame2SlowalFrameMappings = UnifiedFrame2SlowalFrameMapping.objects.all();
-
-        for mapping in unifiedFrame2SlowalFrameMappings:
-            unifiedFrame = res[mapping.unified_frame.id]
-            title = unifiedFrame['title'] if unifiedFrame['title'] is not None else '['+mapping.slowal_frame.lexical_units.first().base+']'
-            unifiedFrame['title'] = title
-            if unifiedFrame['assignee_username'] is None:
-                unifiedFrame['assignee_username'] = assignment.user.username if (assignment := mapping.slowal_frame.assignments.first()) else None
-
         resProcessed = []
         for key, value in res.items():
             if (exclude_status == None or value['status'] != exclude_status) and \
@@ -114,6 +105,7 @@ def unifiedFrame2dict(frame):
         'id'            : frame.id,
         'title'            : frame.title,
         'status'            : str(frame.status),
+        'assignee_username' : assignment.user.username if (assignment := frame.assignments.first()) else None,
         'arguments'     : [
             {
                 'str'         : str(a),
@@ -488,6 +480,8 @@ def frame_assign(request):
         unifiedFrame.title = unified_frame_title
         unifiedFrame.save()
 
+        Assignment.assign(user=request.user, subject=unifiedFrame)
+
         slowal_frames = [connection.slowal_frame for connection in unifiedFrame.unified_frame_2_slowal_frame.all()]
 
         for slowal_frame in slowal_frames:
@@ -506,6 +500,9 @@ def removeUnifiedFrameMappingsAndAssigments(unified_frame_id):
     #odpianie z ramy zunifikowanej
     unifiedFrame2SlowalFrameMappings = UnifiedFrame2SlowalFrameMapping.objects.filter(unified_frame_id=unified_frame_id)
     for unifiedFrame2SlowalFrameMapping in unifiedFrame2SlowalFrameMappings:
+        unifiedFrame2SlowalFrameMapping.slowal_frame.status = 'N'
+        unifiedFrame2SlowalFrameMapping.slowal_frame.save()
+        Assignment.delete(subject_id=unifiedFrame2SlowalFrameMapping.slowal_frame.id)
         unifiedFrameArgumentSlowalFrameMappings = UnifiedFrameArgumentSlowalFrameMapping.objects.filter(unified_frame_mapping=unifiedFrame2SlowalFrameMapping)
         unifiedFrameArgumentSlowalFrameMappings.delete()
         unifiedFrame2SlowalFrameMapping.delete()
-- 
GitLab