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