From 675deb9de2993d192a501d484bb5a6b72cf38ecc Mon Sep 17 00:00:00 2001
From: dcz <dcz@ipipan.waw.pl>
Date: Tue, 24 Oct 2023 15:37:41 +0200
Subject: [PATCH] Free lus module - first commit.

---
 ...fined_selectional_preferences_update_2.txt |  22 +
 entries/static/entries/js/free_lus_list.js    |  26 +
 entries/templates/lu_free.html                |   1 +
 entries/views.py                              |  65 +-
 freelus/__init__.py                           |   0
 freelus/apps.py                               |   5 +
 freelus/models.py                             |   0
 freelus/urls.py                               |   9 +
 freelus/views.py                              |  47 ++
 .../components/unification/free_lu/FreeLu.vue |  50 +-
 .../unification/free_lu/FreeLuEdit.vue        | 744 ++++++++----------
 .../unification/free_lu/FreeLuRightPane.vue   |  10 +-
 .../unification/free_lu/FreeLusList.vue       |  60 ++
 .../SemanticsSchemataComponent.vue            |  47 +-
 .../components/unification/shared/utils.js    |  18 +-
 importer/WalentyXML.py                        |   2 +-
 semantics/models.py                           |   1 +
 shellvalier/urls.py                           |   1 +
 .../commands/add_predefined_preferences.py    |   8 +-
 19 files changed, 630 insertions(+), 486 deletions(-)
 create mode 100644 data/db_manual_updates/predefined_selectional_preferences_update_2.txt
 create mode 100644 entries/static/entries/js/free_lus_list.js
 create mode 100644 freelus/__init__.py
 create mode 100644 freelus/apps.py
 create mode 100644 freelus/models.py
 create mode 100644 freelus/urls.py
 create mode 100644 freelus/views.py
 create mode 100644 frontend/src/components/unification/free_lu/FreeLusList.vue

diff --git a/data/db_manual_updates/predefined_selectional_preferences_update_2.txt b/data/db_manual_updates/predefined_selectional_preferences_update_2.txt
new file mode 100644
index 0000000..7908da8
--- /dev/null
+++ b/data/db_manual_updates/predefined_selectional_preferences_update_2.txt
@@ -0,0 +1,22 @@
+MIEJSCE:
+    <lokal-1, budowla-1, rejon-1, obszar-1, państwo-1, jednostka administracyjna-1, woda-4>
+
+select base, synset_id from meanings_lexicalunit where base='lokal' and sense='1';
+4857
+select base, synset_id from meanings_lexicalunit where base='budowla' and sense='1';
+287
+select base, synset_id from meanings_lexicalunit where base='rejon' and sense='1';
+35149
+select base, synset_id from meanings_lexicalunit where base='obszar' and sense='1';
+2898
+select base, synset_id from meanings_lexicalunit where base='państwo' and sense='1';
+41068
+select base, synset_id from meanings_lexicalunit where base='jednostka administracyjna' and sense='1';
+5592
+select base, synset_id from meanings_lexicalunit where base='woda' and sense='4';
+31676
+
+insert into semantics_selectivepreference_synsets (selectivepreference_id, synset_id) values (9, 4857),(9, 287),(9, 35149),(9, 2898),(9, 41068),(9, 5592),(9, 31676);
+
+
+
diff --git a/entries/static/entries/js/free_lus_list.js b/entries/static/entries/js/free_lus_list.js
new file mode 100644
index 0000000..4b9fbd6
--- /dev/null
+++ b/entries/static/entries/js/free_lus_list.js
@@ -0,0 +1,26 @@
+function setup_free_lus_list(options) {
+    const can_see_assignees = has_permission("users.view_assignment");
+
+    const ajaxURL = can_see_assignees ? '/' + lang + '/entries/get_entries/?with_lexical_units=false&without_frames=true' : '/' + lang + '/unifier/get_unified_frames/?exclude_status=N&restrict_to_user='+window.USER_USERNAME;
+
+    const datatable = setup_datatable({
+        element: options.table,
+        url: ajaxURL,
+        columns: [
+            { data: 'lemma' },
+            { data: 'status' },
+            { data: 'id' },
+        ],
+        hidden_columns: [2],
+        selectEntryId: options.selectEntryId,
+        setup_hierarchy_marking: false
+    });
+    datatable.on('click', 'tr.entry', function () {
+        const data = datatable.row(this).data();
+        if (!data) return;
+        const related = data.related === true;
+        $('.entry', options.table).removeClass('table-primary');
+        options.entrySelected(Number(data.id));
+        $(this).addClass('table-primary');
+    });
+}
diff --git a/entries/templates/lu_free.html b/entries/templates/lu_free.html
index 61a407d..d306c3c 100644
--- a/entries/templates/lu_free.html
+++ b/entries/templates/lu_free.html
@@ -12,6 +12,7 @@
     <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/free_lus_list.js' %}"></script>
     <script src="{% static 'entries/js/jquery-impromptu.min.js' %}"></script>
     <script>
         window.currUnifiedFrameId = {{ unified_frame_id|default:'null' }};
diff --git a/entries/views.py b/entries/views.py
index ee21da5..5435fcf 100644
--- a/entries/views.py
+++ b/entries/views.py
@@ -413,6 +413,16 @@ def get_scroller_params(POST_data):
 # TODO restriction to >1 subentries for testing css – remove!!!
 #from django.db.models import Count
 
+
+def iter_lexical_units(lexical_units, has_unified_frame='false'):
+    for lu in lexical_units:
+        lu._frame = lu._frames[0] if lu._frames and len(lu._frames) > 0 else None
+        if lu._frame is None or (not hasattr(lu._frame, 'slowal_frame_2_unified_frame') and has_unified_frame == 'true'):
+            continue
+        else:
+            yield lu
+
+
 @ajax_required
 @login_required
 def get_entries(request):
@@ -423,6 +433,7 @@ 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'
+        without_frames = request.GET.get('without_frames') == 'true'
         exclude_status = request.GET.get('exclude_status')
         restrict_to_user = request.GET.get('restrict_to_user')
         has_unified_frame = request.GET.get('has_unified_frame')
@@ -432,7 +443,10 @@ def get_entries(request):
         #entries = entries.annotate(nsub=Count('subentries')).filter(nsub__gt=1)
         #entries = entries.filter(subentries__schemata__opinion__key__in=('vul', 'col')).filter(status__key__in=('(S) gotowe', '(S) sprawdzone'))
         #entries = entries.filter(subentries__schema_hooks__alternation=2)
-        
+
+        if without_frames:
+            entries = entries.filter(lexical_units__frames__isnull=True)
+
         total = entries.count()
         if scroller_params['filter']:
             entries = entries.filter(name__startswith=scroller_params['filter'])
@@ -499,14 +513,6 @@ def get_entries(request):
         status_names = STATUS()
         POS_names = POS()
 
-        def iter_lexical_units(e):
-            for lu in e.lexical_units.all():
-                lu._frame = lu._frames[0] if lu._frames and len(lu._frames) > 0 else None
-                if lu._frame is None or (not hasattr(lu._frame, 'slowal_frame_2_unified_frame') and has_unified_frame == 'true'):
-                    continue
-                else:
-                    yield lu
-
         result = {
             'draw' : scroller_params['draw'],
             'recordsTotal': total,
@@ -522,15 +528,7 @@ def get_entries(request):
                     **(
                         {
                             'lexical_units': [
-                                {
-                                    'pk': lu.pk,
-                                    'display': str(lu),
-                                    'assignee_username': (
-                                        lu._frame._assignments[0].user.username if lu._frame and lu._frame._assignments else None
-                                    ),
-                                    'status': lu._frame.status if lu._frame else "",
-                                    'unified_frame_id': lu._frame.slowal_frame_2_unified_frame.unified_frame_id if lu._frame and hasattr(lu._frame, 'slowal_frame_2_unified_frame') else -1,
-                                } for lu in iter_lexical_units(e)
+                                lu2dict(lu) for lu in iter_lexical_units(e.lexical_units.all(), has_unified_frame)
                             ]
                         }
                         if with_lexical_units else {}
@@ -542,6 +540,18 @@ def get_entries(request):
     return JsonResponse({})
 
 
+def lu2dict(lu):
+    return {
+        'pk': lu.pk,
+        'display': str(lu),
+        'assignee_username': (
+             (lu._frame._assignments[0].user.username if lu._frame and lu._frame._assignments else None) if hasattr(lu, '_frame') else None
+        ),
+        'status': lu._frame.status if hasattr(lu, '_frame') and lu._frame else "",
+        'unified_frame_id': lu._frame.slowal_frame_2_unified_frame.unified_frame_id if hasattr(lu, '_frame') and lu._frame and hasattr(lu._frame, 'slowal_frame_2_unified_frame') else -1,
+    }
+
+
 def subentry2str(subentry):
     ret = subentry.entry.name
     if subentry.inherent_sie.name == 'true':
@@ -660,6 +670,7 @@ def frame2dict(frame, entry_meanings):
         'opinion_key'   : frame.opinion.key,
         'id'            : frame.id,
         'status'        : frame.status,
+        'in_building'   : frame.in_building,
         'lexical_units' : [
             {
                 'str'           : lu.text_rep,
@@ -910,7 +921,8 @@ def get_entry(request):
                 if schemata:
                     all_schema_objects += list(schema_objects)
                     subentries.append({ 'str' : subentry2str(subentry), 'schemata' : schemata })
-            frame_objects = Frame.objects.filter(arguments__argument_connections__schema_connections__subentry__entry=entry).distinct()
+            # frame_objects = Frame.objects.filter(arguments__argument_connections__schema_connections__subentry__entry=entry).distinct()
+            frame_objects = Frame.objects.filter(lexical_units__entry=entry).distinct()
             # filter out frames by frame properties
             if filter_frames:
                 frame_objects = get_filtered_objects2(frame_forms, frame_objects)
@@ -918,8 +930,9 @@ def get_entry(request):
                 frame_objects = frame_objects.filter(lexical_units=lexical_unit)
             if local_frame_filter_form:
                 frame_objects = get_filtered_objects(local_frame_filter_form, frame_objects)
-            frames = [frame2dict(frame, entry.lexical_units.all()) for frame in frame_objects]
-            alternations, realisation_phrases, realisation_descriptions = get_alternations(all_schema_objects, frame_objects)
+            frames = [frame2dict(frame, entry.lexical_units.all()) for frame in filter(lambda frame: not frame.in_building, frame_objects.all())]
+            frames_in_building_process = [frame2dict(frame, entry.lexical_units.all()) for frame in filter(lambda frame: frame.in_building, frame_objects.all())]
+            alternations, realisation_phrases, realisation_descriptions = get_alternations(all_schema_objects, filter(lambda frame: not frame.in_building, frame_objects.all()))
             examples = get_examples(entry)
             unified_frame = None
             if lexical_unit and (unified_frame := UnifiedFrame.objects.all().for_lexical_unit(lexical_unit).first()):
@@ -934,7 +947,13 @@ def get_entry(request):
             request.session['last_visited'].insert(0, (entry.name, entry.id))
             request.session['last_visited'] = request.session['last_visited'][:(MAX_LAST_VISITED + 1)]
             request.session.modified = True
-            return JsonResponse({ 'subentries' : subentries, 'frames' : frames, 'alternations' : alternations, 'realisation_phrases' : realisation_phrases, 'realisation_descriptions' : realisation_descriptions, 'examples' : examples, 'unified_frame': unified_frame, 'last_visited' : request.session['last_visited'] })
+
+            frame_lexical_unit_ids = set(map(lambda lu: lu['id'], (lu for iterable in frames for lu in iterable['lexical_units'])))
+            frame_lexical_unit_ids = frame_lexical_unit_ids | set(map(lambda lu: lu['id'], (lu for iterable in frames_in_building_process for lu in iterable['lexical_units'])))
+
+            free_lexical_units = [lu2dict(lu) for lu in filter(lambda lu: lu.id not in frame_lexical_unit_ids, LexicalUnit.objects.filter(Q(base=entry.name) | Q(base__startswith=entry.name+' ')).all())]
+
+            return JsonResponse({'free_lexical_units': free_lexical_units, 'subentries' : subentries, 'frames' : frames, 'frames_in_building_process': frames_in_building_process, 'alternations' : alternations, 'realisation_phrases' : realisation_phrases, 'realisation_descriptions' : realisation_descriptions, 'examples' : examples, 'unified_frame': unified_frame, 'last_visited' : request.session['last_visited'] })
     return JsonResponse({})
 
 
@@ -1112,7 +1131,7 @@ def ajax_synsets(request, base, pos):
 def lexical_units_without_empty_frames(obj_results):
     for lu in obj_results.all():
         lu._frames = lu._frames[0] if lu._frames and len(lu._frames) > 0 else None
-        if lu._frames is None:
+        if lu._frames is not None:
             continue
         else:
             yield lu
diff --git a/freelus/__init__.py b/freelus/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/freelus/apps.py b/freelus/apps.py
new file mode 100644
index 0000000..5e29e9f
--- /dev/null
+++ b/freelus/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class FreeLusConfig(AppConfig):
+    name = 'freelus'
diff --git a/freelus/models.py b/freelus/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/freelus/urls.py b/freelus/urls.py
new file mode 100644
index 0000000..6119d3c
--- /dev/null
+++ b/freelus/urls.py
@@ -0,0 +1,9 @@
+from django.urls import path
+
+from . import views
+
+app_name = 'freelus'
+
+urlpatterns = [
+    path('create_new_slowal_frame/', views.create_new_slowal_frame, name='create_new_slowal_frame'),
+]
diff --git a/freelus/views.py b/freelus/views.py
new file mode 100644
index 0000000..f6832f9
--- /dev/null
+++ b/freelus/views.py
@@ -0,0 +1,47 @@
+import json
+from django.db import transaction
+from django.http import JsonResponse
+
+from common.decorators import ajax_required
+from connections.models import Entry, Status
+from meanings.models import LexicalUnit
+from semantics.models import Frame, FrameOpinion
+
+
+@ajax_required
+@transaction.atomic
+def change_status(request):
+    if request.method == 'POST':
+        entry_id = request.POST['entry_id']
+        status = request.POST['status']
+
+        entry = Entry.get(pk=entry_id)
+        entry.status = Status.objects.get(key=status)
+        entry.save()
+        return JsonResponse({})
+
+    return JsonResponse({})
+
+
+@ajax_required
+@transaction.atomic
+def create_new_slowal_frame(request):
+    if request.method == 'POST':
+        entry_id = request.POST['entry_id']
+        lu_ids = json.loads(request.POST['lu_ids'])
+        frame = Frame(opinion=FrameOpinion.objects.get(key='unk'), in_building=True)
+        frame.save()
+
+        entry = Entry.objects.get(pk=entry_id)
+        for lu_id in lu_ids:
+            lu = LexicalUnit.objects.get(pk=lu_id)
+            lu.entry = entry
+            lu.save()
+            frame.lexical_units.add(lu)
+            entry.lexical_units_count = entry.lexical_units_count + 1
+
+        frame.save()
+        entry.save()
+        return JsonResponse({})
+
+    return JsonResponse({})
diff --git a/frontend/src/components/unification/free_lu/FreeLu.vue b/frontend/src/components/unification/free_lu/FreeLu.vue
index 280e9d2..e433502 100644
--- a/frontend/src/components/unification/free_lu/FreeLu.vue
+++ b/frontend/src/components/unification/free_lu/FreeLu.vue
@@ -1,40 +1,24 @@
 <script>
-import UnificationFramesList from "../Unification/UnificationFramesList.vue";
-import FreeLuRightPane from "./FreeLuRightPane.vue";
+import FreeLuEdit from "./FreeLuEdit.vue";
+import FreeLusList from "./FreeLusList.vue";
 
 export default {
   data () {
     return {
       entryId: null,
-      lexicalUnitId: null,
-      unifiedFrameId: null,
       gettext: window.gettext,
-      unificationEntriesListRefreshKey: 1,
     };
   },
-  components: {FreeLuRightPane, UnificationFramesList},
+  components: {FreeLuEdit, FreeLusList},
   methods: {
-    lexicalUnitSelected (entryId, lexicalUnitId) {
+    entrySelected (entryId) {
       this.entryId = entryId;
-      this.lexicalUnitId = lexicalUnitId;
-    },
-    unifiedFrameSelected (unifiedFrameId, entryId, lexicalUnitId) {
-      this.unifiedFrameId = unifiedFrameId;
-      this.entryId = entryId;
-      this.lexicalUnitId = lexicalUnitId;
+      console.log("entrySelected: " + entryId);
     },
     refreshEntriesList() {
-      this.unificationEntriesListRefreshKey++;
     }
   },
-  setup() {
-    const unified_frame_id = new URL(location.href).searchParams.get('unified_frame_id');
-    return {
-      initial_unified_frame_id: parseInt(unified_frame_id),
-    };
-  },
   mounted () {
-    this.unifiedFrameSelected(window.currUnifiedFrameId);
     $('#entries-list').length && Split(['#entries-list', '#entry-display'], {
       sizes: [20, 80],
       gutterSize: 4,
@@ -52,22 +36,20 @@ export default {
 <template>
   <div id="entries-list" class="col h-100 w-100 pr-0 overflow-hidden">
     <div id="entries-list-div" class="col p-0 h-100 w-100 overflow-hidden">
-      <unification-frames-list
-              :unificationEntriesListRefreshKey="unificationEntriesListRefreshKey"
-              :initialUnifiedFrameId="initial_unified_frame_id"
-              :setupHierarchyMarking="true"
-              @unified-frame-selected="unifiedFrameSelected"
-      />
+      <free-lus-list @entry-selected="entrySelected"/>
     </div>
   </div>
   <div id="entry-display" class="col h-100 p-0 overflow-hidden">
-    <free-lu-right-pane
-        ref="hierarchyRightPane"
-        :entryId="entryId"
-        :lexicalUnitId="lexicalUnitId"
-        :initialUnifiedFrameId="unifiedFrameId"
-        @refresh-entries-list="refreshEntriesList"
-    />
+
+    <div v-if="entryId" :key="entryId" class="row h-100 m-0 p-0 overflow-auto" id="semantics-top-pane">
+      <free-lu-edit
+              ref="freeLusEdit"
+              v-if="entryId"
+              :key="entryId"
+              :entryId="entryId"
+              @refresh-entries-list="refreshEntriesList"
+      />
+    </div>
   </div>
 </template>
 
diff --git a/frontend/src/components/unification/free_lu/FreeLuEdit.vue b/frontend/src/components/unification/free_lu/FreeLuEdit.vue
index 58881e1..4f552fa 100644
--- a/frontend/src/components/unification/free_lu/FreeLuEdit.vue
+++ b/frontend/src/components/unification/free_lu/FreeLuEdit.vue
@@ -6,9 +6,9 @@ import SlowalFrameComponent from "../shared/frame-components/SlowalFrameComponen
 import SemanticsSchemataComponent from "../shared/frame-components/SemanticsSchemataComponent.vue";
 import MeaningComponent from "../shared/frame-components/MeaningComponent.vue";
 import SelectionalPreference from "../Unification/SelectionalPreference.js";
-import { slowal_frames2selecional_preferencies } from "../shared/utils.js";
 import FreeLuPreview from "./FreeLuPreview.vue";
 import FreeLuElement from "./FreeLuElement.vue";
+import {frames2lexical_units} from "../shared/utils";
 
 let FreeLuEdit = {
   components: {FreeLuElement, FreeLuPreview}
@@ -16,11 +16,7 @@ let FreeLuEdit = {
 
 Object.assign(FreeLuEdit, {
   props: {
-    unifiedFrameId: Number,
-    previewedUnifiedFrameId: Number,
-    readOnly: Boolean,
-    initialRightPaneTab: String,
-    forceRefresh: Number,
+    entryId: Number,
   },
   data() {
     return {
@@ -32,15 +28,15 @@ Object.assign(FreeLuEdit, {
       active_unified_frame_argument: null,
       slowal_frames2selecional_preferencies_mapping: {},
       lexical_units: [],
+      free_lexical_units: [],
+      frame_in_progress: null,
+      frame_in_progress_arguments: null,
       img_prefix: window.STATIC_URL,
       frames: [],
       right_pane_tabs: [
         {id: 'schemata', label: gettext('Schematy')},
-        {id: 'frame_preview', label: gettext('PodglÄ…d ram')},
-        {id: 'hierarchy', label: gettext('Hierarchia')},
-        {id: 'notes', label: gettext('Notatki')},
       ],
-      right_pane_tab: this.initialRightPaneTab || 'schemata',
+      right_pane_tab: 'schemata',
       currentPreviewedUnifiedFrameId: this.previewedUnifiedFrameId,
       internalForceRefresh: this.forceRefresh,
       statusButtonTitle: '',
@@ -58,7 +54,7 @@ Object.assign(FreeLuEdit, {
       selectedExamples: null,
       hidden_frames: [],
       hierarchy_hyponyms: null,
-      hierarchy_hyperonyms: null,
+      lexicalUnitsVisible: true,
     }
   },
   components: {FreeLuElement, InfoTooltip, Spinner, FreeLuPreview, SlowalFrameComponent, ExamplesComponent, SemanticsSchemataComponent, MeaningComponent},
@@ -74,203 +70,49 @@ Object.assign(FreeLuEdit, {
     },
   },
   methods: {
-    createHierarchyTree() {
-      return {
-        'unified_frame': this.unified_frame,
-        'hyponyms': this.hierarchy_hyponyms,
-        'hypyronyms': this.hierarchy_hyperonyms
-      };
-    },
-    goToEdit (unifiedFrameId, entryId, lexicalUnitId) {
-      window.location = `/${lang}/entries/unification?unified_frame_id=${this.unified_frame.id}`;
-    },
+      hideLexicalUnits() {
+          this.lexicalUnitsVisible = false;
+      },
+      showLexicalUnits() {
+          this.lexicalUnitsVisible = true;
+      },
     hasWhiteSpace(s) {
       return /\s/g.test(s);
     },
-    async loadFrame() {
-      try {
-        const data = {'unified_frame_id': this.unifiedFrameId, 'no_filters' : false};
-        $.ajax({
-          type: 'post',
-          url: '/' + lang + '/unifier/get_unified_frame/',
-          dataType: 'json',
-          data: data,
-          timeout: 60000,
-          success: function (response) {
-
-            this.img_prefix = window.STATIC_URL;
-            this.lexical_units = this.frames2lexical_units(response.frames);
-            this.unified_frame = response.unified_frame;
-            this.unified_frame_title = this.unified_frame.title;
-            this.unified_frame_arguments = this.unified_frame.arguments;
-            this.frames = response.frames;
-            this.slowal_frames2selecional_preferencies_mapping = slowal_frames2selecional_preferencies(this.unified_frame, response.frames);
+    loadEntry() {
+      $('#lexical-unit-notes').html('');
 
-            this.subentries = response.subentries;
-            this.alternations = response.alternations;
-            this.realisation_phrases = response.realisation_phrases;
-            this.realisation_descriptions = response.realisation_descriptions;
-            this.examples = response.examples;
-
-            this.fulfill_slowal_frames_arguments_with_empty_elems(response.unified_frame, response.frames)
-            window.update_last_visited(response.last_visited);
-            window.clear_info();
+      var data = { 'entry' : this.entryId, 'no_filters' : false, 'lexical_unit_id': this.lexicalUnitId };
+      $.ajax({
+        type     : 'post',
+        url      : '/' + lang + '/entries/get_entry/',
+        dataType : 'json',
+        data     : data,
+        timeout  : 60000,
+        success  : function(response) {
 
-            if (!this.active_slowal_frame) {
-              this.setup_notes_unified_frame();
-            }
-          }.bind(this),
-          error: function (request, errorType, errorMessage) {
-            show_error(errorType + ' (' + errorMessage + ')');
+          window.clear_info();
+          this.frames = response.frames;
+          this.unifiedFrame = response.unified_frame;
+          this.subentries = response.subentries;
+          this.alternations = response.alternations;
+          this.realisation_phrases = response.realisation_phrases;
+          this.realisation_descriptions = response.realisation_descriptions;
+          this.examples = response.examples;
+          this.lexical_units = frames2lexical_units(response.frames);
+          this.free_lexical_units = response.free_lexical_units;
+          if(response.frames_in_building_process.length > 0) {
+              this.frame_in_progress = response.frames_in_building_process[0];
+              this.frame_in_progress_arguments = response.frames_in_building_process[0]['arguments'];
           }
-        });
-        this.loadHierarchy();
-      } catch (error) {
-        console.log(error);
-      }
-    },
-    loadHierarchy() {
-      $.ajax({
-        type: 'post',
-        url: '/' + lang + '/unifier/get_hierarchy_hyponyms/'+this.unifiedFrameId+"/",
-        dataType: 'json',
-        timeout: 60000,
-        success: function (response) {
-          this.hierarchy_hyponyms = response.hyponyms;
-        }.bind(this),
-        error: function (request, errorType, errorMessage) {
-          show_error(errorType + ' (' + errorMessage + ')');
-        }
-      });
 
-      $.ajax({
-        type: 'post',
-        url: '/' + lang + '/unifier/get_hierarchy_hyperonyms/'+this.unifiedFrameId+"/",
-        dataType: 'json',
-        timeout: 60000,
-        success: function (response) {
-          this.hierarchy_hyperonyms = response.hyperonyms;
+          window.update_last_visited(response.last_visited);
         }.bind(this),
-        error: function (request, errorType, errorMessage) {
+        error: function(request, errorType, errorMessage) {
           show_error(errorType + ' (' + errorMessage + ')');
         }
       });
     },
-    setup_notes_unified_frame() {
-      setup_notes($('#notes-component'), $('#lexical-unit-notes-template'), this.unified_frame.id, 'unifier.UnifiedFrame',
-              this.setup_notes_unified_frame, 'hierarchy_frame', true);
-    },
-    unifiedFrameArgumentSelected(argument) {
-      if (this.active_unified_frame_argument === argument) {
-        this.active_unified_frame_argument = null;
-        this.frame_arguments_or_type = false;
-        this.deselectSlowalFrameSelectedElements();
-      } else {
-        this.active_slowal_frame = null;
-        this.active_unified_frame_argument = argument;
-        const slowalFrameArguments = this.getSlowalFrameArgumentsBy(argument);
-        this.frame_arguments_or_type = true;
-        this.deselectSlowalFrameSelectedElements();
-        this.selectedFrameArguments = slowalFrameArguments;
-      }
-      this.unifiedFrameArgumentHovered(argument);
-    },
-    unifiedFrameArgumentHovered(argument) {
-      clear_info();
-      if (argument && this.active_unified_frame_argument === argument) {
-        show_info(gettext('Kliknij, aby cofnąć wybór kolumny do edycji.'));
-      }
-      if (argument && this.active_unified_frame_argument !== argument) {
-        show_info(gettext('Kliknij, aby wybrać kolumnę do edycji.'));
-      }
-    },
-    create_hyponym_or_hyperonym_relation(isHyperonym) {
-      if (this.currentPreviewedUnifiedFrameId === -1) {
-        alert(gettext("Wybierz w oknie podglądu ram ramę, która będzie " + (isHyperonym ? "hiperonimem" : "hiponimem") + " ramy z okna głównego."));
-      } else {
-        const data = isHyperonym ? {'hyponym_id': this.currentPreviewedUnifiedFrameId, 'hyperonym_id': this.unified_frame.id} :
-                {'hyponym_id': this.unified_frame.id, 'hyperonym_id': this.currentPreviewedUnifiedFrameId};;
-        $.ajax({
-          type: 'post',
-          url: '/' + lang + '/unifier/hierarchy_assign/',
-          dataType: 'json',
-          data: data,
-          timeout: 60000,
-          success: function (response) {
-            if(response.succ === 'true') {
-              show_info('Relacja hierarchii została ustanowiona.');
-              this.loadHierarchy();
-              this.$emit('refreshEntriesList');
-            } else if(response.exists === 'true') {
-              alert(gettext("Wybrana relacja hierarchii już występuje."));
-            }
-          }.bind(this),
-          error: function (request, errorType, errorMessage) {
-            show_error(errorType + ' (' + errorMessage + ')');
-          }
-        });
-      }
-    },
-    delete_hyponym_or_hyperonym_relation() {
-      if (this.currentPreviewedUnifiedFrameId === -1) {
-        alert(gettext("Wybierz w oknie podglądu ram ramę, dla której powiązanie ma zostać usunięte."));
-      } else {
-        const data = {'rel1_id': this.currentPreviewedUnifiedFrameId, 'rel2_id': this.unified_frame.id};
-        $.ajax({
-          type: 'post',
-          url: '/' + lang + '/unifier/hierarchy_unassign/',
-          dataType: 'json',
-          data: data,
-          timeout: 60000,
-          success: function (response) {
-            if(response.succ === true) {
-              show_info('Relacja hierarchii została usunięta.');
-              this.loadHierarchy();
-              this.$emit('refreshEntriesList');
-            } else {
-              alert(gettext("Wybrana relacja hierarchii nie występuje."));
-            }
-          }.bind(this),
-          error: function (request, errorType, errorMessage) {
-            show_error(errorType + ' (' + errorMessage + ')');
-          }
-        });
-      }
-    },
-    getSlowalFrameArgumentsBy(unified_frame_argument) {
-      const slowalFrameArgumentIds = [];
-      for (let i in this.unified_frame.slowal_frame_mapping) {
-        const slowal_frame_mapping = this.unified_frame.slowal_frame_mapping[i];
-        const slowalFrame = this.frames.find(frame => frame.id === slowal_frame_mapping.slowal_frame_id);
-        if(slowalFrame != null) {
-          for (let j in slowal_frame_mapping.slowal_frame_argument_mapping) {
-            const slowal_frame_argument_mapping = slowal_frame_mapping.slowal_frame_argument_mapping[j];
-            if (slowal_frame_argument_mapping.unified_frame_agrument_id == unified_frame_argument.id) {
-              const slowalFrameArgument = slowalFrame.arguments.find(arg => arg.argument_id === slowal_frame_argument_mapping.slowal_frame_agrument_id);
-              slowalFrameArgumentIds.push(slowalFrameArgument);
-            }
-          }
-        }
-      }
-      return slowalFrameArgumentIds;
-    },
-    isSuperLeksykograf() {
-      return has_permission("users.view_assignment");
-    },
-    isFrameVerified(frame) {
-      const isSuperLeksykograf = this.isSuperLeksykograf();
-      return (!isSuperLeksykograf && frame.status === 'G') || (isSuperLeksykograf && frame.status === 'S')
-    },
-    select_slowal_frame_req(to_invoke) {
-      if (this.active_slowal_frame) {
-        to_invoke();
-      } else {
-        alert(gettext("Wybierz ramę, dla której chcesz zmienić status."));
-      }
-    },
-    isFrameVisible(status) {
-      return (status != 'B' && status != 'C') || this.isSuperLeksykograf();
-    },
     deselectSlowalFrameSelectedElements() {
       this.subentries.forEach(subentry => {
         subentry.schemata.forEach(s => {
@@ -293,117 +135,94 @@ Object.assign(FreeLuEdit, {
       this.selectedSchemas = [];
       this.selectedExamples = [];
     },
-    slowalFrameSelected(frame) {
-      this.deselectSlowalFrameSelectedElements();
-      if (this.active_slowal_frame === frame) {
-        this.active_slowal_frame = null;
-      } else {
-        this.active_slowal_frame = frame;
-      }
-    },
-    isSelectedFrame(frame) {
-      if (this.active_slowal_frame) {
-        return frame.id === this.active_slowal_frame.id;
-      } else {
-        return false;
-      }
-    },
-    changePreviewedUnifiedFrameId(unifiedFrameId) {
-      this.currentPreviewedUnifiedFrameId = unifiedFrameId;
-    },
-    getArgumentCSS(argument) {
-      return (argument.role ? argument.role.str + ' ' : '') + (argument == this.active_unified_frame_argument ? 'active' : '');
-    },
     schemataSelected(schemas) {
       this.selectedSchemas = schemas;
     },
     exampleSelected(selectedExamples) {
       this.selectedExamples = selectedExamples;
     },
-    isReadOnlyForSuperLeksykograf() {
-      return (this.isSuperLeksykograf() && this.unified_frame.status === 'O') && this.unified_frame.assignee_username !== window.USER_USERNAME;
-    },
-    frames2lexical_units(frames) {
-      const lexical_units = []
-      for (let i in frames) {
-        const frame = frames[i];
-        for (let j in frame.lexical_units) {
-          const lexical_unit = frame.lexical_units[j];
-          lexical_unit.opinion = frame.opinion;
-          lexical_unit.opinion_key = frame.opinion_key;
-          lexical_unit.frame_status = frame.status;
-          lexical_unit.frame = frame;
-          lexical_units.push(lexical_unit);
-        }
-      }
-      return lexical_units;
-    },
-    fulfill_slowal_frames_arguments_with_empty_elems(unified_frame, slowal_frames) {
-      for (let i in unified_frame.slowal_frame_mapping) {
-        const slowal_frame_mapping = unified_frame.slowal_frame_mapping[i];
-        let slowal_frame = slowal_frames.find(o => o.id === slowal_frame_mapping.slowal_frame_id);
-        if(slowal_frame != null) {
-          let new_slowal_frame_arguments = [];
-          for (let j in unified_frame.arguments) {
-            const unified_frame_argument = unified_frame.arguments[j];
-            let unified_frame_argument_mapping = slowal_frame_mapping.slowal_frame_argument_mapping.find(o => o.unified_frame_agrument_id === unified_frame_argument.id);
-            let slowal_frame_argument = null;
-            if (unified_frame_argument_mapping == null) {
-              slowal_frame_argument = {
-                'str': 'Empty',
-                'id': slowal_frame.id + '-_' + (unified_frame_argument.id),
-                'role': 'Empty',
-                'role_type': 'Empty',
-                'preferences': [],
-                'proposed_roles': [],
+      meaningLuSelected(selectedLus) {
+          this.selectedLus = selectedLus;
+      },
+      insideFrameSelectionChanged(selectedFrameArguments) {
+          this.selectedFrameArguments = selectedFrameArguments;
+      },
+      slowalFrameSelected(frame) {
+          this.deselectSlowalFrameSelectedElements();
+          if (this.active_slowal_frame === frame) {
+              this.active_slowal_frame = null;
+          } else {
+              this.active_slowal_frame = frame;
+          }
+      },
+      create_new_slowal_frame() {
+          const lusSelect = function () {
+              return this.free_lexical_units.map(lu => {
+                  return `<label><input type="checkbox" name="lus" value="${lu.pk}" /> ${lu.display}</label><br />`;
+              }).join("");
+          }.bind(this);
+
+          const extract_frames_to_new_frame_popup = {
+              state0: {
+                  title: 'Wybierz jednostki leksykalne',
+                  html: lusSelect,
+                  buttons: {Anuluj: 0, Stwórz: 1},
+                  focus: -1,
+                  submit: function (e, v, m, f) {
+                      if (v == 0) {
+                          e.preventDefault();
+                          $.prompt.close();
+                      }
+                      if (v === 1) {
+                          e.preventDefault();
+                          let lu_ids = normalizeFormData(f.lus);
+                          const data = {
+                              'lu_ids': JSON.stringify(lu_ids),
+                              'entry_id': this.entryId
+                          };
+                          $.ajax({
+                              type: 'post',
+                              url: '/' + lang + '/freelus/create_new_slowal_frame/',
+                              dataType: 'json',
+                              data: data,
+                              timeout: 60000,
+                              success: function (response) {
+                                  show_info('Nowa rama została stworzona.');
+                                  this.loadEntry();
+                                  $.prompt.close();
+                              }.bind(this),
+                              error: function (request, errorType, errorMessage) {
+                                  show_error(errorType + ' (' + errorMessage + ')');
+                                  $.prompt.close();
+                              }
+                          });
+                      }
+                  }.bind(this)
               }
-            } else {
-              slowal_frame_argument = slowal_frame.arguments.find(o => o.argument_id === unified_frame_argument_mapping.slowal_frame_agrument_id);
-            }
-            new_slowal_frame_arguments.push(slowal_frame_argument)
           }
-          slowal_frame.arguments = new_slowal_frame_arguments;
-        }
+          $.prompt(extract_frames_to_new_frame_popup);
       }
-    },
-    createFrameHierarchyRepresentationHTML(unified_frame) {
-
-    },
-    createHierarchyHTML() {
-      this.unified_frame
-    }
   },
   mounted() {
-
-    if(this.unifiedFrameId) {
-      this.loadFrame();
-    }
-
-    if(!this.readOnly) {
-      Split(['#semantics-frames-pane', '#semantics-schemata-pane'], {
-        sizes: [40, 60],
-        minSize: 10,
-        gutterSize: 4,
-        elementStyle: (dimension, size, gutterSize) => {
-          return {
-            'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)'
-          }
-        },
-      });
-      Split(['#semantics-unified-frame-pane', '#examples'], {
-        sizes: [60, 40],
-        direction: 'vertical',
-        gutterSize: 4,
-        minSize: 10,
-      });
-    } else {
-      Split(['#semantics-unified-frame-pane-preview', '#examples-preview'], {
-        sizes: [60, 40],
-        direction: 'vertical',
-        gutterSize: 4,
-        minSize: 10,
-      });
+    if(this.entryId) {
+      this.loadEntry();
     }
+    Split(['#semantics-frames-pane', '#free-lus-schemata-pane'], {
+      sizes: [40, 60],
+      minSize: 10,
+      gutterSize: 4,
+      elementStyle: (dimension, size, gutterSize) => {
+        return {
+          'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)'
+        }
+      },
+    });
+    Split(['#free-lus-pane', '#free-lus-examples'], {
+      sizes: [60, 40],
+      direction: 'vertical',
+      gutterSize: 4,
+      minSize: 10,
+    });
   }
 });
 
@@ -413,123 +232,244 @@ export default FreeLuEdit;
 
 <template>
     <div class="col h-100 px-0 pt-0 pb-0 overflow-auto" id="semantics-frames-pane">
-      <div :id="'semantics-unified-frame-pane' + (readOnly ? '-preview' : '')" class="col w-100 p-0 overflow-auto">
-        <table v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" cellspacing="1">
+      <div id="free-lus-pane" class="col w-100 p-0 overflow-auto">
+        <table class="table-button-menu sticky-top" cellspacing="1">
           <tr style="background-color: white;">
-            <td id="change-title" @click="create_hyponym_or_hyperonym_relation(false)" style="padding: 10px 15px 10px 15px; color: #000000;">Nadrama</td>
-            <td id="add-arg" @click="create_hyponym_or_hyperonym_relation(true)" style="padding: 10px 15px 10px 15px; color: #000000;">Podrama</td>
-            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="delete_hyponym_or_hyperonym_relation">Usuń powiązanie</td>
-            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="goToEdit">Edytuj</td>
+            <td id="create-new-frame" @click="create_new_slowal_frame()" style="padding: 10px 15px 10px 15px; color: #000000;">Nowa rama</td>
+<!--            <td id="add-arg" @click="create_hyponym_or_hyperonym_relation(true)" style="padding: 10px 15px 10px 15px; color: #000000;">Podrama</td>-->
+<!--            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="delete_hyponym_or_hyperonym_relation">Usuń powiązanie</td>-->
+<!--            <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="goToEdit">Edytuj</td>-->
           </tr>
         </table>
         
         <spinner />
         <div align="center">
-        <div align="left" style="display: table;">
-          <div class="unifiedFrame mt-3" v-bind:data-frame_id="unified_frame.id" id="unified-frame-title" v-html="unified_frame_title"></div>
-          <table v-if="unified_frame.id" id="unified-frame" class="m-0 table-borderless border border-secondary text-dark frame active">
-          <tbody>
-            <tr>
-              <template v-for="argument in unified_frame_arguments">
-              <td
-                class="argument py-2 px-1 border-top border-left border-secondary role-column"
-                    :class="getArgumentCSS(argument)"
-                    @click="unifiedFrameArgumentSelected(argument)"
-                    @mouseover="unifiedFrameArgumentHovered(argument)"
-                    @mouseleave="unifiedFrameArgumentHovered(null)"
-                >
-                {{ argument.role_type }}
-                
-                <div
-                  v-if="argument.role"
-                >
-                  [{{ argument.role.str }}]
-                </div>
-                <div v-else>
-                  <ul class="ul-role">
-                    <li v-for="proposed_role in argument.proposed_roles">
-                      {{ proposed_role.str }}
-                    </li>
-                  </ul>
+
+            <div class="lu-table mt-3 mb-3">
+                <table class="m-0 table-borderless text-dark">
+                    <tr><td>
+                        <table class="m-0 border border-secondary text-dark">
+                            <tbody>
+                            <tr>
+                                <th scope="row" class="py-2 px-1 text-secondary">Jednostka leksykalna</th>
+                                <th scope="row" class="py-2 px-1 text-secondary">Opinia</th>
+                                <th scope="row" class="py-2 px-1 text-secondary">Status</th>
+                            </tr>
+                            <tr class="preferences py-0 px-0 border-top border-left border-secondary"
+                                v-if="lexicalUnitsVisible"
+                                v-for='lexical_unit in lexical_units'
+                            >
+                                <!--                  <template v-if="isFrameVisible(lexical_unit.frame_status)">-->
+                                <td class="argument py-2 px-1 border-top border-left border-secondary">{{ lexical_unit.str }}</td>
+                                <td class="argument py-2 px-1 border-top border-left border-secondary">
+                                    <img v-bind:src="img_prefix + 'entries/img/' +lexical_unit.opinion_key + '.svg'" width="12" height="12" v-bind:alt="lexical_unit.opinion">
+                                    {{ lexical_unit.opinion }}
+                                </td>
+                                <td class="argument py-2 px-1 border-top border-left border-secondary">[{{ lexical_unit.frame_status }}]</td>
+                                <!--                  </template>-->
+                            </tr>
+                            </tbody>
+                        </table>
+                    </td>
+                        <td style="vertical-align: text-top; padding-left: 10px; padding-top: 8px; min-width: 50px;">
+                            <span class="cursor-pointer" @click.stop="hideLexicalUnits()" title="Ukryj jednostki leksykalne">&#9652;</span> /
+                            <span class="cursor-pointer" @click.stop="showLexicalUnits()" title="Pokaż jednostki leksykalne">&#9662;</span></td>
+                    </tr>
+                </table>
+            </div>
+
+            <div class="lu-table mt-3 mb-3">
+                <table class="m-0 table-borderless text-dark">
+                    <tr><td>
+                        <table class="m-0 border border-secondary text-dark">
+                            <tbody>
+                            <tr>
+                                <th scope="row" class="py-2 px-1 text-secondary">Wolne jednostki leksykalne</th>
+                            </tr>
+                            <tr class="preferences py-0 px-0 border-top border-left border-secondary"
+                                v-if="lexicalUnitsVisible"
+                                v-for='lexical_unit in free_lexical_units'
+                            >
+                                <td class="argument py-2 px-1 border-top border-left border-secondary">{{ lexical_unit.display }}</td>
+                            </tr>
+                            </tbody>
+                        </table>
+                    </td>
+                        <td style="vertical-align: text-top; padding-left: 10px; padding-top: 8px; min-width: 50px;">
+                            <span class="cursor-pointer" @click.stop="hideLexicalUnits()" title="Ukryj jednostki leksykalne">&#9652;</span> /
+                            <span class="cursor-pointer" @click.stop="showLexicalUnits()" title="Pokaż jednostki leksykalne">&#9662;</span></td>
+                    </tr>
+                </table>
+            </div>
+
+
+
+            <div class="row pt-3" style="flex-wrap: nowrap;" v-if="frame_in_progress">
+                <div class="col pl-5 pr-4">
+                    <div class="row">
+                        <div class="col frame px-0" id="lexical-unit-frame_in_progress">
+                            <meaning-component
+                                    :key="frame_in_progress.lexical_units"
+                                    :lexicalUnits="frame_in_progress.lexical_units"
+                                    :selectedExamples="selectedExamples"
+                                    @meaning-lu-selected="meaningLuSelected"
+                            ></meaning-component>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <div class="col px-0 frame mb-3 active">
+                            <table class="table m-0 table-borderless border border-secondary text-dark">
+                                <tbody>
+                                <tr class="opinion-row">
+                                    <th scope="row" class="py-2 px-1 text-secondary" style="width: 3em;">Opinia</th>
+                                    <td class="opinion-cell py-2 px-1" :colspan="frame_in_progress.arguments.length">
+                                        <table class="table m-0 p-0 table-borderless">
+                                            <tr>
+                                                <td class="opinion-cell p-0">
+                                                    <img :src="'/static/entries/img/' + frame_in_progress.opinion_key + '.svg'" :alt="frame_in_progress.opinion"
+                                                         width="12" height="12"> {{frame_in_progress.opinion}}
+                                                </td>
+                                            </tr>
+                                        </table>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <th scope="row" class="py-2 px-1 text-secondary">Rola</th>
+                                    <template v-for="argument in frame_in_progress.arguments">
+                                        <td class="argument py-2 px-1 border-top border-left border-secondary"
+                                            @mouseenter="argument.hover=true"
+                                            @mouseleave="argument.hover=false"
+                                            @click.stop="selectArgument(argument)"
+                                            :class="computeArgumentCSS(argument)"
+                                        >
+                                            {{argument.str}}
+                                        </td>
+                                    </template>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
                 </div>
-              </td>
-              </template>
-              
-              
-            </tr>
-            <tr>
-              <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'
-              >
-                <ul class="ul-preference" v-if="argument.preferences.length > 0">
-                  <li v-for='preference in argument.preferences'>
-                    <div
-                      v-if="preference.url != null"
-                      class="preference py-2 px-1 preference-bold"
-                    >
-                      <a class="synset-plwn" v-bind:href="preference.url" target="_blank">{{ preference.str }}</a>
+            </div>
+
+
+
+
+
+<!--            <div v-if="frame_in_progress" align="left" style="display: table;">-->
+<!--&lt;!&ndash;                <div class="unifiedFrame mt-3" v-if="frame_in_progress" v-bind:data-frame_id="frame_in_progress.id" id="unified-frame-title"></div>&ndash;&gt;-->
+<!--                <table v-if="frame_in_progress.id" id="unified-frame-opac" class="table-borderless">-->
+<!--                    <tr><td>-->
+<!--                        <table id="unified-frame" class="m-0 table-borderless border border-secondary text-dark frame active">-->
+<!--                            <tbody>-->
+<!--                                <tr>-->
+<!--                                    <th scope="row" class="py-2 px-1 text-secondary role-header">Role</th>-->
+
+<!--                                    <template v-for="argument in frame_in_progress_arguments">-->
+<!--                                        <td-->
+<!--                                                class="argument py-2 px-1 border-top border-left border-secondary role-column"-->
+<!--                                                :class="getArgumentCSS(argument)"-->
+<!--                                                @click="unifiedFrameArgumentSelected(argument)"-->
+<!--                                                @mouseover="unifiedFrameArgumentHovered(argument)"-->
+<!--                                                @mouseleave="unifiedFrameArgumentHovered(null)"-->
+<!--                                        >-->
+<!--                                            <span style="font-size: 0.8rem;">{{ roleStrMapping(argument.role_type) }}</span>-->
+<!--                                            <div-->
+<!--                                                    v-if="argument.role"-->
+<!--                                            >-->
+<!--                                                [{{ argument.role.str }}]-->
+<!--                                            </div>-->
+<!--                                            <div v-else>-->
+<!--                                                <ul class="ul-role">-->
+<!--                                                    <li v-for="proposed_role in argument.proposed_roles">-->
+<!--                                                        {{ proposed_role.str }}-->
+<!--                                                    </li>-->
+<!--                                                </ul>-->
+<!--                                            </div>-->
+<!--                                        </td>-->
+<!--                                    </template>-->
+
+
+<!--                                </tr>-->
+<!--                            </tbody>-->
+<!--                        </table>-->
+<!--                    </td></tr>-->
+<!--                </table>-->
+<!--            </div>-->
+
+
+            <div id="semantics-frames">
+                <template v-for="frame in frames">
+                    <div class="row pt-3" style="flex-wrap: nowrap;">
+                        <div class="col pl-5 pr-4">
+                            <div class="row">
+                                <div class="col frame px-0" id="lexical-unit">
+                                    <meaning-component
+                                            :key="frame.lexical_units"
+                                            :lexicalUnits="frame.lexical_units"
+                                            :selectedExamples="selectedExamples"
+                                            @meaning-lu-selected="meaningLuSelected"
+                                    ></meaning-component>
+                                </div>
+                            </div>
+                            <div class="row">
+                                <div class="col px-0 frame mb-3 active"
+                                     @mouseenter="frame.hover=true"
+                                     @mouseleave="frame.hover=false"
+                                     @click="slowalFrameSelected(frame)"
+                                     :class="frame === active_slowal_frame ? 'active-frame' : frame.hover ? 'bg-highlight' : ''" >
+                                    <slowal-frame-component
+                                            :frame="frame"
+                                            :key="frame"
+                                            :selectedExamples="selectedExamples"
+                                            @frame-selection-changed="insideFrameSelectionChanged"
+                                    />
+                                </div>
+                            </div>
+                        </div>
+<!--                        <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="col pl-0 pt-4" style="max-width: 60px;">-->
+<!--                            <div class="row"></div>-->
+<!--                            <div class="row">-->
+<!--                                <div class="col">-->
+<!--&lt;!&ndash;                                    <button v-if="!isFrameVerified(frame)"&ndash;&gt;-->
+<!--&lt;!&ndash;                                            class="btn btn-sm btn-dark px-2 py-0" role="button"&ndash;&gt;-->
+<!--&lt;!&ndash;                                            style="font-size: 20px; min-width: 35px"&ndash;&gt;-->
+<!--&lt;!&ndash;                                            @click="change_slowal2unified_frame_argument_mapping(frame)"&ndash;&gt;-->
+<!--&lt;!&ndash;                                            title="Zamień wybrane argumenty ramy"&ndash;&gt;-->
+<!--&lt;!&ndash;                                    >Z</button>&ndash;&gt;-->
+<!--                                </div>-->
+<!--                            </div>-->
+<!--                            <div class="row">-->
+<!--                                <div v-if="isFrameVerified(frame)" class="col pl-1" style="display: flex;">-->
+<!--                                    <input-->
+<!--                                            type="checkbox"-->
+<!--                                            :checked="isFrameVerified(frame)"-->
+<!--                                            class="custom-control custom-checkbox ok-checkbox"-->
+<!--                                    >-->
+<!--                                </div>-->
+<!--                            </div>-->
+<!--                        </div>-->
                     </div>
-                    <div v-else class="preference py-2 px-1 preference-bold">{{ preference.str }}</div>
-                  </li>
-                </ul>
-                <ul class="ul-preference" v-if="unified_frame.status !== 'S'">
-                  <li v-for="preference in slowal_frames2selecional_preferencies_mapping[argument.id]">
-                    <span v-if="preference.url != null" class="preference py-2 px-1">
-                      <a class="synset-plwn" v-bind:href="preference.url" target="_blank">{{ preference.str }}</a>
-                    </span>
-                    <span v-else class="preference py-2 px-1">{{ preference.str }}</span>
-                    <info-tooltip v-if="preference.info" :text="preference.info" />
-                  </li>
-                </ul>
-              </td>
-            </tr>
-          </tbody>
-        </table>
+                </template>
+            </div>
+
         </div>
-        <div v-if="unified_frame.id" class="lu-table mt-3 mb-3">
-            <table class="m-0 table-borderless border border-secondary text-dark">
-              <tbody>
-                <tr>
-                  <th scope="row" class="py-2 px-1 text-secondary">Jednostka leksykalna</th>
-                  <th scope="row" class="py-2 px-1 text-secondary">Opinia</th>
-                  <th scope="row" class="py-2 px-1 text-secondary">Status</th>
-                </tr>
-                <tr class="preferences py-0 px-0 border-top border-left border-secondary"
-                  v-for='lexical_unit in lexical_units'
-                >
-                  <template v-if="isFrameVisible(lexical_unit.frame)">
-                    <td class="cursor-pointer argument py-2 px-1 border-top border-left border-secondary"
-                        @mouseenter="lexical_unit.frame.hover=true"
-                        @mouseleave="lexical_unit.frame.hover=false"
-                        :class="lexical_unit.frame === active_slowal_frame ? 'active-lu' : lexical_unit.frame.hover ? 'lu-underline' : ''"
-                        @click="slowalFrameSelected(lexical_unit.frame)">{{ lexical_unit.str }}</td>
-                    <td class="argument py-2 px-1 border-top border-left border-secondary">
-                      <img v-bind:src="img_prefix + 'entries/img/' +lexical_unit.opinion_key + '.svg'" width="12" height="12" v-bind:alt="lexical_unit.opinion">
-                      {{ lexical_unit.opinion }}
-                    </td>
-                    <td class="argument py-2 px-1 border-top border-left border-secondary">[{{ lexical_unit.frame_status }}]</td>
-                  </template>
-                </tr>
-              </tbody>
-            </table>
-          </div>
-      </div>
-      </div>
-      <div :id="'examples' + (readOnly ? '-preview' : '')" class="col w-100 p-0 tab-pane overflow-auto">
-         <examples-component v-if="examples"
-              :examples="examples" 
-              :frame="active_slowal_frame"
-              :frame_arguments="selectedFrameArguments"
-              :frame_arguments_or_type="frame_arguments_or_type"
-              :lus="selectedLus"
-              :schemas="selectedSchemas"
-              :key="examples"
-              @example-selected="exampleSelected"
-          />
+        </div>
+        <div id="free-lus-examples" class="col w-100 p-0 tab-pane overflow-auto">
+           <examples-component v-if="examples"
+                :examples="examples"
+                :frame="active_slowal_frame"
+                :frame_arguments="selectedFrameArguments"
+                :frame_arguments_or_type="frame_arguments_or_type"
+                :lus="selectedLus"
+                :schemas="selectedSchemas"
+                :key="examples"
+                @example-selected="exampleSelected"
+            />
         </div>
     </div>
-    <div v-if="!readOnly" class="col h-100 px-1 pt-0 pb-0 overflow-auto" style="padding-left: 0px!important; padding-right: 0px!important;" id="semantics-schemata-pane">
+    <div class="col h-100 px-1 pt-0 pb-0 overflow-auto" style="padding-left: 0px!important; padding-right: 0px!important;" id="free-lus-schemata-pane">
       <ul class="nav nav-pills nav-justified p-1" id="entryTabs" role="tablist">
         <li
           v-for="tab in right_pane_tabs"
@@ -540,7 +480,7 @@ export default FreeLuEdit;
           {{ tab.label }}
         </li>
       </ul>
-      <div v-if="active_slowal_frame" :class="right_pane_tab !== 'schemata' && 'd-none'">
+      <div :class="right_pane_tab !== 'schemata' && 'd-none'">
           <semantics-schemata-component 
                 :subentries="subentries"
                 :key="subentries"
diff --git a/frontend/src/components/unification/free_lu/FreeLuRightPane.vue b/frontend/src/components/unification/free_lu/FreeLuRightPane.vue
index 8372acd..0aa7d04 100644
--- a/frontend/src/components/unification/free_lu/FreeLuRightPane.vue
+++ b/frontend/src/components/unification/free_lu/FreeLuRightPane.vue
@@ -51,15 +51,13 @@ export default {
 </script>
 
 <template>
-  <div v-if="key || unifiedFrameId" :key="(key, entryIdLocal, unifiedFrameId)" class="row h-100 m-0 p-0 overflow-auto" id="semantics-top-pane">
+  <div v-if="key || entryId" :key="(key, entryIdLocal, unifiedFrameId)" class="row h-100 m-0 p-0 overflow-auto" id="semantics-top-pane">
     <free-lu-edit
       ref="hierarchyEdit"
-      v-if="unifiedFrameId"
-      :key="unifiedFrameId"
+      v-if="entryId"
+      :key="entryId"
       :readOnly="false"
-      :unifiedFrameId="unifiedFrameId"
-      :previewedUnifiedFrameId="previewedUnifiedFrameId"
-      :initialRightPaneTab="previewedUnifiedFrameId && unifiedFrameId !== previewedUnifiedFrameId ? 'frame_preview' : 'schemata'"
+      :entryId="entryId"
       @go-to-display="goToDisplay"
       @swap-frames="swapFrames"
       @refresh-entries-list="refreshEntriesList"
diff --git a/frontend/src/components/unification/free_lu/FreeLusList.vue b/frontend/src/components/unification/free_lu/FreeLusList.vue
new file mode 100644
index 0000000..109bc9d
--- /dev/null
+++ b/frontend/src/components/unification/free_lu/FreeLusList.vue
@@ -0,0 +1,60 @@
+<script>
+export default {
+  data() {
+    return {
+      gettext: window.gettext,
+      canViewAssignment: has_permission("users.view_assignment")
+    }
+  },
+  methods: {
+    reset_list() {
+      this.$emit('unifiedFrameSelected', null);
+      setup_free_lus_list({
+        table: this.$refs.framestable,
+        entrySelected: (entryId) => {
+          this.$emit('entrySelected', entryId);
+        },
+        selectEntryId: this.initialUnifiedFrameId,
+      });
+    }
+  },
+  watch: {
+    unificationEntriesListRefreshKey() {
+      // TODO: reload data and click in selected row
+      // this.datatableObject.ajax.reload();
+      setup_free_lus_list({
+        table: this.$refs.framestable,
+        entrySelected: (entryId) => {
+          this.$emit('entrySelected', entryId);
+        },
+        selectEntryId: this.initialUnifiedFrameId,
+      });
+    }
+  },
+  emits: ['entrySelected'],
+  mounted() {
+    this.$.appContext.config.globalProperties.$entries_list = this;
+    setup_free_lus_list({
+      table: this.$refs.framestable,
+      entrySelected: (entryId) => {
+        this.$emit('entrySelected', entryId);
+      },
+      selectEntryId: this.initialUnifiedFrameId,
+    });
+  },
+};
+</script>
+
+<template>
+  <table ref="framestable" class="table table-sm table-hover text-dark">
+    <thead>
+      <tr>
+        <th class="p-1">{{ gettext('Hasło') }}</th>
+        <th class="p-1">{{ gettext('Status') }}</th>
+        <th class="p-1" hidden="true">{{ gettext('Id') }}</th>
+      </tr>
+    </thead>
+    <tbody id="free-entries">
+    </tbody>
+  </table>
+</template>
diff --git a/frontend/src/components/unification/shared/frame-components/SemanticsSchemataComponent.vue b/frontend/src/components/unification/shared/frame-components/SemanticsSchemataComponent.vue
index fef1136..3c5306c 100644
--- a/frontend/src/components/unification/shared/frame-components/SemanticsSchemataComponent.vue
+++ b/frontend/src/components/unification/shared/frame-components/SemanticsSchemataComponent.vue
@@ -36,14 +36,14 @@
             },
             getRealisationDescriptions(schema, alternation_id) {
                 const alternationDescList = [];
-                if (this.alternations) {
+                if (this.alternations && this.frame) {
                     alternationDescList.push(this.realisation_descriptions[this.frame.id][schema.id][alternation_id]);
                 }
                 return '<i>' + alternationDescList + '</i>';
             },
             getPhraseCss(position, alternation) {
                 const styles = [];
-                if (this.alternations) {
+                if (this.alternations && this.frame) {
                     const argumentIdSet = new Set();
 
                     for (let arg_id in alternation) {
@@ -70,12 +70,12 @@
                 return styles;
             },
             getAlternation(schema, alternation) {
-                const r = this.alternations[this.frame.id][schema.id][alternation];
+                const r = this.frame ? this.alternations[this.frame.id][schema.id][alternation] : null;
                 return r;
             },
             getPositionPhrases(curr_alternations, index, curr_phrase_id) {
                 const phrases = [];
-                if (this.alternations) {
+                if (this.alternations && this.frame) {
                     for (let i in curr_alternations) {
                         const alternation = curr_alternations[i]
 
@@ -105,6 +105,8 @@
         },
         mounted() {
             this.img_prefix = window.STATIC_URL;
+            // let subentries = this.subentries;
+            // console.log("subentries.lenght: "+subentries.lenght);
         },
     };
 </script>
@@ -116,7 +118,6 @@
                 <div class="mb-1 sticky-top"><h5 class="bg-dark text-light p-1">{{subentry.str}}</h5></div>
                 <template v-for="schema in subentry.schemata">
                     <div class="schema mb-3"
-                         v-if="this.frame && alternations[this.frame.id][schema.id]"
                          @mouseenter="schema.hover=true"
                          @mouseleave="schema.hover=false"
                          @click="selectSchema(schema)"
@@ -144,21 +145,37 @@
 
                             </tr>
 
-                            <template v-for="(alternation, index) in this.alternations[this.frame.id][schema.id]">
+                            <template v-if="this.frame" >
+                                <template v-for="(alternation, index) in this.alternations[this.frame.id][schema.id]">
+                                    <tr class="realisation-description">
+                                        <td class="px-1 py-2" :colspan="getSchemataPositionCnt(schema)"
+                                            v-html="getRealisationDescriptions(schema, index)"></td>
+                                    </tr>
+                                    <tr class="phrase-types alt-0">
+                                        <th scope="row" class="py-0 px-1 text-secondary">Typy fraz</th>
+                                        <td v-for="position in schema.positions" class="px-0 py-0 border-top border-left border-secondary">
+                                            <template v-for="phrase in position.phrases">
+                                                <div class="phrase px-1 py-2"
+                                                     :class="getPhraseCss(position, alternation)">
+                                                    <info-tooltip :text="phrase.desc" :visibleText="phrase.str"/>
+                                                </div>
+                                                <div v-for="phrase in getPositionPhrases(alternation, index, phrase.id)" class="realisation-phrase px-1 py-2"><i>{{phrase}}</i></div>
+                                            </template>
+                                        </td>
+                                    </tr>
+                                </template>
+                            </template>
+                            <template v-else>
                                 <tr class="realisation-description">
-                                    <td class="px-1 py-2" :colspan="getSchemataPositionCnt(schema)"
-                                        v-html="getRealisationDescriptions(schema, index)"></td>
+                                    <td class="px-1 py-2" :colspan="getSchemataPositionCnt(schema)" v-html="getRealisationDescriptions(schema)"></td>
                                 </tr>
                                 <tr class="phrase-types alt-0">
                                     <th scope="row" class="py-0 px-1 text-secondary">Typy fraz</th>
                                     <td v-for="position in schema.positions" class="px-0 py-0 border-top border-left border-secondary">
-                                        <template v-for="phrase in position.phrases">
-                                            <div class="phrase px-1 py-2"
-                                                 :class="getPhraseCss(position, alternation)">
-                                                <info-tooltip :text="phrase.desc" :visibleText="phrase.str"/>
-                                            </div>
-                                            <div v-for="phrase in getPositionPhrases(alternation, index, phrase.id)" class="realisation-phrase px-1 py-2"><i>{{phrase}}</i></div>
-                                        </template>
+                                        <div v-for="phrase in position.phrases" class="phrase px-1 py-2"
+                                             :class="getPhraseCss(position, null)">
+                                            <info-tooltip :text="phrase.desc" :visibleText="phrase.str"/>
+                                        </div>
                                     </td>
                                 </tr>
                             </template>
diff --git a/frontend/src/components/unification/shared/utils.js b/frontend/src/components/unification/shared/utils.js
index 2c69dd2..0a3a8de 100644
--- a/frontend/src/components/unification/shared/utils.js
+++ b/frontend/src/components/unification/shared/utils.js
@@ -55,8 +55,24 @@ function send_post_request_with_timeout(path, data, succ_func, err_func, timeout
   });
 }
 
+function frames2lexical_units(frames) {
+  const lexical_units = []
+  for (let i in frames) {
+    const frame = frames[i];
+    for (let j in frame.lexical_units) {
+      const lexical_unit = frame.lexical_units[j];
+      lexical_unit.opinion = frame.opinion;
+      lexical_unit.opinion_key = frame.opinion_key;
+      lexical_unit.frame_status = frame.status;
+      lexical_units.push(lexical_unit);
+    }
+  }
+  return lexical_units;
+}
+
 export {
   slowal_frames2selecional_preferencies,
   send_post_request,
-  send_post_request_with_timeout
+  send_post_request_with_timeout,
+  frames2lexical_units
 };
diff --git a/importer/WalentyXML.py b/importer/WalentyXML.py
index 4978ae4..3c70a4e 100644
--- a/importer/WalentyXML.py
+++ b/importer/WalentyXML.py
@@ -75,7 +75,7 @@ class WalentyTeiHandler(handler.ContentHandler):
                 base = self._subtree._children[0]._children[0]._content
                 try:
                     entry = Entry(self._subtree, self._entry_meanings, self._meanings, self._frames, self._examples_in, self._examples_out, self._misconnected_out)
-                    if entry._status == '(S) sprawdzone' or entry._status == '(S) gotowe':
+                    if entry._status == '(S) sprawdzone' or entry._status == 'sprawdzone' or entry._status == '(S) gotowe':
                         entry.store(self._meanings, self._stored_positions)
                     else:
                         print("Odrzucono niegotowe: {}, status: {}".format(entry._base, entry._status))
diff --git a/semantics/models.py b/semantics/models.py
index 6542ce3..18240b1 100644
--- a/semantics/models.py
+++ b/semantics/models.py
@@ -16,6 +16,7 @@ class Frame(models.Model):
         default=choices.FrameStatus.NEW,
     )
     assignments = GenericRelation("users.Assignment", content_type_field="subject_ct", object_id_field="subject_id")
+    in_building = models.BooleanField(default=False)
 
     def sorted_arguments(self):  # TODO: zaimplementowac wlasciwe sortowanie
         return Argument.objects.filter(frame=self)
diff --git a/shellvalier/urls.py b/shellvalier/urls.py
index 7c54156..2d79020 100644
--- a/shellvalier/urls.py
+++ b/shellvalier/urls.py
@@ -19,6 +19,7 @@ urlpatterns = i18n_patterns(
     path('semantics/', include('semantics.urls')),
     path('unifier/', include('unifier.urls')),
     path('financial_settlement/', include('financial_settlement.urls')),
+    path('freelus/', include('freelus.urls')),
     path('', dash, name='dash'),
     # uncomment to leave default (Polish) urls unchanged
     #prefix_default_language=False,
diff --git a/syntax/management/commands/add_predefined_preferences.py b/syntax/management/commands/add_predefined_preferences.py
index cee1119..4f4bc22 100644
--- a/syntax/management/commands/add_predefined_preferences.py
+++ b/syntax/management/commands/add_predefined_preferences.py
@@ -299,10 +299,10 @@ def create_predefined_preferences():
                                          sense='1',
                                          pos='noun').synset
     sytuacja_members.synsets.add(ciąg_zdarzeń_1)
-    czasownik_1 = LexicalUnit.objects.get(base='CZASOWNIK',
-                                         sense='1',
-                                         pos='noun').synset
-    sytuacja_members.synsets.add(czasownik_1)
+    # czasownik_1 = LexicalUnit.objects.get(base='CZASOWNIK',
+    #                                      sense='1',
+    #                                      pos='noun').synset
+    # sytuacja_members.synsets.add(czasownik_1)
     sytuacja_members.save()
     # SYTUACJA ==> czynność-1, zdarzenie-2, okoliczność-1, ciąg zdarzeń-1
     sytuacja, xx = PredefinedSelectionalPreference.objects.get_or_create(name='SYTUACJA',
-- 
GitLab