From eea8354ed2c9629e5f3c731c6630324fa2e5fc21 Mon Sep 17 00:00:00 2001 From: dcz <dcz@ipipan.waw.pl> Date: Tue, 14 Nov 2023 12:44:42 +0100 Subject: [PATCH] Final stage of vertical relations. --- entries/static/entries/css/entries.css | 4 + .../static/entries/css/unification_frames.css | 4 + entries/static/entries/js/entries.js | 16 + .../entries/js/unification_frames_list.js | 9 +- .../Unification/UnificationFramesList.vue | 14 +- .../frame-components/SlowalFrameComponent.vue | 190 ++-- .../vertical_relations/VerticalRelation.vue | 8 +- .../VerticalRelationEdit.vue | 947 +++++++++++++++--- .../VerticalRelationRightPane.vue | 3 +- syntax/management/commands/import_tei.py | 13 +- unifier/models.py | 2 + unifier/views.py | 43 +- vertical_relations/models.py | 60 +- vertical_relations/urls.py | 12 + vertical_relations/views.py | 309 +++++- 15 files changed, 1308 insertions(+), 326 deletions(-) diff --git a/entries/static/entries/css/entries.css b/entries/static/entries/css/entries.css index 55067e2..388783c 100644 --- a/entries/static/entries/css/entries.css +++ b/entries/static/entries/css/entries.css @@ -281,6 +281,10 @@ legend { background-color: rgba(138, 11, 17, 0.14) !important; } +.vertical_rel_not_exists { + background-color: rgba(61, 22, 87, 0.14) !important; +} + .table-primary, .table-primary>td, .table-primary>th { diff --git a/entries/static/entries/css/unification_frames.css b/entries/static/entries/css/unification_frames.css index 5b851fa..42c6c4b 100644 --- a/entries/static/entries/css/unification_frames.css +++ b/entries/static/entries/css/unification_frames.css @@ -31,6 +31,10 @@ table.table-button-menu { background-color: #dee1e4; } +#target-unified-frame .argument.active { + background-color: #dee1e4; +} + #free-lus-frame .argument.active { background-color: black; } diff --git a/entries/static/entries/js/entries.js b/entries/static/entries/js/entries.js index da416ee..3236b7c 100644 --- a/entries/static/entries/js/entries.js +++ b/entries/static/entries/js/entries.js @@ -15,6 +15,7 @@ var role_sub_attributes = [] var frame_opinions = [] var main_vertical_relations = [] var temporal_vertical_relations = [] +var vertical_relation_negations = [] function make_opinion_row(item, span, width) { const opinion_row = document.createElement('tr'); @@ -1011,6 +1012,9 @@ function setup_datatable(options) { if (options.setup_hierarchy_marking === true && data.hierarchy_exists !== true) { $(row).addClass('hierarchy_not_exists'); } + if (options.setup_vertical_rel_marking === true && data.has_vertical_relations !== true) { + $(row).addClass('vertical_rel_not_exists'); + } if(!options.disable_display_graphical_status) { for (let i in options.columns) { @@ -1169,6 +1173,16 @@ function getTemporalVerticalRelations() { }); } +function getVerticalRelationNegations() { + $.ajax({ + dataType: "json", + url: '/' + lang + '/vertical_relations/ajax_vertical_relation_negations', + success: function(data){ + vertical_relation_negations = data.negations; + }, + async: false + }); +} $(document).ready(function() { bind_last_visited(); @@ -1209,6 +1223,8 @@ $(document).ready(function() { getTemporalVerticalRelations(); + getVerticalRelationNegations(); + // $.getJSON('relations', function(data){ // memorizeRelations(data.relations); // }); diff --git a/entries/static/entries/js/unification_frames_list.js b/entries/static/entries/js/unification_frames_list.js index 45c2e25..80c9a7c 100644 --- a/entries/static/entries/js/unification_frames_list.js +++ b/entries/static/entries/js/unification_frames_list.js @@ -8,7 +8,11 @@ function setup_frames_list(options) { ) ? gettext("tak") : gettext("nie"); } - const ajaxURL = can_see_assignees ? '/' + lang + '/unifier/get_unified_frames/' : '/' + lang + '/unifier/get_unified_frames/?exclude_status=N&restrict_to_user='+window.USER_USERNAME; + let ajaxURL = can_see_assignees ? '/' + lang + '/unifier/get_unified_frames/' : '/' + lang + '/unifier/get_unified_frames/?exclude_status=N&restrict_to_user='+window.USER_USERNAME; + + if(options.include_unified_frame_status) { + ajaxURL += '?include_status=' + options.include_unified_frame_status; + } const datatable = setup_datatable({ element: options.table, @@ -21,7 +25,8 @@ function setup_frames_list(options) { ], hidden_columns: can_see_assignees ? [3] : [2,3], selectEntryId: options.selectEntryId, - setup_hierarchy_marking: options.setupHierarchyMarking + setup_hierarchy_marking: options.setupHierarchyMarking, + setup_vertical_rel_marking: options.setup_vertical_rel_marking }); datatable.on('click', 'tr.entry', function () { const data = datatable.row(this).data(); diff --git a/frontend/src/components/unification/Unification/UnificationFramesList.vue b/frontend/src/components/unification/Unification/UnificationFramesList.vue index 47be0f7..542337a 100644 --- a/frontend/src/components/unification/Unification/UnificationFramesList.vue +++ b/frontend/src/components/unification/Unification/UnificationFramesList.vue @@ -4,6 +4,8 @@ export default { initialUnifiedFrameId: Number, unificationEntriesListRefreshKey: Number, setupHierarchyMarking: Boolean, + setup_vertical_rel_marking: Boolean, + include_unified_frame_status: String }, data() { return { @@ -20,7 +22,9 @@ export default { this.$emit('unifiedFrameSelected', unifiedFrameId); }, selectEntryId: this.initialUnifiedFrameId, - setupHierarchyMarking: this.setupHierarchyMarking + setupHierarchyMarking: this.setupHierarchyMarking, + setup_vertical_rel_marking: this.setup_vertical_rel_marking, + include_unified_frame_status: this.include_unified_frame_status }); } }, @@ -34,7 +38,9 @@ export default { this.$emit('unifiedFrameSelected', unifiedFrameId); }, selectEntryId: this.initialUnifiedFrameId, - setupHierarchyMarking: this.setupHierarchyMarking + setupHierarchyMarking: this.setupHierarchyMarking, + setup_vertical_rel_marking: this.setup_vertical_rel_marking, + include_unified_frame_status: this.include_unified_frame_status }); } }, @@ -47,7 +53,9 @@ export default { this.$emit('unifiedFrameSelected', unifiedFrameId); }, selectEntryId: this.initialUnifiedFrameId, - setupHierarchyMarking: this.setupHierarchyMarking + setupHierarchyMarking: this.setupHierarchyMarking, + setup_vertical_rel_marking: this.setup_vertical_rel_marking, + include_unified_frame_status: this.include_unified_frame_status }); }, }; diff --git a/frontend/src/components/unification/shared/frame-components/SlowalFrameComponent.vue b/frontend/src/components/unification/shared/frame-components/SlowalFrameComponent.vue index c1f06ae..7de9f38 100644 --- a/frontend/src/components/unification/shared/frame-components/SlowalFrameComponent.vue +++ b/frontend/src/components/unification/shared/frame-components/SlowalFrameComponent.vue @@ -1,102 +1,104 @@ <script> -import InfoTooltip from "/src/components/shared/InfoTooltip.vue"; + import InfoTooltip from "/src/components/shared/InfoTooltip.vue"; -export default { - props: { - frame: Object, - selectedExamples: Object, - }, - components: {InfoTooltip}, - emits: ['frameSelectionChanged'], - data() { - return { - img_prefix: window.STATIC_URL, - selectionalPreferenciesShow: Boolean - } - }, - methods: { - getTitleHTML() { - const ret = window.lexical_units2dom(this.frame.lexical_units); - return ret; - }, - getArguments() { - return this.frame.arguments; - }, - selectArgument(argument) { - argument.selected = !argument.selected; - const selectedArguments = this.frame.arguments.filter(argument => argument.selected) - this.$emit('frameSelectionChanged', selectedArguments); - }, - computeArgumentCSS(argument) { - const selectedExampleFrameArguments = this.selectedExamples && this.selectedExamples.length > 0 ? new Set(this.selectedExamples.map(e => e.argument_ids).flat()) : null; - return argument.role + ' ' + (argument.selected ? 'active' : argument.hover ? 'bg-highlight' : '') - + (selectedExampleFrameArguments != null ? selectedExampleFrameArguments.has(argument.id) ? 'example-yes' : 'example-no' : ''); - }, - hideSelectionalPreferencies() { - this.selectionalPreferenciesShow = false; - }, - showSelectionalPreferencies() { - this.selectionalPreferenciesShow = true; - } - }, - mounted() { - this.img_prefix = window.STATIC_URL; - }, -}; + export default { + props: { + frame: Object, + selectedExamples: Object, + }, + components: {InfoTooltip}, + emits: ['frameSelectionChanged'], + data() { + return { + img_prefix: window.STATIC_URL, + selectionalPreferenciesShow: Boolean + } + }, + methods: { + getTitleHTML() { + const ret = window.lexical_units2dom(this.frame.lexical_units); + return ret; + }, + getArguments() { + return this.frame.arguments; + }, + selectArgument(argument) { + argument.selected = !argument.selected; + const selectedArguments = this.frame.arguments.filter(argument => argument.selected) + this.$emit('frameSelectionChanged', selectedArguments); + }, + computeArgumentCSS(argument) { + const selectedExampleFrameArguments = this.selectedExamples && this.selectedExamples.length > 0 ? new Set(this.selectedExamples.map(e => e.argument_ids).flat()) : null; + return argument.role + ' ' + (argument.selected ? 'active' : argument.hover ? 'bg-highlight' : '') + + (selectedExampleFrameArguments != null ? selectedExampleFrameArguments.has(argument.id) ? 'example-yes' : 'example-no' : ''); + }, + hideSelectionalPreferencies() { + this.selectionalPreferenciesShow = false; + }, + showSelectionalPreferencies() { + this.selectionalPreferenciesShow = true; + } + }, + mounted() { + this.img_prefix = window.STATIC_URL; + }, + }; </script> <template> - <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.arguments.length"> - <table class="table m-0 p-0 table-borderless"> - <tr> - <td class="opinion-cell p-0"> - <img :src="'/static/entries/img/' + frame.opinion_key + '.svg'" :alt="frame.opinion" - width="12" height="12"> {{frame.opinion}} - </td> - <td class="opinion-cell p-0" style="text-align: right;"> - <span class="cursor-pointer" @click.stop="hideSelectionalPreferencies()" title="Ukryj preferencje selekcyjne">▴</span> / - <span class="cursor-pointer" @click.stop="showSelectionalPreferencies()" title="Pokaż preferencje selekcyjne">▾</span></td> - </tr> - </table> - </td> - </tr> - <tr> - <th scope="row" class="py-2 px-1 text-secondary">Rola</th> - <template v-for="argument in frame.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> - <tr v-if="selectionalPreferenciesShow"> - <th scope="row" class="py-0 px-1 text-secondary">Preferencje selekcyjne</th> - <template v-for="argument in getArguments()"> - - <td class="preferences py-0 px-0 border-top border-left border-secondary" - :class="argument.selected ? 'active' : argument.hover ? 'bg-highlight' : ''" - > - <template v-if="argument.preferences.length > 0" v-for='preference in argument.preferences'> - <div - 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> - <info-tooltip v-if="preference.info" :text="'definicja: <i>'+ preference.info +'</i>'" /> - </div> - <div v-else class="preference py-2 px-1">{{ preference.str }}</div> - </template> + <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.arguments.length"> + <table class="table m-0 p-0 table-borderless"> + <tr> + <td class="opinion-cell p-0"> + <img :src="'/static/entries/img/' + frame.opinion_key + '.svg'" :alt="frame.opinion" + width="12" height="12"> {{frame.opinion}} </td> + <td class="opinion-cell p-0" style="text-align: right;"> + <span class="cursor-pointer" @click.stop="hideSelectionalPreferencies()" + title="Ukryj preferencje selekcyjne">▴</span> / + <span class="cursor-pointer" @click.stop="showSelectionalPreferencies()" + title="Pokaż preferencje selekcyjne">▾</span></td> + </tr> + </table> + </td> + </tr> + <tr> + <th scope="row" class="py-2 px-1 text-secondary">Rola</th> + <template v-for="argument in frame.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> + <tr v-if="selectionalPreferenciesShow"> + <th scope="row" class="py-0 px-1 text-secondary">Preferencje selekcyjne</th> + <template v-for="argument in getArguments()"> + + <td class="preferences py-0 px-0 border-top border-left border-secondary" + :class="argument.selected ? 'active' : argument.hover ? 'bg-highlight' : ''" + > + <template v-if="argument.preferences.length > 0" v-for='preference in argument.preferences'> + <div + 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> + <info-tooltip v-if="preference.info" :text="'definicja: <i>'+ preference.info +'</i>'"/> + </div> + <div v-else class="preference py-2 px-1">{{ preference.str }}</div> </template> - </tr> - </tbody> - </table> + </td> + </template> + </tr> + </tbody> + </table> </template> diff --git a/frontend/src/components/unification/vertical_relations/VerticalRelation.vue b/frontend/src/components/unification/vertical_relations/VerticalRelation.vue index ce8456e..69f44f4 100644 --- a/frontend/src/components/unification/vertical_relations/VerticalRelation.vue +++ b/frontend/src/components/unification/vertical_relations/VerticalRelation.vue @@ -50,12 +50,18 @@ export default { </script> <template> + <div id="overlay"> + <div class="cv-spinner"> + <span class="spinner"></span> + </div> + </div> <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" + :setup_vertical_rel_marking="true" + :include_unified_frame_status="'S'" @unified-frame-selected="unifiedFrameSelected" /> </div> diff --git a/frontend/src/components/unification/vertical_relations/VerticalRelationEdit.vue b/frontend/src/components/unification/vertical_relations/VerticalRelationEdit.vue index 3ea0a31..e2067d4 100644 --- a/frontend/src/components/unification/vertical_relations/VerticalRelationEdit.vue +++ b/frontend/src/components/unification/vertical_relations/VerticalRelationEdit.vue @@ -21,47 +21,81 @@ export default { data() { return { gettext: window.gettext, - unified_frame: {}, - unified_frame_title: '', - unified_frame_arguments: [], + + source_unified_frame: { + unified_frame: {}, + title: '', + unified_frame_arguments: [], + active_unified_frame_argument: null, + slowal_frames2selecional_preferencies_mapping: {}, + lexical_units: [], + subentries: null, + alternations: null, + realisation_phrases: null, + realisation_descriptions: null, + examples: null, + frames: null, + vertical_relations: null, + }, + target_unified_frame: { + unified_frame: {}, + title: '', + unified_frame_arguments: [], + active_unified_frame_argument: null, + slowal_frames2selecional_preferencies_mapping: {}, + lexical_units: [], + subentries: null, + alternations: null, + realisation_phrases: null, + realisation_descriptions: null, + examples: null, + frames: null, + vertical_relations: null, + }, + active_unified_frame_argument: null, - slowal_frames2selecional_preferencies_mapping: {}, - lexical_units: [], + selected_target_unified_frame_arguments: [], + img_prefix: window.STATIC_URL, - frames: [], right_pane_tabs: [ {id: 'hierarchy', label: gettext('Hierarchia')}, {id: 'notes', label: gettext('Notatki')}, ], right_pane_tab: 'hierarchy', - currentPreviewedUnifiedFrameId: this.previewedUnifiedFrameId, - internalForceRefresh: this.forceRefresh, - statusButtonTitle: '', active_slowal_frame: null, - showVerifiedFrames: false, - subentries: null, - alternations: null, - realisation_phrases: null, - realisation_descriptions: null, - examples: null, + selectedFrameArguments: null, frame_arguments_or_type: false, selectedLus: null, selectedSchemas: null, selectedExamples: null, - hidden_frames: [], - target_unified_frame: null, hierarchy_hyponyms: null, hierarchy_hyperonyms: null, current_vertical_relation: null, - vertical_relations: null, } }, components: {HierarchyElement, InfoTooltip, Spinner, HierarchyPreview, SlowalFrameComponent, ExamplesComponent, SemanticsSchemataComponent, MeaningComponent}, emits: ['goToDisplay', 'refresh', 'swapFrames', 'refreshEntriesList', 'clearUnifiedFrameView'], watch: { - forceRefresh(newVal, oldVal) { - this.loadFrame(); + unifiedFrameId(newVal, oldVal) { + const unifiedFrameId = newVal; + if(this.current_vertical_relation && this.current_vertical_relation.target_unified_frame && this.target_unified_frame.unified_frame.id) { + //Mamy zaÅ‚adowanÄ… ramÄ™ docelowÄ… oraz zapisanÄ… w relacji poziomej. + //Pytamy czy usunąć ramÄ™ docelowÄ… z relacji. + if (confirm(gettext("Czy chcesz usnąć aktualnÄ… ramÄ™ docelowÄ… z relacji poziomej?"))) { + this.remove_target_relation(() => { + this.loadFrame(unifiedFrameId, this.target_unified_frame); + }, true); + } + } else if(this.current_vertical_relation && !this.current_vertical_relation.target_unified_frame) { + //Åadujemy ramÄ™ docelowÄ… + this.loadFrame(unifiedFrameId, this.target_unified_frame); + } else if(!this.current_vertical_relation) { + //Nie mamy utworzonej relacji głównej. + //Åadujemy ramÄ™ źródÅ‚owÄ… + this.loadFrame(unifiedFrameId, this.source_unified_frame); + } + } }, computed: { @@ -72,7 +106,7 @@ export default { methods: { createHierarchyTree() { return { - 'unified_frame': this.unified_frame, + 'unified_frame': this.source_unified_frame.unified_frame, 'hyponyms': this.hierarchy_hyponyms, 'hypyronyms': this.hierarchy_hyperonyms }; @@ -80,44 +114,46 @@ export default { hasWhiteSpace(s) { return /\s/g.test(s); }, - async loadFrame() { + async loadFrame(unified_frame_id_to_load, unified_frame) { 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.vertical_relations = response.vertical_relations; - this.slowal_frames2selecional_preferencies_mapping = slowal_frames2selecional_preferencies(this.unified_frame, response.frames); - - 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(); - - if (!this.active_slowal_frame) { - this.setup_notes_unified_frame(); - } - }.bind(this), - error: function (request, errorType, errorMessage) { - show_error(errorType + ' (' + errorMessage + ')'); - } - }); + if(!unified_frame_id_to_load) { + //Pierwsze Å‚adowanie, bierzemt z id propsów + unified_frame_id_to_load = this.unifiedFrameId; + unified_frame = this.source_unified_frame; + } + send_post_request('/unifier/get_unified_frame/', + {'unified_frame_id': unified_frame_id_to_load, 'no_filters' : false}, + (response) => { + this.img_prefix = window.STATIC_URL; + + unified_frame.lexical_units = this.frames2lexical_units(response.frames); + unified_frame.unified_frame = response.unified_frame; + unified_frame.frames = response.frames; + unified_frame.title = unified_frame.unified_frame.title; + unified_frame.unified_frame_arguments = unified_frame.unified_frame.arguments; + unified_frame.vertical_relations = response.vertical_relations; + unified_frame.slowal_frames2selecional_preferencies_mapping = slowal_frames2selecional_preferencies(unified_frame.unified_frame, response.frames); + + unified_frame.subentries = response.subentries; + unified_frame.alternations = response.alternations; + unified_frame.realisation_phrases = response.realisation_phrases; + unified_frame.realisation_descriptions = response.realisation_descriptions; + unified_frame.examples = response.examples; + + if(this.current_vertical_relation && this.current_vertical_relation.target_unified_frame && this.source_unified_frame.unified_frame.id && this.target_unified_frame.unified_frame.id) { + this.fulfill_target_frames_arguments_with_empty_elems(this.current_vertical_relation.unified_frame_arguments_mapping, this.source_unified_frame, this.target_unified_frame) + } + window.update_last_visited(response.last_visited); + window.clear_info(); + + if (this.current_vertical_relation) { + this.setup_notes_vertical_relation(); + } + + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + }) this.loadHierarchy(); } catch (error) { console.log(error); @@ -150,9 +186,13 @@ export default { } }); }, - 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); + setup_notes_vertical_relation() { + setup_notes($('#notes-component'), $('#lexical-unit-notes-template'), this.current_vertical_relation.id, 'vertical_relations.UnifiedFrameVerticalRelation', + this.setup_notes_vertical_relation, 'vertical_relation', true); + }, + target_unified_frame_argument_selected(frame, argument) { + argument.selected = !argument.selected; + this.selected_target_unified_frame_arguments = frame.unified_frame_arguments.filter(argument => argument.selected) }, unifiedFrameArgumentSelected(argument) { if (this.active_unified_frame_argument === argument) { @@ -169,20 +209,11 @@ export default { } 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.')); - } - }, 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); + for (let i in this.source_unified_frame.unified_frame.slowal_frame_mapping) { + const slowal_frame_mapping = this.source_unified_frame.unified_frame.slowal_frame_mapping[i]; + const slowalFrame = this.source_unified_frame.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]; @@ -195,30 +226,56 @@ export default { } 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.")); + 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.')); } }, - isFrameVisible(status) { - return (status != 'B' && status != 'C') || this.isSuperLeksykograf(); + // 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 => { + this.source_unified_frame.subentries.forEach(subentry => { subentry.schemata.forEach(s => { s.selected = false; }); }); - this.frames.forEach(frame => { + this.source_unified_frame.frames.forEach(frame => { frame.lexical_units.forEach(lu => { lu.selected = false; }); @@ -226,7 +283,7 @@ export default { argument.selected = false; }); }); - this.examples.forEach(example => { + this.source_unified_frame.examples.forEach(example => { example.selected = false; }); this.selectedLus = []; @@ -234,26 +291,23 @@ export default { 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; - }, + // 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; + // } + // }, getArgumentCSS(argument) { - return (argument.role ? argument.role.str + ' ' : '') + (argument == this.active_unified_frame_argument ? 'active' : ''); + return (argument.role ? argument.role.str + ' ' : '') + (argument.selected ? 'active' : ''); }, schemataSelected(schemas) { this.selectedSchemas = schemas; @@ -262,7 +316,7 @@ export default { this.selectedExamples = selectedExamples; }, isReadOnlyForSuperLeksykograf() { - return (this.isSuperLeksykograf() && this.unified_frame.status === 'O') && this.unified_frame.assignee_username !== window.USER_USERNAME; + return (this.isSuperLeksykograf() && this.source_unified_frame.unified_frame.status === 'O') && this.source_unified_frame.unified_frame.assignee_username !== window.USER_USERNAME; }, frames2lexical_units(frames) { const lexical_units = [] @@ -279,33 +333,54 @@ export default { } 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': [], - } - } 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) + add_empty_argument() { + if(this.current_vertical_relation && this.current_vertical_relation.target_unified_frame && this.target_unified_frame) { + const slowal_frame_argument = { + 'str': 'Empty', + 'unified_frame_argument_id': -1, + 'id': -1, + 'role': 'Empty', + 'role_type': 'Empty', + 'preferences': [], + 'proposed_roles': [], + } + this.target_unified_frame.unified_frame_arguments.push(slowal_frame_argument); + } else { + alert(gettext("Wcelu dodanie pustego elementu, ustaw ramÄ™ docelowa.")); + } + }, + fulfill_target_frames_arguments_with_empty_elems(unified_frame_arguments_mapping, source_unified_frame, target_unified_frame) { + let new_slowal_frame_arguments = []; + const used_argument_ids = new Set(); + for (let j in source_unified_frame.unified_frame_arguments) { + const unified_frame_argument = source_unified_frame.unified_frame_arguments[j]; + let unified_frame_argument_mapping = unified_frame_arguments_mapping.find(o => o.source_unified_agrument_id === unified_frame_argument.id); + let slowal_frame_argument = null; + if (unified_frame_argument_mapping.target_unified_agrument_id == null) { + slowal_frame_argument = { + 'str': 'Empty', + 'unified_frame_argument_id': unified_frame_argument.id, + 'id': -1, + 'role': 'Empty', + 'role_type': 'Empty', + 'preferences': [], + 'proposed_roles': [], } - slowal_frame.arguments = new_slowal_frame_arguments; + } else { + used_argument_ids.add(unified_frame_argument_mapping.target_unified_agrument_id); + slowal_frame_argument = target_unified_frame.unified_frame_arguments.find(o => o.id === unified_frame_argument_mapping.target_unified_agrument_id); + slowal_frame_argument.unified_frame_argument_id = unified_frame_argument.id; + } + new_slowal_frame_arguments.push(slowal_frame_argument) + } + for (let j in target_unified_frame.unified_frame_arguments) { + const unified_frame_argument = target_unified_frame.unified_frame_arguments[j]; + if(!used_argument_ids.has(unified_frame_argument.id) && unified_frame_argument.id !== -1) { + unified_frame_argument.unified_frame_argument_id = -1; + new_slowal_frame_arguments.push(unified_frame_argument) } } + target_unified_frame.unified_frame_arguments = new_slowal_frame_arguments; }, createFrameHierarchyRepresentationHTML(unified_frame) { @@ -336,14 +411,16 @@ export default { let relation_id = normalizeFormData(f.opinion)[0]; send_post_request('/vertical_relations/save_main_vertical_relation/', { - 'source_unified_frame_id': this.unified_frame.id, - 'target_unified_frame_id': this.target_unified_frame ? this.target_unified_frame.id : null, + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': null, 'main_vertical_relation_id': relation_id }, (reponse) => { show_info('Relacja główne zostaÅ‚a ustawiona.'); + this.clear_relation(); this.current_vertical_relation = reponse['vertical_relation']; - this.loadFrame(); + this.$emit('refreshEntriesList'); + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); $.prompt.close(); }, (request, errorType, errorMessage) => { @@ -365,8 +442,6 @@ export default { return `<label><input type="checkbox" ${temporal_vertical_relations_ids.has(relation.id) ? 'checked' : ''} name="opinion" value="${relation.id}" /> ${relation.name}</label><br />`; }).join(""); }.bind(this); - - const temporal_vertical_relation_select_popup = { state0: { title: 'Wybierz relacje pomocnicze', @@ -383,14 +458,14 @@ export default { let relation_ids = normalizeFormData(f.opinion); send_post_request('/vertical_relations/save_temporal_vertical_relation/', { - 'source_unified_frame_id': this.unified_frame.id, - 'target_unified_frame_id': this.target_unified_frame ? this.target_unified_frame.id : null, + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id ? this.target_unified_frame.unified_frame.id : null, 'temporal_vertical_relation_ids': JSON.stringify(relation_ids) }, (reponse) => { show_info('Relacje pomocnicze zostaÅ‚y ustawione.'); this.current_vertical_relation = reponse['vertical_relation']; - this.loadFrame(); + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); $.prompt.close(); }, (request, errorType, errorMessage) => { @@ -407,11 +482,33 @@ export default { alert(gettext("Dodanie relacji pomocniczych wymaga ustawienia relacji głównej.")); } }, + clear_relation() { + this.current_vertical_relation = null; + this.target_unified_frame = { + unified_frame: {}, + title: '', + unified_frame_arguments: [], + active_unified_frame_argument: null, + slowal_frames2selecional_preferencies_mapping: {}, + lexical_units: [], + subentries: null, + alternations: null, + realisation_phrases: null, + realisation_descriptions: null, + examples: null, + frames: null, + vertical_relations: null, + }; + }, + finish_edit() { + this.clear_relation(); + }, load_vertical_relation() { const load_vertical_relation_select = function () { - return this.vertical_relations.map(vertical_relation => { + let ret = this.source_unified_frame.vertical_relations.map(vertical_relation => { return `<label><input type="radio" name="opinion" value="${vertical_relation.id}" /> ${vertical_relation.str}</label><br />`; - }).join(""); + }); + return ret.join(""); }.bind(this); const load_vertical_relation_select_popup = { @@ -435,7 +532,12 @@ export default { (reponse) => { show_info('Relacja zostaÅ‚a zaÅ‚adowana.'); this.current_vertical_relation = reponse['vertical_relation']; - this.loadFrame(); + if (this.current_vertical_relation.target_unified_frame) { + this.loadFrame(this.current_vertical_relation.target_unified_frame.id, this.target_unified_frame); + } else { + this.clear_relation(); + this.current_vertical_relation = reponse['vertical_relation']; + } $.prompt.close(); }, (request, errorType, errorMessage) => { @@ -457,8 +559,9 @@ export default { }, (reponse) => { show_info('Relacja zostaÅ‚a usuniÄ™ta.'); - this.current_vertical_relation = null; - this.loadFrame(); + this.clear_relation(); + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + this.$emit('refreshEntriesList'); $.prompt.close(); }, (request, errorType, errorMessage) => { @@ -469,7 +572,338 @@ export default { } else { alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej relacji.")); } - } + }, + add_target_relation() { + if(this.current_vertical_relation) { + if(this.target_unified_frame.unified_frame.id) { + send_post_request('/vertical_relations/save_target_relation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + }, + (reponse) => { + show_info('Relacja docelowa zostaÅ‚a ustawiona.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("Dodanie relacji docelowej nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + $.prompt.close(); + }) + } else { + alert(gettext("Wybierze z listy relacjÄ™ docelowÄ….")); + } + } else { + alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej relacji.")); + } + }, + remove_target_relation(exex_after, do_not_ask) { + if(this.current_vertical_relation) { + if(this.current_vertical_relation.target_unified_frame) { + if (!do_not_ask && !confirm(gettext("Czy na pewno chcesz usunąć relacjÄ™ docelowÄ…?"))) return false; + send_post_request('/vertical_relations/remove_target_relation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + }, + (reponse) => { + if(reponse.succ == true) { + show_info('Relacja docelowa zostaÅ‚a usuniÄ™ta.'); + this.clear_relation(); + this.current_vertical_relation = reponse['vertical_relation']; + if (exex_after) { + exex_after(); + } + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + } else { + alert(reponse.error); + } + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("UsiniÄ™cie relacji docelowej nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + $.prompt.close(); + }) + } else { + alert(gettext("Wybierze z listy relacjÄ™ docelowÄ….")); + } + } else { + alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej relacji.")); + } + }, + nagete_relation() { + if(this.target_unified_frame.unified_frame.id) { + if(this.selected_target_unified_frame_arguments.length > 0) { + if(this.selected_target_unified_frame_arguments.length == 1) { + const vertical_relation_negations_select = function () { + return vertical_relation_negations.map(negation => { + return `<label><input type="radio" ${this.current_vertical_relation.negation && this.current_vertical_relation.negation.id == negation.id ? 'checked' : ''} name="negation" value="${negation.id}" /> ${negation.name}</label><br />`; + }).join(""); + }.bind(this); + const nagete_select_popup = { + state0: { + title: 'Wybierz negacjÄ™', + html: vertical_relation_negations_select, + 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 relation_id = normalizeFormData(f.negation)[0]; + send_post_request('/vertical_relations/save_vertical_relation_negation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + 'negation_id': relation_id, + 'unified_frame_argument_id': this.selected_target_unified_frame_arguments[0].id + }, + (reponse) => { + show_info('NegacjÄ… zostaÅ‚a ustawiona.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.selected_target_unified_frame_arguments[0].selected = null; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("Ustawienie negacji nie powiodÅ‚a siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + $.prompt.close(); + }) + } + }.bind(this) + } + } + $.prompt(nagete_select_popup); + } else { + alert(gettext("W celu ustawienia relacji wybierz dokÅ‚adnie jeden argument ramy.")); + } + } else { + alert(gettext("W celu ustawienia relacji wybierz docelowy argument ramy.")); + } + } else { + alert(gettext("Ustawienie negacji wymaga ustawienia relacji docelowej.")); + } + }, + remove_negation() { + if(this.current_vertical_relation && this.current_vertical_relation.negation) { + if (!confirm(gettext("Czy na pewno chcesz usunąć negacjÄ™?"))) return false; + send_post_request('/vertical_relations/remove_vertical_relation_negation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + }, + (reponse) => { + show_info('Negacja zostaÅ‚a usuniÄ™ta.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("UsiniÄ™cie negacji nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + }) + } else { + alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej negacji.")); + } + }, + add_subrelation() { + const iterate_select = function () { + const vertical_relations_html = this.source_unified_frame.vertical_relations.filter( + vertical_relation => { + return vertical_relation.target_unified_frame_id !== this.target_unified_frame.unified_frame.id + }) + .map(vertical_relation => { + return `<label><input type="radio" name="instance" value="${vertical_relation.id}" /> ${vertical_relation.str}</label><br />`; + }).join(""); + const temporal_vertical_relation_html = temporal_vertical_relations.map(relation => { + return `<label><input type="checkbox" name="temporal_vertical_relation" value="${relation.id}" /> ${relation.name}</label><br />`; + }).join(""); + return '<div class="row">' + + '<div class="column"><div class="role_select_header">Instancje</div>' + vertical_relations_html + '</div>' + + '<div class="column"><div class="role_select_header">Relacje temporalne</div>' + temporal_vertical_relation_html + '</div>' + + '</div>'; + }.bind(this); + + const subrelation_select_popup = { + state0: { + title: 'Wybierz instancjÄ™ oraz relacjÄ™ temporalnÄ…', + html: iterate_select, + 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(); + const instance_id = normalizeFormData(f.instance)[0]; + const temporal_vertical_relation_id = normalizeFormData(f.temporal_vertical_relation)[0]; + + send_post_request('/vertical_relations/save_subrelation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + 'subrelation_instance_id': instance_id, + 'temporal_vertical_relation_id': temporal_vertical_relation_id, + }, + (reponse) => { + show_info('Podrelacja zostaÅ‚a zaÅ‚adowana.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("Zapis podrelacji nie powiodÅ‚ siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + $.prompt.close(); + }) + } + }.bind(this) + } + } + $.prompt(subrelation_select_popup); + }, + remove_subrelation() { + if(this.current_vertical_relation) { + if(this.target_unified_frame.unified_frame.id) { + if (!confirm(gettext("Czy na pewno chcesz usunąć podrelacjÄ™?"))) return false; + send_post_request('/vertical_relations/remove_subrelation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + }, + (reponse) => { + show_info('Podrelacja zostaÅ‚a usuniÄ™ta.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("UsiniÄ™cie podrelacji nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + }) + } else { + alert(gettext("Wybierze z listy relacjÄ™ docelowÄ….")); + } + } else { + alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej relacji.")); + } + }, + iterate_relation() { + if(this.target_unified_frame.unified_frame.id) { + const iterate_relation_select = function () { + return temporal_vertical_relations.map(relation => { + return `<label><input type="radio" name="opinion" value="${relation.id}" /> ${relation.name}</label><br />`; + }).join(""); + }.bind(this); + const iterate_relation_select_popup = { + state0: { + title: 'Wybierz relacjÄ™', + html: iterate_relation_select, + 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 relation_id = normalizeFormData(f.opinion)[0]; + send_post_request('/vertical_relations/save_iter_relation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + 'temporal_vertical_relation_id': relation_id + }, + (reponse) => { + show_info('Relacja iteracji zostaÅ‚a ustawiona.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + $.prompt.close(); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("Ustawienie relacji iteracji nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + $.prompt.close(); + }) + } + }.bind(this) + } + } + $.prompt(iterate_relation_select_popup); + } else { + alert(gettext("Ustawienie iteracji wymaga ustawienia relacji docelowej.")); + } + }, + remove_iter_relation() { + if(this.current_vertical_relation && this.current_vertical_relation.iter_temporal_vertical_relation) { + if (!confirm(gettext("Czy na pewno chcesz usunąć relacjÄ™ iteracji?"))) return false; + send_post_request('/vertical_relations/remove_iter_relation/', + { + 'source_unified_frame_id': this.source_unified_frame.unified_frame.id, + 'target_unified_frame_id': this.target_unified_frame.unified_frame.id, + 'vertical_relation_id': this.current_vertical_relation.main_vertical_relation.id, + }, + (reponse) => { + show_info('Relacja iteracji zostaÅ‚a usuniÄ™ta.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.source_unified_frame.unified_frame.id, this.source_unified_frame); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("UsiniÄ™cie relacji iteracji nie powiodÅ‚o siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + }) + } else { + alert(gettext("Rama źródÅ‚owa nie posiada jeszcze ustawionej relacji iteracji.")); + } + }, + get_target_instance_title(vertical_relation, unified_frame) { + const ret = unified_frame.title; + const target_str = vertical_relation && vertical_relation.target_unified_frame ? '::I' + vertical_relation.id : ''; + const neg_str = vertical_relation && vertical_relation.negation ? ' (' + vertical_relation.negation.name +': ' + vertical_relation.negation_argument.role + ')' : ''; + const iter_str = vertical_relation && vertical_relation.iter_temporal_vertical_relation ? ' (iterated: ' + vertical_relation.iter_temporal_vertical_relation.name +')' : ''; + return ret + target_str + neg_str + iter_str; + }, + change_slowal2unified_frame_argument_mapping() { + if (this.selected_target_unified_frame_arguments && this.selected_target_unified_frame_arguments.length == 2) { + const mapping = this.selected_target_unified_frame_arguments.map(arg => { + return { + 'unified_frame_argument_id': arg.unified_frame_argument_id, + 'id': arg.id + } + }); + send_post_request('/vertical_relations/change_argument_mapping/', + { + 'vertical_relation_id': this.current_vertical_relation.id, + 'selected_arguments': JSON.stringify(mapping), + }, + (reponse) => { + show_info('Zargumenty zostaÅ‚y zamienione.'); + this.current_vertical_relation = reponse['vertical_relation']; + this.loadFrame(this.target_unified_frame.unified_frame.id, this.target_unified_frame); + }, + (request, errorType, errorMessage) => { + show_error(errorType + ' (' + errorMessage + ')'); + alert(gettext("Zamiana argumentów nie powiodÅ‚a siÄ™. Błąd: " + errorType + ' (' + errorMessage + ')')); + }) + } else { + alert(gettext("Zamiany pozycji argumentu w ramie wymaga zaznaczenia dokÅ‚adnie 2 argumentów.")); + } + }, }, mounted() { @@ -503,23 +937,24 @@ export default { <div id="source-unified-frame-pane" class="col w-100 p-0 overflow-auto"> <table v-if="!isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" cellspacing="1"> <tr style="background-color: white;"> - <td id="change-main-relation" @click="save_main_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj relacjÄ™</td> - <td id="change-temporal-relation" @click="save_temporal_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj podrelacjÄ™</td> - <td id="remove-relation" @click="remove_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">UsuÅ„ relacjÄ™</td> - <td id="available-relations" @click="load_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">DostÄ™pne relacje</td> + <td class="table-button-menu-td" id="change-main-relation" @click="save_main_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj relacjÄ™</td> + <td class="table-button-menu-td" id="change-temporal-relation" @click="save_temporal_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj podrelacjÄ™</td> + <td class="table-button-menu-td" id="remove-relation" @click="remove_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">UsuÅ„ relacjÄ™</td> + <td class="table-button-menu-td" id="available-relations" @click="load_vertical_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">DostÄ™pne relacje</td> + <td class="table-button-menu-td" @click="finish_edit()" style="padding: 10px 15px 10px 15px; color: #000000;">ZakoÅ„cz</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"> + <div class="unifiedFrame mt-3" v-bind:data-frame_id="source_unified_frame.unified_frame.id" id="unified-frame-title">{{source_unified_frame.title + (current_vertical_relation && current_vertical_relation.source_unified_frame ? '::I' + current_vertical_relation.id : '')}}</div> + <table v-if="source_unified_frame.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"> + <template v-for="argument in source_unified_frame.unified_frame_arguments"> <td class="argument py-2 px-1 border-top border-left border-secondary role-column" - :class="getArgumentCSS(argument)" + :class="getArgumentCSS(argument, active_unified_frame_argument)" @click="unifiedFrameArgumentSelected(argument)" @mouseover="unifiedFrameArgumentHovered(argument)" @mouseleave="unifiedFrameArgumentHovered(null)" @@ -545,7 +980,7 @@ export default { </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' + v-for='argument in source_unified_frame.unified_frame_arguments' :key='argument.id' > <ul class="ul-preference" v-if="argument.preferences.length > 0"> @@ -559,8 +994,8 @@ export default { <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]"> + <ul class="ul-preference" v-if="source_unified_frame.unified_frame.status !== 'S'"> + <li v-for="preference in source_unified_frame.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> @@ -573,10 +1008,10 @@ export default { </tbody> </table> </div> - <div v-if="unified_frame.id" class="lu-table mt-3 mb-3"> + <div v-if="source_unified_frame.unified_frame.id" class="lu-table mt-3 mb-3"> <table class="m-0 table-borderless border border-secondary text-dark"> <td class="argument py-2 px-1 border-top border-left border-secondary"> - <template v-for='lexical_unit in lexical_units'> + <template v-for='lexical_unit in source_unified_frame.lexical_units'> {{ lexical_unit.str }}, </template> </td> @@ -587,8 +1022,22 @@ export default { <div v-if="current_vertical_relation" class="lu-table mt-3 mb-3" style="padding-left: 50px;"> <table class="m-0 table-borderless text-dark"> <tr> - <td class="argument py-2 px-1 border-top border-left border-secondary" colspan="2"> - {{current_vertical_relation.main_vertical_relation.name}} + <td class="argument py-2 px-1 font-weight-bold">Relacja główna:</td> + <td class="argument py-2 px-1"> + {{current_vertical_relation.main_vertical_relation.name}} + </td> + </tr> + <tr> + <td class="argument py-2 px-1 font-weight-bold">Wiąże instancjÄ™:</td> + <td class="argument py-2 px-1"> + {{(current_vertical_relation && current_vertical_relation.source_unified_frame ? current_vertical_relation.source_unified_frame.title + '::I' + current_vertical_relation.id : '') + ', ' + + (current_vertical_relation && current_vertical_relation.target_unified_frame ? current_vertical_relation.target_unified_frame.title + '::I' + current_vertical_relation.id : '')}} + </td> + </tr> + <tr> + <td class="argument py-2 px-1 font-weight-bold">Podrelacja:</td> + <td class="argument py-2 px-1"> + {{current_vertical_relation.temporal_vertical_relation ? current_vertical_relation.temporal_vertical_relation.map(r => r.name).join(',') : ''}} </td> </tr> </table> @@ -596,16 +1045,182 @@ export default { </div> </div> <div id="target-unified-frame-pane" class="col w-100 p-0 overflow-auto"> + <table v-if="!isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" cellspacing="1"> + <tr style="background-color: white;"> + <td class="table-button-menu-td" @click="this.current_vertical_relation && this.current_vertical_relation.target_unified_frame ? remove_target_relation() : add_target_relation() " style="padding: 10px 15px 10px 15px; color: #000000;">{{this.current_vertical_relation && this.current_vertical_relation.target_unified_frame ? 'UsuÅ„ relacjÄ™ docelowÄ…' : 'Ustaw relacjÄ™ docelowÄ…'}}</td> + <td class="table-button-menu-td" @click="add_empty_argument()" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj arg. EMPTY</td> + <td class="table-button-menu-td" @click="this.current_vertical_relation && this.current_vertical_relation.subrelation ? remove_subrelation() : add_subrelation()" style="padding: 10px 15px 10px 15px; color: #000000;">{{this.current_vertical_relation && this.current_vertical_relation.subrelation ? 'UsuÅ„ podrelacjÄ™' : 'Dodaj podrelacjÄ™'}}</td> + <td class="table-button-menu-td" @click="this.current_vertical_relation && this.current_vertical_relation.negation ? remove_negation() : nagete_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">{{this.current_vertical_relation && this.current_vertical_relation.negation ? 'UsuÅ„ negacjÄ™' : 'Zaneguj instancje'}}</td> + <td class="table-button-menu-td" @click="this.current_vertical_relation && this.current_vertical_relation.iter_temporal_vertical_relation ? remove_iter_relation() : iterate_relation()" style="padding: 10px 15px 10px 15px; color: #000000;">{{this.current_vertical_relation && this.current_vertical_relation.iter_temporal_vertical_relation ? 'UsuÅ„ relacjÄ™ iteracji' : 'Iteruj instancje' }}</td> + </tr> + </table> + <div v-if="target_unified_frame.unified_frame.id"> + <div class="d-flex justify-content-center flex-row"> + <div> + <div class="unifiedFrame mt-3" v-bind:data-frame_id="target_unified_frame.unified_frame.id" id="target-unified-frame-title">{{get_target_instance_title(current_vertical_relation, target_unified_frame)}}</div> + <table v-if="target_unified_frame.unified_frame.id" id="target-unified-frame" class="m-0 table-borderless border border-secondary text-dark frame active"> + <tbody> + <tr> + <template v-for="argument in target_unified_frame.unified_frame_arguments"> + <td + class="argument py-2 px-1 border-top border-left border-secondary role-column" + :class="getArgumentCSS(argument)" + @click="target_unified_frame_argument_selected(target_unified_frame, 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> + </td> + </template> + </tr> + <tr> + <template v-for="argument in target_unified_frame.unified_frame_arguments"> + <td class="preferences py-0 px-0 border-top border-left border-secondary role-column align-top" + > + <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-else class="preference py-2 px-1 preference-bold">{{ preference.str }}</div> + </li> + </ul> + <ul class="ul-preference" v-if="target_unified_frame.unified_frame.status !== 'S'"> + <li v-for="preference in target_unified_frame.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> + </template> + </tr> + </tbody> + </table> + </div> + <div v-if="!isReadOnlyForSuperLeksykograf()" class="pl-0 pt-4" style="max-width: 60px;"> + <div> + <div class="py-3 pl-1"> + <button class="btn btn-sm btn-dark px-2 py-0" role="button" + style="font-size: 20px; min-width: 35px" + @click="change_slowal2unified_frame_argument_mapping(frame)" + title="ZamieÅ„ wybrane argumenty ramy" + >Z</button> + </div> + </div> + </div> + </div> + </div> + + + <div v-if="current_vertical_relation && current_vertical_relation.subrelation && current_vertical_relation.subrelation.target_unified_frame"> + <div class="d-flex justify-content-center flex-row"> + <div> + <div class="unifiedFrame mt-3" v-bind:data-frame_id="current_vertical_relation.subrelation.target_unified_frame.id" id="subrelation-unified-frame-title">{{get_target_instance_title(current_vertical_relation.subrelation, current_vertical_relation.subrelation.target_unified_frame)}}</div> + <table v-if="current_vertical_relation.subrelation.target_unified_frame.id" id="subrelation-unified-frame" class="m-0 table-borderless border border-secondary text-dark frame active"> + <tbody> + <tr> + <template v-for="argument in current_vertical_relation.subrelation.target_unified_frame.arguments"> + <td + class="argument py-2 px-1 border-top border-left border-secondary role-column" + :class="getArgumentCSS(argument)" + > + {{ 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> + </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 current_vertical_relation.subrelation.target_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-else class="preference py-2 px-1 preference-bold">{{ preference.str }}</div> + </li> + </ul> + <ul class="ul-preference" v-if="current_vertical_relation.subrelation.target_unified_frame.status !== 'S'"> + <li v-for="preference in current_vertical_relation.subrelation.target_unified_frame.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> + </div> + </div> + + <div align="left"> + <div class="lu-table mt-3 mb-3" style="padding-left: 50px;"> + <table class="m-0 table-borderless text-dark"> + <tr> + <td class="argument py-2 px-1 font-weight-bold">Podrelacja:</td> + <td class="argument py-2 px-1"> + {{current_vertical_relation.temporal_vertical_relation_for_subrelation.name + '(' + + current_vertical_relation.target_unified_frame.title + '::I' + current_vertical_relation.id + ', ' + + current_vertical_relation.subrelation.target_unified_frame.title + '::I' + current_vertical_relation.subrelation.id + + ')' + }} + </td> + </tr> + </table> + </div> + </div> + + </div> + </div> <div id="examples" class="col w-100 p-0 tab-pane overflow-auto"> - <examples-component v-if="examples" - :examples="examples" + <examples-component v-if="source_unified_frame.examples" + :examples="source_unified_frame.examples" :frame="active_slowal_frame" :frame_arguments="selectedFrameArguments" :frame_arguments_or_type="frame_arguments_or_type" :lus="selectedLus" :schemas="selectedSchemas" - :key="examples" + :key="source_unified_frame.examples" @example-selected="exampleSelected" /> </div> diff --git a/frontend/src/components/unification/vertical_relations/VerticalRelationRightPane.vue b/frontend/src/components/unification/vertical_relations/VerticalRelationRightPane.vue index b240ac4..1179632 100644 --- a/frontend/src/components/unification/vertical_relations/VerticalRelationRightPane.vue +++ b/frontend/src/components/unification/vertical_relations/VerticalRelationRightPane.vue @@ -51,11 +51,10 @@ 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 || unifiedFrameId" class="row h-100 m-0 p-0 overflow-auto" id="semantics-top-pane"> <vertical-relation-edit ref="hierarchyEdit" v-if="unifiedFrameId" - :key="unifiedFrameId" :unifiedFrameId="unifiedFrameId" :previewedUnifiedFrameId="previewedUnifiedFrameId" @go-to-display="goToDisplay" diff --git a/syntax/management/commands/import_tei.py b/syntax/management/commands/import_tei.py index f1afea6..afa7753 100644 --- a/syntax/management/commands/import_tei.py +++ b/syntax/management/commands/import_tei.py @@ -26,7 +26,7 @@ from syntax.models_phrase import ( LemmaOperator, LemmaCooccur, ModificationType, ) -from vertical_relations.models import MainVerticalRelation, TemporalVerticalRelation +from vertical_relations.models import MainVerticalRelation, TemporalVerticalRelation, VerticalRelationNegation class Command(BaseCommand): @@ -364,6 +364,7 @@ def import_vertical_relations(): main_relations = [(1, u'cause(s)'), (2, u'conditioned'), (3, u'presuppose(s) (pressuposition)'), (4, u'exclude(s)'), (5, u'antonimic'), (6, u'implicate(s)')] + MainVerticalRelation.objects.all().delete() for pri, name in main_relations: relation = MainVerticalRelation(name=name, priority=pri) relation.save() @@ -373,6 +374,16 @@ def import_vertical_relations(): (8, u'after'), (9, u'met'), (10, u'overlapped'), (11, u'begun'), (12, u'contains'), (13, u'ended')] + TemporalVerticalRelation.objects.all().delete() for pri, name in temporal_relations: relation = TemporalVerticalRelation(name=name, priority=pri) relation.save() + + negations = [(1, u'negated-all'), (2, u'negated-ex'), (3, u'positive-ex')] + + VerticalRelationNegation.objects.all().delete() + for pri, name in negations: + negation = VerticalRelationNegation(name=name, priority=pri) + negation.save() + + diff --git a/unifier/models.py b/unifier/models.py index 6a8cd87..e8d0de5 100644 --- a/unifier/models.py +++ b/unifier/models.py @@ -39,6 +39,8 @@ class UnifiedFrame(models.Model): hasHierarchyElems = models.BooleanField(default=False) + has_vertical_relations = models.BooleanField(default=False) + def sorted_arguments(self): # TODO: zaimplementowac wlasciwe sortowanie return UnifiedFrameArgument.objects.filter(unified_frame=self) diff --git a/unifier/views.py b/unifier/views.py index f7b4ada..c4799d1 100644 --- a/unifier/views.py +++ b/unifier/views.py @@ -219,6 +219,7 @@ def get_unified_frames(request): if request.method == 'POST': scroller_params = get_scroller_params(request.POST) exclude_status = request.GET.get('exclude_status') + include_status = request.GET.get('include_status') restrict_to_user = request.GET.get('restrict_to_user') scroller_params = get_scroller_params(request.POST) @@ -253,6 +254,13 @@ def get_unified_frames(request): if scroller_params['filter']: unified_frames = unified_frames.filter(title__startswith=scroller_params['filter']) + if include_status: + unified_frames = unified_frames.filter(status=include_status) + + if exclude_status: + unified_frames = unified_frames.exclude(status=exclude_status) + + # TODO: zapytać, czy mamy zaciÄ…gać powiÄ…zane ramy zunifikowane poprzez Enrty (slowal_frame -> lexical_units -> entries -> related_entries) # linked_ids = set() # if request.session['show_linked_entries']: @@ -275,12 +283,12 @@ def get_unified_frames(request): 'status': unifiedFrame.status, 'assignee_username': user, 'hierarchy_exists': unifiedFrame.hasHierarchyElems, + 'has_vertical_relations': unifiedFrame.has_vertical_relations, } res_processed = [] for key, value in res.items(): - if ((exclude_status is None or value['status'] != exclude_status) and - (restrict_to_user is None or value['assignee_username'] == restrict_to_user)) or \ + if (restrict_to_user is None or value['assignee_username'] == restrict_to_user) or \ value['status'] == choices.UnifiedFrameStatus.VERIFIED: res_processed.append(value) @@ -404,31 +412,6 @@ def get_unified_frame_json(unified_frame, request): slowal_frames_db = slowal_frames_db.select_related("opinion") - # slowal_frames_db = slowal_frames_db.prefetch_related( - # Prefetch( - # 'lexical_units', - # queryset=LexicalUnit.objects - # ), - # Prefetch( - # 'arguments', - # queryset=Argument.objects.select_related("role", "role__role", "role__attribute", "role__sub_attribute").prefetch_related( - # Prefetch( - # 'example_connections', - # queryset=ExampleConnection.objects.select_related('example', 'lexical_unit').prefetch_related( - # Prefetch( - # 'arguments', - # queryset=Argument.objects - # ), - # Prefetch( - # 'schema_connections', - # queryset=SchemaHook.objects - # ) - # ) - # ) - # ) - # ) - # ) - slowal_frames_db = slowal_frames_db.prefetch_related("arguments__role__role") slowal_frames_db = slowal_frames_db.prefetch_related("arguments__role__attribute") slowal_frames_db = slowal_frames_db.prefetch_related("arguments__role__sub_attribute") @@ -489,8 +472,9 @@ def get_unified_frame_json(unified_frame, request): vertical_relations = UnifiedFrameVerticalRelation.objects.filter(source_unified_frame=unified_frame) vertical_relations = vertical_relations.prefetch_related("target_unified_frame") \ .prefetch_related("target_unified_frame").prefetch_related("main_vertical_relation")\ - .prefetch_related("temporal_vertical_relation")\ - .prefetch_related("iterated_target_unified_frame").prefetch_related("iterated_temporal_vertical_relation") + .prefetch_related("negation")\ + .prefetch_related("subrelation").prefetch_related("temporal_vertical_relation_for_subrelation")\ + .prefetch_related("iter_temporal_vertical_relation") return {'vertical_relations': vertical_relations_2_dict(vertical_relations), 'unified_frame_id': unified_frame.id, 'unified_frame': unified_frame_dict, 'subentries': subentries, 'frames': slowal_frames_dict, 'alternations': alternations, 'realisation_phrases': realisation_phrases, @@ -504,6 +488,7 @@ def vertical_relations_2_dict(vertical_relations): 'str': str(vertical_relation), 'id': vertical_relation.id, 'source_unified_frame_id': vertical_relation.source_unified_frame.id, + 'target_unified_frame_id': vertical_relation.target_unified_frame.id if vertical_relation.target_unified_frame else None, } for vertical_relation in sorted(vertical_relations.all(), key=lambda x: x.id) ] diff --git a/vertical_relations/models.py b/vertical_relations/models.py index c4eea01..45601ae 100644 --- a/vertical_relations/models.py +++ b/vertical_relations/models.py @@ -25,10 +25,33 @@ class TemporalVerticalRelation(models.Model): return self.name +class VerticalRelationNegation(models.Model): + name = models.CharField(max_length=100) + priority = models.PositiveIntegerField() + + class Meta: + ordering = ['priority'] + + def __str__(self): + return self.name + + class UnifiedFrameArgument2UnifiedFrameArgumentMapping(object): pass +class UnifiedFrameVerticalRelation(object): + pass + + +class UnifiedFrameArgument2UnifiedFrameArgumentMapping(models.Model): + source_unified_agrument = models.ForeignKey(UnifiedFrameArgument, related_name='source_unified_agrument_mapping', + on_delete=models.PROTECT) + target_unified_agrument = models.ForeignKey(UnifiedFrameArgument, related_name='target_unified_agrument_mapping', blank=True, null=True, on_delete=models.PROTECT) + unified_frame_vertical_relation = models.ForeignKey('UnifiedFrameVerticalRelation', + related_name='unified_frame_arguments_mapping', on_delete=models.PROTECT) + + class UnifiedFrameVerticalRelation(models.Model): source_unified_frame = models.ForeignKey(UnifiedFrame, related_name='source_vertical_relation', default=None, blank=True, null=True, on_delete=models.PROTECT) @@ -38,26 +61,25 @@ class UnifiedFrameVerticalRelation(models.Model): default=None, blank=True, null=True, on_delete=models.PROTECT) temporal_vertical_relation = models.ManyToManyField(related_name='unified_frame_vertical_relation', to=TemporalVerticalRelation) - is_negated = models.BooleanField(default=False) + negation = models.ForeignKey(VerticalRelationNegation, related_name='vertical_relation_negation', + default=None, blank=True, null=True, on_delete=models.PROTECT) + negation_argument = models.ForeignKey(UnifiedFrameArgument, related_name='negation_argument', + default=None, blank=True, null=True, on_delete=models.PROTECT) - iterated_target_unified_frame = models.ForeignKey(UnifiedFrame, related_name='iterated_target_vertical_relation', + subrelation = models.ForeignKey('UnifiedFrameVerticalRelation', related_name='subrelation_recursive', default=None, blank=True, null=True, on_delete=models.PROTECT) - iterated_temporal_vertical_relation = models.ManyToManyField(related_name='iterated_unified_frame_vertical_relation', - to=TemporalVerticalRelation) - - def __str__(self): - iter_str = ('(iter:' + self.iterated_target_unified_frame.ttile + ' - ' + - (','.join(self.iterated_temporal_vertical_relation.all()) if self.iterated_temporal_vertical_relation else '') + ')') if self.iterated_target_unified_frame else '' - - return self.source_unified_frame.title + ':' + (self.target_unified_frame.title if self.target_unified_frame else '') + \ - ' - ' + ('[neg]' if self.is_negated else '') + self.main_vertical_relation.name + ', ' + \ - (','.join(self.temporal_vertical_relation.all()) if self.is_negated else '') + iter_str + temporal_vertical_relation_for_subrelation = models.ForeignKey(TemporalVerticalRelation, related_name='temporal_vertical_relation_for_subrelation', + default=None, blank=True, null=True, on_delete=models.PROTECT) + iter_temporal_vertical_relation = models.ForeignKey(TemporalVerticalRelation, related_name='iter_temporal_vertical_relation', + default=None, blank=True, null=True, on_delete=models.PROTECT) -class UnifiedFrameArgument2UnifiedFrameArgumentMapping(models.Model): - source_unified_agrument = models.ForeignKey(UnifiedFrameArgument, related_name='source_unified_agrument_mapping', - on_delete=models.PROTECT) - target_unified_agrument = models.ForeignKey(UnifiedFrameArgument, related_name='target_unified_agrument_mapping', on_delete=models.PROTECT) - unified_frame_vertical_relation = models.ForeignKey(UnifiedFrameVerticalRelation, - related_name='unified_frame_arguments_mapping', on_delete=models.PROTECT) - + def __str__(self): + subrelation_str = (', sub: (iterated:' + self.subrelation.target_unified_frame.title + ' - ' + + (self.temporal_vertical_relation_for_subrelation.name if self.temporal_vertical_relation_for_subrelation else '') + ')') if self.subrelation and self.subrelation.target_unified_frame else '' + + return str(self.id) + '::'+self.source_unified_frame.title + ':' + (self.target_unified_frame.title if self.target_unified_frame else '') + \ + ' - ' + self.main_vertical_relation.name + ', ' + (','.join([str(t) for t in self.temporal_vertical_relation.all()]) if self.temporal_vertical_relation else '') +\ + (' (' + self.negation.name + ': ' + self.negation_argument.role.role.role + ')' if self.negation else '') + \ + (' (iterated:' + str(self.iter_temporal_vertical_relation.name) + '] ' if self.iter_temporal_vertical_relation else '') +\ + subrelation_str diff --git a/vertical_relations/urls.py b/vertical_relations/urls.py index 0c597d4..9e5dab5 100644 --- a/vertical_relations/urls.py +++ b/vertical_relations/urls.py @@ -11,5 +11,17 @@ urlpatterns = [ path('load_vertical_relation/', views.load_vertical_relation, name='load_vertical_relation'), path('save_temporal_vertical_relation/', views.save_temporal_vertical_relation, name='save_temporal_vertical_relation'), path('remove_vertical_relation/', views.remove_vertical_relation, name='remove_vertical_relation'), + path('save_target_relation/', views.save_target_relation, name='save_target_relation'), + path('remove_target_relation/', views.remove_target_relation, name='remove_target_relation'), + path('ajax_vertical_relation_negations/', views.ajax_vertical_relation_negations, name='ajax_vertical_relation_negations'), + path('save_vertical_relation_negation/', views.save_vertical_relation_negation, name='save_vertical_relation_negation'), + path('remove_vertical_relation_negation/', views.remove_vertical_relation_negation, name='remove_vertical_relation_negation'), + path('save_subrelation/', views.save_subrelation, name='save_subrelation'), + path('remove_subrelation/', views.remove_subrelation, name='remove_subrelation'), + path('save_iter_relation/', views.save_iter_relation, name='save_iter_relation'), + path('remove_iter_relation/', views.remove_iter_relation, name='remove_iter_relation'), + path('change_argument_mapping/', views.change_argument_mapping, name='change_argument_mapping'), + + ] diff --git a/vertical_relations/views.py b/vertical_relations/views.py index ed17d73..710b386 100644 --- a/vertical_relations/views.py +++ b/vertical_relations/views.py @@ -4,8 +4,10 @@ from django.db import transaction from django.http import JsonResponse from common.decorators import ajax_required, ajax +from unifier.models import UnifiedFrame from unifier.views import unified_frame_2_dict -from vertical_relations.models import UnifiedFrameVerticalRelation, MainVerticalRelation, TemporalVerticalRelation +from vertical_relations.models import UnifiedFrameVerticalRelation, MainVerticalRelation, TemporalVerticalRelation, \ + VerticalRelationNegation, UnifiedFrameArgument2UnifiedFrameArgumentMapping @ajax(method='get', encode_result=True) @@ -34,6 +36,19 @@ def ajax_temporal_vertical_relations(request): return context +@ajax(method='get', encode_result=True) +def ajax_vertical_relation_negations(request): + negations = [] + for negation in VerticalRelationNegation.objects.order_by('priority'): + negations.append({"id": negation.id, "name": negation.name}) + + context = { + 'negations': negations, + } + + return context + + @ajax_required @transaction.atomic def save_main_vertical_relation(request): @@ -53,11 +68,212 @@ def save_main_vertical_relation(request): relation.main_vertical_relation = main_vertical_relation relation.save() + unified_frame = UnifiedFrame.objects.get(id=source_unified_frame_id) + unified_frame.has_vertical_relations = True + unified_frame.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def save_vertical_relation_negation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + unified_frame_argument_id = request.POST['unified_frame_argument_id'] + negation_id = request.POST['negation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.negation_id = negation_id + relation.negation_argument_id = unified_frame_argument_id + + relation.save() + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) return JsonResponse({}) +@ajax_required +@transaction.atomic +def remove_vertical_relation_negation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.negation = None + relation.negation_argument = None + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def save_subrelation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + subrelation_instance_id = request.POST['subrelation_instance_id'] + temporal_vertical_relation_id = request.POST['temporal_vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.subrelation_id = subrelation_instance_id + relation.temporal_vertical_relation_for_subrelation_id = temporal_vertical_relation_id + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def remove_subrelation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.subrelation = None + relation.temporal_vertical_relation_for_subrelation = None + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def save_iter_relation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + temporal_vertical_relation_id = request.POST['temporal_vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.iter_temporal_vertical_relation_id = temporal_vertical_relation_id + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def remove_iter_relation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + vertical_relation_id = request.POST['vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame_id=target_unified_frame_id, + main_vertical_relation_id=vertical_relation_id) + relation.iter_temporal_vertical_relation_id = None + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def save_target_relation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + main_vertical_relation_id = request.POST['vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame=None, + main_vertical_relation_id=main_vertical_relation_id) + relation.target_unified_frame_id = target_unified_frame_id + relation.save() + + source_unified_frame = UnifiedFrame.objects.get(id=source_unified_frame_id) + target_unified_frame = UnifiedFrame.objects.get(id=target_unified_frame_id) + + target_unified_frame_arguments = list(sorted(target_unified_frame.unified_arguments.all(), key=lambda x: x.id)) + source_unified_frame_arguments = list(sorted(source_unified_frame.unified_arguments.all(), key=lambda x: x.id)) + source_unified_frame_arguments_cnt = len(source_unified_frame_arguments) + target_unified_frame_arguments_cnt = len(target_unified_frame_arguments) + for ind in range(source_unified_frame_arguments_cnt): + source_unified_frame_argument = source_unified_frame_arguments[ind] + if ind < target_unified_frame_arguments_cnt: + target_unified_frame_argument = target_unified_frame_arguments[ind] + + unified_frame_argument_slowal_frame_mapping = \ + UnifiedFrameArgument2UnifiedFrameArgumentMapping(unified_frame_vertical_relation=relation, + source_unified_agrument=source_unified_frame_argument, + target_unified_agrument=target_unified_frame_argument) + unified_frame_argument_slowal_frame_mapping.save() + else: + unified_frame_argument_slowal_frame_mapping = \ + UnifiedFrameArgument2UnifiedFrameArgumentMapping(unified_frame_vertical_relation=relation, + source_unified_agrument=source_unified_frame_argument, + target_unified_agrument=None) + unified_frame_argument_slowal_frame_mapping.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id)}) + + return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def remove_target_relation(request): + if request.method == 'POST': + source_unified_frame_id = request.POST['source_unified_frame_id'] + target_unified_frame_id = request.POST['target_unified_frame_id'] + main_vertical_relation_id = request.POST['vertical_relation_id'] + + relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, + target_unified_frame=target_unified_frame_id, + main_vertical_relation_id=main_vertical_relation_id) + + conflict_subrelations = UnifiedFrameVerticalRelation.objects.filter(subrelation=relation) + if not conflict_subrelations.exists(): + relation.target_unified_frame_id = None + relation.negation = None + relation.subrelation = None + relation.temporal_vertical_relation_for_subrelation = None + relation.iter_temporal_vertical_relation = None + UnifiedFrameArgument2UnifiedFrameArgumentMapping.objects.filter(unified_frame_vertical_relation=relation).delete() + relation.save() + + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id), 'succ': True}) + else: + conflict_subrelation = conflict_subrelations.all()[0] + return JsonResponse({'vertical_relation': get_vertical_relation(relation.id), 'succ': False, 'error': 'Nie można usunąć relacji docelowej, ponieważ pozostaje ona w zależnoÅ›ci podrelacji do: ' + str(conflict_subrelation)}) + + return JsonResponse({}) + + @ajax_required @transaction.atomic def save_temporal_vertical_relation(request): @@ -69,6 +285,7 @@ def save_temporal_vertical_relation(request): relation = UnifiedFrameVerticalRelation.objects.get(source_unified_frame_id=source_unified_frame_id, target_unified_frame_id=target_unified_frame_id if target_unified_frame_id else None) + relation.temporal_vertical_relation.clear() for temporal_vertical_relation_id in temporal_vertical_relation_ids: temporal_relation = TemporalVerticalRelation.objects.get(id=temporal_vertical_relation_id) relation.temporal_vertical_relation.add(temporal_relation) @@ -85,7 +302,8 @@ def save_temporal_vertical_relation(request): def load_vertical_relation(request): if request.method == 'POST': vertical_relation_id = request.POST['vertical_relation_id'] - return JsonResponse({'vertical_relation': get_vertical_relation(vertical_relation_id)}) + relation = get_vertical_relation(vertical_relation_id) + return JsonResponse({'vertical_relation': relation}) return JsonResponse({}) @@ -93,7 +311,15 @@ def load_vertical_relation(request): def relation2dict(vertical_relation): return { 'id': vertical_relation.id, - 'is_negated': vertical_relation.is_negated, + 'negation': { + 'id': vertical_relation.negation.id, + 'name': vertical_relation.negation.name, + } if vertical_relation.negation else None, + 'negation_argument': { + 'id': vertical_relation.negation_argument.id, + 'role': vertical_relation.negation_argument.role.role.role, + } if vertical_relation.negation_argument else None, + 'source_unified_frame': unified_frame_2_dict(vertical_relation.source_unified_frame) if vertical_relation.source_unified_frame else None, 'target_unified_frame': unified_frame_2_dict(vertical_relation.target_unified_frame) if vertical_relation.target_unified_frame else None, 'main_vertical_relation': { 'id': vertical_relation.main_vertical_relation.id, @@ -103,11 +329,20 @@ def relation2dict(vertical_relation): 'id': temporal_relation.id, 'name': temporal_relation.name, } for temporal_relation in vertical_relation.temporal_vertical_relation.all()] if vertical_relation.temporal_vertical_relation else None, - 'iterated_target_unified_frame': unified_frame_2_dict(vertical_relation.iterated_target_unified_frame) if vertical_relation.iterated_target_unified_frame else None, - 'iterated_temporal_vertical_relation': [{ - 'id': temporal_relation.id, - 'name': temporal_relation.name, - } for temporal_relation in vertical_relation.iterated_temporal_vertical_relation.all()] if vertical_relation.iterated_temporal_vertical_relation else None, + 'subrelation': relation2dict(vertical_relation.subrelation) if vertical_relation.subrelation else None, + 'temporal_vertical_relation_for_subrelation': { + 'id': vertical_relation.temporal_vertical_relation_for_subrelation.id, + 'name': vertical_relation.temporal_vertical_relation_for_subrelation.name, + } if vertical_relation.temporal_vertical_relation_for_subrelation else None, + 'iter_temporal_vertical_relation': { + 'id': vertical_relation.iter_temporal_vertical_relation.id, + 'name': vertical_relation.iter_temporal_vertical_relation.name, + } if vertical_relation.iter_temporal_vertical_relation else None, + 'unified_frame_arguments_mapping': [{ + 'source_unified_agrument_id': arguments_mapping.source_unified_agrument.id if arguments_mapping.source_unified_agrument else None, + 'target_unified_agrument_id': arguments_mapping.target_unified_agrument.id if arguments_mapping.target_unified_agrument else None, + } for arguments_mapping in vertical_relation.unified_frame_arguments_mapping.all()] if vertical_relation.unified_frame_arguments_mapping else None, + } @@ -122,7 +357,63 @@ def get_vertical_relation(vertical_relation_id): def remove_vertical_relation(request): if request.method == 'POST': vertical_relation_id = request.POST['vertical_relation_id'] - UnifiedFrameVerticalRelation.objects.get(id=vertical_relation_id).delete() + UnifiedFrameArgument2UnifiedFrameArgumentMapping.objects.filter(unified_frame_vertical_relation_id=vertical_relation_id).delete() + relation = UnifiedFrameVerticalRelation.objects.get(id=vertical_relation_id) + source_unified_frame_id = relation.source_unified_frame.id + relation.delete() + + if not UnifiedFrameVerticalRelation.objects.filter(source_unified_frame_id=source_unified_frame_id).exists(): + unified_frame = UnifiedFrame.objects.get(id=source_unified_frame_id) + unified_frame.has_vertical_relations = False + unified_frame.save() + return JsonResponse({}) return JsonResponse({}) + + +@ajax_required +@transaction.atomic +def change_argument_mapping(request): + if request.method == 'POST': + vertical_relation_id = request.POST['vertical_relation_id'] + slowal_frame_selected_arguments = json.loads(request.POST['selected_arguments']) + + relation = UnifiedFrameVerticalRelation.objects.get(id=vertical_relation_id) + + arg1_unified_frame_argument_id = int(slowal_frame_selected_arguments[0]['unified_frame_argument_id']) + arg1_id = int(slowal_frame_selected_arguments[0]['id']) + + arg2_unified_frame_argument_id = int(slowal_frame_selected_arguments[1]['unified_frame_argument_id']) + arg2_id = int(slowal_frame_selected_arguments[1]['id']) + + unified_frame_argument_mapping1f = UnifiedFrameArgument2UnifiedFrameArgumentMapping.objects.filter( + unified_frame_vertical_relation=relation, + source_unified_agrument_id=arg1_unified_frame_argument_id) + unified_frame_argument_mapping2f = UnifiedFrameArgument2UnifiedFrameArgumentMapping.objects.filter( + unified_frame_vertical_relation=relation, + source_unified_agrument_id=arg2_unified_frame_argument_id) + + unified_frame_argument_mapping1 = unified_frame_argument_mapping1f[0] if unified_frame_argument_mapping1f and unified_frame_argument_mapping1f.exists() else None + unified_frame_argument_mapping2 = unified_frame_argument_mapping2f[0] if unified_frame_argument_mapping2f and unified_frame_argument_mapping2f.exists() else None + + if unified_frame_argument_mapping1 is not None and unified_frame_argument_mapping2 is not None: + # mamy oba argumenty, zamieniamy miescami + unified_frame_argument_mapping1.target_unified_agrument_id = arg2_id if arg2_id >= 0 else None + unified_frame_argument_mapping2.target_unified_agrument_id = arg1_id if arg1_id >= 0 else None + unified_frame_argument_mapping1.save() + unified_frame_argument_mapping2.save() + elif unified_frame_argument_mapping1 is not None and unified_frame_argument_mapping2 is None: + # mamy lewy argument, prawy jest Empty + unified_frame_argument_mapping1.target_unified_agrument_id = arg2_id if arg2_id >= 0 else None + unified_frame_argument_mapping1.save() + elif unified_frame_argument_mapping1 is None and unified_frame_argument_mapping2 is not None: + # mamy prawy argument, lewy jest Empty + unified_frame_argument_mapping2.target_unified_agrument_id = arg1_id if arg1_id >= 0 else None + unified_frame_argument_mapping2.save() + + relation = get_vertical_relation(vertical_relation_id) + return JsonResponse({'vertical_relation': relation}) + + return JsonResponse({}) + -- GitLab