diff --git a/entries/static/entries/js/entries.js b/entries/static/entries/js/entries.js index 3236b7c26153c8e2f848f094e23f82407d4e4605..a270bc82d5ad192b3b6b4f2471c334f7402bc301 100644 --- a/entries/static/entries/js/entries.js +++ b/entries/static/entries/js/entries.js @@ -17,6 +17,10 @@ var main_vertical_relations = [] var temporal_vertical_relations = [] var vertical_relation_negations = [] +var example_opinions = [] +var example_sources = [] + + function make_opinion_row(item, span, width) { const opinion_row = document.createElement('tr'); opinion_row.className = 'opinion-row'; @@ -1184,6 +1188,30 @@ function getVerticalRelationNegations() { }); } +function getExampleOpinions() { + $.ajax({ + dataType: "json", + url: '/' + lang + '/entries/example_opinions', + success: function(data){ + example_opinions = data.example_opinions; + }, + async: false + }); +} + + +function getExampleSources() { + $.ajax({ + dataType: "json", + url: '/' + lang + '/entries/example_sources', + success: function(data){ + example_sources = data.example_sources; + }, + async: false + }); +} + + $(document).ready(function() { bind_last_visited(); @@ -1225,6 +1253,10 @@ $(document).ready(function() { getVerticalRelationNegations(); + getExampleOpinions(); + + getExampleSources(); + // $.getJSON('relations', function(data){ // memorizeRelations(data.relations); // }); diff --git a/entries/urls.py b/entries/urls.py index 9fd3101c30f53f50efa34b53be8dcb92cec42527..da5e3c6fe5d110d2cbd0cf07c04d0e3ce07d686c 100644 --- a/entries/urls.py +++ b/entries/urls.py @@ -2,7 +2,8 @@ from django.urls import path from . import autocompletes, views from .views import ajax_plWN_context_lookup, ajax_predefined_preferences, ajax_relations, ajax_synsets, ajax_roles, \ - ajax_role_attributes, ajax_role_sub_attributes, ajax_free_slowal_frame_lookup, ajax_frame_opinions + ajax_role_attributes, ajax_role_sub_attributes, ajax_free_slowal_frame_lookup, ajax_frame_opinions, \ + ajax_example_opinions, ajax_example_sources app_name = 'entries' @@ -35,6 +36,9 @@ urlpatterns = [ path('free_slowal_frame_lookup/', ajax_free_slowal_frame_lookup, name='free_slowal_frame_lookup'), + path('example_opinions/', ajax_example_opinions, name='example_opinions'), + path('example_sources/', ajax_example_sources, name='example_sources'), + # TODO remove! #path('test/', views.test, name='test'), path('', views.entries, name='entries'), diff --git a/entries/views.py b/entries/views.py index f6f1f0255ceeb412799e5555cc7dac0f6dab144e..0e2422afc77b6e126a6159c4d68f44e3fe77ecfa 100644 --- a/entries/views.py +++ b/entries/views.py @@ -19,7 +19,7 @@ from django.utils.translation import gettext as _ from crispy_forms.utils import render_crispy_form from connections.models import Entry, Subentry, ArgumentConnection, RealisationDescription -from examples.models import Example +from examples.models import Example, ExampleOpinion, ExampleSource from meanings.models import LexicalUnit from syntax.models import NaturalLanguageDescription, Schema from semantics.models import Frame, PredefinedSelectionalPreference, SelectivePreferenceRelations, SemanticRole, \ @@ -477,7 +477,9 @@ def get_entries(request): #entries = entries.filter(subentries__schema_hooks__alternation=2) if without_frames: - entries = entries.filter(name__in=(LexicalUnit.objects.filter(Q(frames__isnull=True) | Q(frames__in_building=True)).values("base"))) + # entries = entries.filter(lexical_units__frames__isnull=True) + entries = entries.filter(Q(lexical_units__frames__isnull=True) | Q(lexical_units__frames__in_building=True)) + # entries = entries.filter(name__in=(LexicalUnit.objects.filter(Q(frames__isnull=True) | Q(frames__in_building=True)).values("base"))) total = entries.count() if scroller_params['filter']: @@ -1170,6 +1172,31 @@ def ajax_relations(request): return context + +@ajax(method='get', encode_result=True) +def ajax_example_opinions(request): + + relations = [{"id": relation.id, "opinion": relation.key} for relation in ExampleOpinion.objects.all()] + + context = { + 'example_opinions': relations, + } + + return context + + +@ajax(method='get', encode_result=True) +def ajax_example_sources(request): + + relations = [{"id": relation.id, "source": relation.key} for relation in ExampleSource.objects.all()] + + context = { + 'example_sources': relations, + } + + return context + + @ajax(method='get', encode_result=True) def ajax_synsets(request, base, pos): diff --git a/freelus/urls.py b/freelus/urls.py index c808a311a370381194f9aae4df405ba817fe679f..e000196643f3525e6b0377e93967934dc14ca5f4 100644 --- a/freelus/urls.py +++ b/freelus/urls.py @@ -20,4 +20,5 @@ urlpatterns = [ path('remove_frame_in_progress/', views.remove_frame_in_progress, name='remove_frame_in_progress'), path('duplicate_frame/', views.duplicate_frame, name='duplicate_frame'), + path('add_examples_to_lus/', views.add_examples_to_lus, name='add_examples_to_lus'), ] diff --git a/freelus/views.py b/freelus/views.py index dc430fad56622b531fc0ab5d34528f527d10c890..1a9544fe51fb8805c36c045ae851267f1eeb77d2 100644 --- a/freelus/views.py +++ b/freelus/views.py @@ -55,24 +55,18 @@ def change_lus_in_slowal_frame(request): entry = Entry.objects.get(pk=entry_id) for lu_id in frame_lexical_units_to_remove: lu = LexicalUnit.objects.get(pk=lu_id) - entry.lexical_units.remove(lu) frame.lexical_units.remove(lu) - entry.lexical_units_count = entry.lexical_units_count - 1 frame_lexical_units_to_add = request_lu_int_ids.difference(frame_lexical_units) for lu_id in frame_lexical_units_to_add: lu = LexicalUnit.objects.get(pk=lu_id) - entry.lexical_units.add(lu) frame.lexical_units.add(lu) - entry.lexical_units_count = entry.lexical_units_count + 1 if len(frame.lexical_units.all()) == 0: remove_frame_in_progress_base(frame, request.user) else: frame.save() - entry.save() - return JsonResponse({}) return JsonResponse({}) @@ -189,6 +183,34 @@ def change_role_base(frame_argument, request): frame_argument.role = argument_role +@ajax_required +@transaction.atomic +def add_examples_to_lus(request): + """ + Add new example to the lus. + The request has to contain 'selected_lus' that represents lu ids. + Example 'example', 'opinion', 'source' is also required. + :param request: http request + :return: Empty json response + """ + if request.method == 'POST': + sentence = request.POST['sentence'] + opinion_id = request.POST['opinion-id'] + source_id = request.POST['source-id'] + entry_id = request.POST['entry-id'] + selected_lus = json.loads(request.POST['selected_lus']) + + example = Example.objects.create(entry_id=entry_id, sentence=sentence, opinion_id=opinion_id, source_id=source_id) + example.save() + + lexical_units = LexicalUnit.objects.filter(id__in=selected_lus).all() + for lexical_unit in lexical_units: + example_conn = ExampleConnection(example_id=example.id, lexical_unit=lexical_unit) + example_conn.save() + + return JsonResponse({}) + + @ajax_required @transaction.atomic def attach_examples_to_frame(request): diff --git a/frontend/src/components/unification/free_lu/FreeLuEdit.vue b/frontend/src/components/unification/free_lu/FreeLuEdit.vue index 2081a8137131c896cb98c0d6d768b4b1bc0fe191..0135b6b7df221e0b9818361596147085f615ac8c 100644 --- a/frontend/src/components/unification/free_lu/FreeLuEdit.vue +++ b/frontend/src/components/unification/free_lu/FreeLuEdit.vue @@ -292,7 +292,8 @@ if (this.frame_in_progress) { if (this.selectedLus && this.selectedLus.length > 0) { const examplesSelect = function () { - return '<div class="attach-examples-table-wrapper-scroll-y attach-examples-custom-scrollbar"><table id="attach-examples" class="table table-bordered table-striped mb-0"><thead><tr class="font-weight-bold"><th></th><th>Zdanie</th><th>Źródło</th><th>Opinia</th></tr></thead>' + this.examples.map(example => { + return '<div></div>' + + '<div class="attach-examples-table-wrapper-scroll-y attach-examples-custom-scrollbar"><table id="attach-examples" class="table table-bordered table-striped mb-0"><thead><tr class="font-weight-bold"><th></th><th>Zdanie</th><th>Źródło</th><th>Opinia</th></tr></thead>' + this.examples.map(example => { return `<tr><td><input type="checkbox" ${this.selectedLus && example.lu_ids.includes(this.selectedLus[0].id) ? 'checked' : ''} name="lus" value="${example.id}" /></td><td>${example.sentence}</td><td>${example.source}</td><td>${example.opinion}</td></tr>`; }).join("") + '</table></div>'; }.bind(this); @@ -338,6 +339,73 @@ alert(gettext("Stwórz nową ramę.")); } }, + add_new_example() { + if (this.frame_in_progress) { + if (this.selectedLus && this.selectedLus.length > 0) { + const examplesSelect = function () { + let example_opinions_display = "<select name = \"opinion\">"; + let i; + for (i = 0; i < example_opinions.length; i++) { + example_opinions_display += "<option value = \"" + example_opinions[i].id + "\">" + example_opinions[i].opinion + "</option>"; + } + example_opinions_display += "</select>" + + let example_sources_display = "<select name = \"source\">"; + for (i = 0; i < example_sources.length; i++) { + example_sources_display += "<option value = \"" + example_sources[i].id + "\">" + example_sources[i].source + "</option>"; + } + example_sources_display += "</select>" + + return '<div class="attach-examples-table-wrapper-scroll-y attach-examples-custom-scrollbar"><table id="attach-examples" class="table table-bordered table-striped mb-0"><thead><tr class="font-weight-bold"><th>Zdanie</th><th>Źródło</th><th>Opinia</th></tr></thead>' + + '<tr><td><input type="text" name="sentence"/></td><td>'+example_sources_display+'</td><td>'+example_opinions_display+'</td></tr></table></div>'; + }.bind(this); + + const attach_examples_popup = { + state0: { + title: 'Dodaj przykład dla: ' + this.selectedLus.map(e => e.str).join(', '), + html: examplesSelect, + buttons: {Anuluj: 0, Wybierz: 1}, + focus: -1, + submit: function (e, v, m, f) { + if (v == 0) { + e.preventDefault(); + $.prompt.close(); + } + if (v === 1) { + e.preventDefault(); + let sentence = normalizeFormData(f.sentence)[0]; + let source = normalizeFormData(f.source)[0]; + let opinion = normalizeFormData(f.opinion)[0]; + + send_post_request('/freelus/add_examples_to_lus/', + { + 'selected_lus': JSON.stringify(this.selectedLus.map(e => e.id)), + 'entry-id': this.entryId, + 'sentence': sentence, + 'source-id': source, + 'opinion-id': opinion, + }, + (response) => { + show_info('Przykład został dodany.'); + this.loadEntry(); + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + $.prompt.close(); + }) + } + }.bind(this) + } + } + $.prompt(attach_examples_popup); + } else { + alert(gettext("Zaznacz jednostkę leksykalną, do której chcesz dodać przykład.")); + } + } else { + alert(gettext("Stwórz nową ramę.")); + } + }, change_frame_opinion() { if (this.frame_in_progress) { const frame_opinion_select = function () { @@ -639,6 +707,9 @@ <td id="assign-examples" class="table-button-menu-td" @click="attach_examples()" style="padding: 10px 15px 10px 15px; color: #000000;">Podłącz przykłady </td> + <td id="change-frame-opinion" class="table-button-menu-td" @click="change_frame_opinion()" + style="padding: 10px 15px 10px 15px; color: #000000;">Zmień opinię + </td> <td id="finish-frame-building" class="table-button-menu-td" @click="finish_frame_building()" style="padding: 10px 15px 10px 15px; color: #000000;">Gotowe </td> @@ -657,12 +728,13 @@ <td id="delete-schema" class="table-button-menu-td" @click="delete_schema_connections()" style="padding: 10px 15px 10px 15px; color: #000000;">Odłącz pozycję </td> + <td id="add_new_example" class="table-button-menu-td" @click="add_new_example()" + style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj przykład + </td> <td id="remove-argument" class="table-button-menu-td" @click="remove_argument()" style="padding: 10px 15px 10px 15px; color: #000000;">Usuń argument </td> - <td id="change-frame-opinion" class="table-button-menu-td" @click="change_frame_opinion()" - style="padding: 10px 15px 10px 15px; color: #000000;">Zmień opinię - </td> + <td id="duplicate_slowal_frame" class="table-button-menu-td" @click="duplicate_slowal_frame()" style="padding: 10px 15px 10px 15px; color: #000000;">Powiel ramę </td>