From 60cebbebed1f4d1a39789ba3a1b08847b2e20761 Mon Sep 17 00:00:00 2001
From: dcz <dcz@ipipan.waw.pl>
Date: Mon, 27 Jun 2022 21:42:48 +0200
Subject: [PATCH] Role selection popup

---
 entries/static/entries/css/entries.css        |   5 +
 .../entries/js/components/LexicalUnitEdit.js  | 205 +++++++++++++++---
 entries/static/entries/js/entries.js          |  27 +++
 entries/urls.py                               |   5 +-
 entries/views.py                              |  27 ++-
 unifier/urls.py                               |   2 +
 unifier/views.py                              |  46 +++-
 7 files changed, 277 insertions(+), 40 deletions(-)

diff --git a/entries/static/entries/css/entries.css b/entries/static/entries/css/entries.css
index 4a6d18c..e28fb44 100644
--- a/entries/static/entries/css/entries.css
+++ b/entries/static/entries/css/entries.css
@@ -209,3 +209,8 @@ legend {
 .dataTables_scrollHeadInner, .table {
     width:100% !important;
 }
+
+.role_select_header {
+    font-weight: bold;
+    font-size: 13px;
+}
diff --git a/entries/static/entries/js/components/LexicalUnitEdit.js b/entries/static/entries/js/components/LexicalUnitEdit.js
index c59daa6..3ff5ad3 100644
--- a/entries/static/entries/js/components/LexicalUnitEdit.js
+++ b/entries/static/entries/js/components/LexicalUnitEdit.js
@@ -62,8 +62,7 @@ export default {
             for (var i in curr_examples) {
               curr_examples_by_id[curr_examples[i].id] = curr_examples[i];
             }
-            // show_syntax(response.subentries);
-            // show_unified_frame(response.unified_frame, response.frames)
+            unified_frame_active_frame = this.unified_frame;
             show_unified_frame_lexical_units(response.frames)
             fulfill_slowal_frames_arguments_with_empty_elems(response.unified_frame, response.frames)
             show_semantics_unified_view(response.frames, response.subentries);
@@ -107,43 +106,173 @@ export default {
       }
     },
     changeTitle() {
-        let title = this.unified_frame.title != null ? this.unified_frame.title : '';
-        var change_title_popup = {
+      let title = this.unified_frame.title != null ? this.unified_frame.title : '';
+      var change_title_popup = {
+        state0: {
+          title: 'Zmiana nazwy ramy',
+          html: '<input type="text" size="32" value="' + title + '" name="title" />',
+          buttons: { Anuluj: 0, Zapisz: 1},
+          focus: -1,
+          submit: function(e,v,m,f){
+            if (v == 0) {
+              $.prompt.close();
+            }
+            if (v === 1) {
+              e.preventDefault();
+              var title = f.title;
+              var data = { 'unified_frame_id' : this.unified_frame.id, 'unified_frame_title' : title };
+              $.ajax({
+                type     : 'post',
+                url      : '/' + lang + '/unifier/save_unified_frame_title/',
+                dataType : 'json',
+                data     : data,
+                timeout  : 60000,
+                success  : function(response) {
+                  show_info('Tytuł ramy zosał zapisany');
+                  $.prompt.close();
+                  this.loadFrame();
+                }.bind(this),
+                error: function(request, errorType, errorMessage) {
+                  show_error(errorType + ' (' + errorMessage + ')');
+                  $.prompt.close();
+                }
+              });
+            }
+          }.bind(this)
+        }
+      }
+      $.prompt(change_title_popup);
+    },
+    changeRole() {
+      if (!this.active_unified_frame_argument) {
+        alert(gettext("Zaznacz argument, dla którego chcesz wybrać rolę."));
+      } else {
+        var existingSelect = function () {
+          let selected_unified_frame_argument = this.unified_frame_arguments.find(o => o.id === this.active_unified_frame_argument.id);
+          if (!selected_unified_frame_argument.proposed_roles) {
+            return gettext('Brak ról do wyboru.')
+          }
+          return selected_unified_frame_argument.proposed_roles.map(role => {
+            return `<label><input type="radio" name="roles" value="${role.id}" /> ${role.str}</label><br />`;
+          }).join("");
+        }.bind(this);
+
+        var newSelect = function () {
+          let rolesHTML = roles.map(role => {
+            return `<label><input type="radio" name="role" value="${role.id}" /> ${role.role}</label><br />`;
+          }).join("");
+          let attributesHTML = role_attributes.map(attribute => {
+            return `<label><input type="radio" name="attribute" value="${attribute.id}" /> ${attribute.attribute}</label><br />`;
+          }).join("");
+          return '<div class="row"><div class="column"><div class="role_select_header">Role</div>' + rolesHTML + '</div><div class="column"><div class="role_select_header">Atrybuty</div>' + attributesHTML +'</div></div>';
+        }.bind(this);
+
+        let change_role_popup = {
           state0: {
-            title: 'Zmiana nazwy ramy',
-            html: '<input type="text" size="32" value="' + title + '" name="title" />',
-            buttons: { Anuluj: 0, Zapisz: 1},
+            title: 'Wybór roli',
+            html: 'Wybierz lub dodaj rolÄ™',
+            buttons: { Wybierz: 0, Dodaj: 1, Koniec: -1 },
             focus: -1,
             submit: function(e,v,m,f){
-              if (v == 0) {
+              if (v == -1) {
+                e.preventDefault();
+
+                this.loadFrame();
+
                 $.prompt.close();
               }
-              if (v === 1) {
+              if (v === 0) {
                 e.preventDefault();
-                var title = f.title;
-                var data = { 'unified_frame_id' : this.unified_frame.id, 'unified_frame_title' : title };
-                $.ajax({
-                  type     : 'post',
-                  url      : '/' + lang + '/unifier/save_unified_frame_title/',
-                  dataType : 'json',
-                  data     : data,
-                  timeout  : 60000,
-                  success  : function(response) {
-                    show_info('Tytuł ramy zosał zapisany');
-                    $.prompt.close();
-                    this.loadFrame();
-                  }.bind(this),
-                  error: function(request, errorType, errorMessage) {
-                    show_error(errorType + ' (' + errorMessage + ')');
-                    $.prompt.close();
-                  }
+                $.prompt.goToState('state1');
+              }
+              if (v == 1) {
+                e.preventDefault();
+                $.prompt.goToState('state2');
+              }
+            }.bind(this)
+          },
+          state1: {
+            title: 'Wybierz rolÄ™',
+            html: existingSelect(),
+            buttons: {Anuluj: -1, Zatwierdź: 1},
+            focus: -1,
+            submit: function (e, v, m, f) {
+              if (v == -1) {
+                e.preventDefault();
+                $.prompt.goToState('state0');
+              }
+              if (v == 1) {
+                e.preventDefault();
+                normalizeFormData(f.roles).map(role_id => {
+                  var data = { 'unified_frame_id' : this.unified_frame.id, 'complement_id' : this.active_unified_frame_argument.id, 'role_id' : role_id };
+                  $.ajax({
+                    type     : 'post',
+                    url      : '/' + lang + '/unifier/save_selected_role/',
+                    dataType : 'json',
+                    data     : data,
+                    timeout  : 60000,
+                    success  : function(response) {
+                      show_info('Wybrana rola zosała zapisana');
+                      $.prompt.goToState('state0');
+                    }.bind(this),
+                    error: function(request, errorType, errorMessage) {
+                      show_error(errorType + ' (' + errorMessage + ')');
+                      $.prompt.close();
+                    }
+                  });
                 });
               }
             }.bind(this)
+          },
+          state2: {
+            title: 'Dodaj rolÄ™',
+            html: newSelect(),
+            buttons: {Anuluj: -1, Zatwierdź: 1},
+            focus: -1,
+            submit: function (e, v, m, f) {
+              if (v == -1) {
+                e.preventDefault();
+                $.prompt.goToState('state0');
+              }
+              if (v == 1) {
+                e.preventDefault();
+
+                var role_id = normalizeFormData(f.role)[0];
+
+                if(role_id != null) {
+                  var attribute_id = normalizeFormData(f.attribute)[0];
+
+                  var data = {
+                    'unified_frame_id': this.unified_frame.id,
+                    'complement_id': this.active_unified_frame_argument.id,
+                    'role_id': role_id,
+                    'attribute_id': attribute_id
+                  };
+                  $.ajax({
+                    type: 'post',
+                    url: '/' + lang + '/unifier/save_new_role/',
+                    dataType: 'json',
+                    data: data,
+                    timeout: 60000,
+                    success: function (response) {
+                      show_info('Nowa rola zosała zapisana');
+                      $.prompt.goToState('state0');
+                    }.bind(this),
+                    error: function (request, errorType, errorMessage) {
+                      show_error(errorType + ' (' + errorMessage + ')');
+                      $.prompt.close();
+                    }
+                  });
+                } else {
+                  alert(gettext("Musisz wybrać pzynajmniej rolę."));
+                }
+              }
+            }.bind(this)
           }
-        }
-        $.prompt(change_title_popup);
+        };
+        $.prompt(change_role_popup);
       }
+    }
   },
   mounted () {
     Split(['#semantics-frames-pane', '#semantics-schemata-pane'], {
@@ -169,7 +298,7 @@ export default {
           <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="$emit('goToDisplay')">Gotowe</td>
         </tr>
         <tr style="background-color: white;">
-          <td id="change-role" style="padding: 10px 15px 10px 15px; color: #000000;">Zmień rolę</td>
+          <td id="change-role" @click="changeRole" style="padding: 10px 15px 10px 15px; color: #000000;">Zmień rolę</td>
           <td id="remove-arg" style="padding: 10px 15px 10px 15px; color: #000000;">Usuń argum.</td>
           <td id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;">Zamień okna</td>
           <td id="duplicates" style="padding: 10px 15px 10px 15px; color: #000000;">Duplikuj</td>
@@ -192,11 +321,19 @@ export default {
               @mouseleave="unifiedFrameArgumentHovered(null)"
             >
               {{ argument.role_type }}
-              <ul>
-                <li v-for="proposed_role in argument.proposed_roles">
-                  {{ proposed_role.role }}
-                </li>
-              </ul>
+              
+              <div
+                v-if="argument.role"
+              >
+                [{{ argument.role.str }}]
+              </div>
+              <div v-else>
+                <ul>
+                  <li v-for="proposed_role in argument.proposed_roles">
+                    {{ proposed_role.str }}
+                  </li>
+                </ul>
+              </div>
             </td>
           </tr>
           <tr>
diff --git a/entries/static/entries/js/entries.js b/entries/static/entries/js/entries.js
index e98ec50..9a72eb8 100644
--- a/entries/static/entries/js/entries.js
+++ b/entries/static/entries/js/entries.js
@@ -9,6 +9,9 @@ var curr_realisation_descriptions = null;
 var curr_examples = null;
 var curr_examples_by_id = null;
 
+var roles = []
+var role_attributes = []
+
 function make_opinion_row(item, span, width) {
     var opinion_row = document.createElement('tr');
     opinion_row.className = 'opinion-row';
@@ -1063,7 +1066,27 @@ function initialize_entries_list() {
     
 }
 
+function getRoles() {
+    $.ajax({
+        dataType: "json",
+        url: 'roles',
+        success: function(data){
+            roles = data.roles;
+        },
+        async: false
+    });
+}
 
+function getRoleAttributes() {
+    $.ajax({
+        dataType: "json",
+        url: 'role_attributes',
+        success: function(data){
+            role_attributes = data.role_attributes;
+        },
+        async: false
+    });
+}
 
 $(document).ready(function() {
 
@@ -1129,6 +1152,10 @@ $(document).ready(function() {
 
     getPredefinedSelections();
 
+    getRoles();
+
+    getRoleAttributes();
+
     $.getJSON('relations', function(data){
         memorizeRelations(data.relations);
     });
diff --git a/entries/urls.py b/entries/urls.py
index 47ea4be..b728674 100644
--- a/entries/urls.py
+++ b/entries/urls.py
@@ -1,7 +1,8 @@
 from django.urls import path
 
 from . import autocompletes, views
-from .views import ajax_plWN_context_lookup, ajax_predefined_preferences, ajax_relations, ajax_synsets
+from .views import ajax_plWN_context_lookup, ajax_predefined_preferences, ajax_relations, ajax_synsets, ajax_roles, \
+    ajax_role_attributes
 
 app_name = 'entries'
 
@@ -21,6 +22,8 @@ urlpatterns = [
     path('autocomplete/', autocompletes.autocomplete, name='autocomplete'),
     path('plWN_context_lookup/', ajax_plWN_context_lookup, name='plWN_context_lookup'),
     path('predefined_preferences/', ajax_predefined_preferences, name='predefined_preferences'),
+    path('roles/', ajax_roles, name='roles'),
+    path('role_attributes/', ajax_role_attributes, name='role_attributes'),
     path('relations/', ajax_relations, name='relations'),
     path('synsets/', ajax_synsets, name='synsets'),
 
diff --git a/entries/views.py b/entries/views.py
index e8e75cf..39df259 100644
--- a/entries/views.py
+++ b/entries/views.py
@@ -19,7 +19,8 @@ from crispy_forms.utils import render_crispy_form
 from connections.models import Entry, Subentry, ArgumentConnection, RealisationDescription
 from meanings.models import LexicalUnit
 from syntax.models import NaturalLanguageDescription, Schema
-from semantics.models import Frame, PredefinedSelectionalPreference, SelectivePreferenceRelations
+from semantics.models import Frame, PredefinedSelectionalPreference, SelectivePreferenceRelations, SemanticRole, \
+    RoleAttribute
 
 from common.decorators import ajax_required, ajax
 from unifier.models import UnifiedFrame
@@ -912,6 +913,30 @@ def ajax_predefined_preferences(request):
 
     return context
 
+@ajax(method='get', encode_result=True)
+def ajax_roles(request):
+    roles = []
+    for role in SemanticRole.objects.order_by('priority'):
+       roles.append({"id": role.id, "role": role.role, "priority": role.priority})
+
+    context = {
+        'roles': roles,
+    }
+
+    return context
+
+@ajax(method='get', encode_result=True)
+def ajax_role_attributes(request):
+    roleAttributes = []
+    for roleAttribute in RoleAttribute.objects.order_by('priority'):
+        roleAttributes.append({"id": roleAttribute.id, "attribute": roleAttribute.attribute, "priority": roleAttribute.priority})
+
+    context = {
+        'role_attributes': roleAttributes,
+    }
+
+    return context
+
 # @render('relations.json')
 @ajax(method='get', encode_result=True)
 def ajax_relations(request):
diff --git a/unifier/urls.py b/unifier/urls.py
index d761f5d..166cca0 100644
--- a/unifier/urls.py
+++ b/unifier/urls.py
@@ -14,5 +14,7 @@ urlpatterns = [
     path('change_slowal2unified_fram_argument_mapping/', views.change_slowal2unified_fram_argument_mapping, name='change_slowal2unified_fram_argument_mapping'),
     path('change_slowal2unified_mapping_verification/', views.change_slowal2unified_mapping_verification, name='change_slowal2unified_mapping_verification'),
     path('save_unified_frame_title/', views.save_unified_frame_title, name='save_unified_frame_title'),
+    path('save_selected_role/', views.save_selected_role, name='save_selected_role'),
+    path('save_new_role/', views.save_new_role, name='save_new_role'),
 
 ]
diff --git a/unifier/views.py b/unifier/views.py
index 34ee7de..7aca78b 100644
--- a/unifier/views.py
+++ b/unifier/views.py
@@ -6,13 +6,14 @@ from django.http import JsonResponse
 from common.decorators import ajax_required
 from entries.polish_strings import EXAMPLE_SOURCE, EXAMPLE_OPINION
 from entries.views import get_scroller_params, get_alternations, get_prefs_list, schema2dict, frame2dict
-from semantics.models import Frame
+from semantics.models import Frame, ArgumentRole, SemanticRole, RoleAttribute
 from syntax.models import Schema
 from unifier.models import UnifiedFrameArgument, UnifiedRelationalSelectionalPreference, UnifiedFrame, \
     UnifiedFrame2SlowalFrameMapping, UnifiedFrameArgumentSlowalFrameMapping
 
 
 @ajax_required
+@transaction.atomic
 def save_synset_preference(request):
     if request.method == 'POST':
         frame_id = request.POST['frame_id']
@@ -25,6 +26,7 @@ def save_synset_preference(request):
     return JsonResponse({})
 
 @ajax_required
+@transaction.atomic
 def save_predefined_preference(request):
     if request.method == 'POST':
         frame_id = request.POST['frame_id']
@@ -98,13 +100,17 @@ def unifiedFrame2dict(frame):
             {
                 'str'         : str(a),
                 'id'          : a.id,
-                'role'        : '{}{}'.format(a.role.role.role.lower(), ' ' + a.role.attribute.attribute.lower() if a.role.attribute else '') if a.role is not None else None,
+                'role'        : {
+                    'str': '{}{}'.format(a.role.role.role.lower(), ' ' + a.role.attribute.attribute.lower() if a.role.attribute else '') if a.role is not None else None,
+                    'id': str(a.role.id)
+                } if a.role is not None else None,
                 'role_type'   : a.role_type.type.lower(),
                 'preferences' : get_prefs_list(a),
                 'proposed_roles': [{
-                    'role'        : '{}{}'.format(r.role.role.lower(), ' ' + r.attribute.attribute.lower() if r.attribute else ''),
+                    'str': '{}{}'.format(r.role.role.lower(), ' ' + r.attribute.attribute.lower() if r.attribute else ''),
+                    'id': str(r.id)
                 } for r in a.proposed_roles.all()],
-            } for a in frame.unified_arguments.all()
+            } for a in sorted(frame.unified_arguments.all(), key=lambda x: x.order_id)
         ],
 
         'slowal_frame_mapping': [
@@ -280,3 +286,35 @@ def save_unified_frame_title(request):
             unifiedFrame.title = unified_frame_title
             unifiedFrame.save()
     return JsonResponse({})
+
+@ajax_required
+@transaction.atomic
+def save_selected_role(request):
+    if request.method == 'POST':
+        unified_frame_id = request.POST['unified_frame_id']
+        complement_id = request.POST['complement_id']
+        role_id = request.POST['role_id']
+
+        unifiedFrameArgument = UnifiedFrameArgument.objects.get(unified_frame_id=int(unified_frame_id), id=int(complement_id))
+        unifiedFrameArgument.role_id = role_id
+        unifiedFrameArgument.save()
+    return JsonResponse({})
+
+@ajax_required
+@transaction.atomic
+def save_new_role(request):
+    if request.method == 'POST':
+        unified_frame_id = request.POST['unified_frame_id']
+        complement_id = request.POST['complement_id']
+        role_id = request.POST['role_id']
+        attribute_id = request.POST.get('attribute_id', None)
+
+        argumentRole = ArgumentRole.objects.filter(role_id=role_id, attribute_id=attribute_id).first()
+        if argumentRole is None:
+            argumentRole = ArgumentRole(role=SemanticRole.objects.get(pk=role_id), attribute=RoleAttribute.objects.get(pk=attribute_id))
+            argumentRole.save()
+
+        unifiedFrameArgument = UnifiedFrameArgument.objects.get(unified_frame_id=unified_frame_id, id=complement_id)
+        unifiedFrameArgument.role = argumentRole
+        unifiedFrameArgument.save()
+    return JsonResponse({})
-- 
GitLab