diff --git a/entries/static/entries/js/components/LexicalUnitDisplay.js b/entries/static/entries/js/components/LexicalUnitDisplay.js index 99b3fcb279c23f0dccb34c0f4f2cdc88d1d04f98..98af15685d26ed6117fc7c590a33689e6b946107 100644 --- a/entries/static/entries/js/components/LexicalUnitDisplay.js +++ b/entries/static/entries/js/components/LexicalUnitDisplay.js @@ -2,10 +2,11 @@ import Spinner from './Spinner.js'; import SemanticsSchemataComponent from "./frame-components/SemanticsSchemataComponent.js"; import ExamplesComponent from "./frame-components/ExamplesComponent.js"; import SlowalFrameComponent from "./frame-components/SlowalFrameComponent.js"; +import MeaningComponent from "./frame-components/MeaningComponent.js"; export default { - components: { Spinner, SemanticsSchemataComponent, ExamplesComponent, SlowalFrameComponent }, + components: { Spinner, SemanticsSchemataComponent, ExamplesComponent, SlowalFrameComponent, MeaningComponent }, props: { entryId: Number, lexicalUnitId: Number @@ -22,8 +23,10 @@ export default { realisation_descriptions: null, examples: null, selectedFrameArguments: null, + selectedExampleFrameArguments: null, selectedLus: null, - selectedSchemas: null + selectedSchemas: null, + selectedExamples: null, } }, emits: ['refresh', 'refreshEntriesList'], @@ -111,41 +114,57 @@ export default { setup_notes () { setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), this.lexicalUnitId, 'meanings.LexicalUnit', this.setup_notes); }, - frameSelectionChanged (selectedFrameArguments, selectedLus) { + meaningLuSelected(selectedLus) { this.selectedLus = selectedLus; + }, + frameSelectionChanged (selectedFrameArguments) { this.selectedFrameArguments = selectedFrameArguments; }, schemataSelected(schemas) { this.selectedSchemas = schemas; }, + exampleSelected(selectedExamples) { + this.selectedExamples = selectedExamples; + }, setup () { $('#lexical-unit-notes').html(''); - var data = { 'entry' : this.entryId, 'no_filters' : false, 'lexical_unit_id': this.lexicalUnitId }; - $.ajax({ - type : 'post', - url : '/' + lang + '/entries/get_entry/', - dataType : 'json', - data : data, - timeout : 60000, - success : function(response) { - - window.clear_info(); - this.frame = response.frames[0]; - this.unifiedFrame = response.unified_frame; - this.subentries = response.subentries; - this.alternations = response.alternations; - this.realisation_phrases = response.realisation_phrases; - this.realisation_descriptions = response.realisation_descriptions; - this.examples = response.examples; - - window.update_last_visited(response.last_visited); - window.setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), this.lexicalUnitId, 'meanings.LexicalUnit', this.setup_notes); - }.bind(this), - error: function(request, errorType, errorMessage) { - show_error(errorType + ' (' + errorMessage + ')'); - } + get_entry(this.entryId, false, this.lexicalUnitId).then(entry => { + this.frame = entry.frames[0]; + this.unifiedFrame = entry.unified_frame; + this.subentries = entry.subentries; + this.alternations = entry.alternations; + this.realisation_phrases = entry.realisation_phrases; + this.realisation_descriptions = entry.realisation_descriptions; + this.examples = entry.examples; + setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), this.lexicalUnitId, 'meanings.LexicalUnit', this.setup_notes); }); + + // var data = { 'entry' : this.entryId, 'no_filters' : false, 'lexical_unit_id': this.lexicalUnitId }; + // $.ajax({ + // type : 'post', + // url : '/' + lang + '/entries/get_entry/', + // dataType : 'json', + // data : data, + // timeout : 60000, + // success : function(response) { + // + // window.clear_info(); + // this.frame = response.frames[0]; + // this.unifiedFrame = response.unified_frame; + // this.subentries = response.subentries; + // this.alternations = response.alternations; + // this.realisation_phrases = response.realisation_phrases; + // this.realisation_descriptions = response.realisation_descriptions; + // this.examples = response.examples; + // + // window.update_last_visited(response.last_visited); + // window.setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), this.lexicalUnitId, 'meanings.LexicalUnit', this.setup_notes); + // }.bind(this), + // error: function(request, errorType, errorMessage) { + // show_error(errorType + ' (' + errorMessage + ')'); + // } + // }); } }, mounted () { @@ -170,11 +189,23 @@ export default { <div id="main-frames-pane" class="row"> <div class="col h-100 pl-3 pr-1 pt-0 pb-2 overflow-auto" id="semantics-frames-pane"> <spinner /> + <div id="semantics-frames"></div> <div id="vue-semantics-frames" v-if="frame"> - <slowal-frame-component - :frame="frame" :key="frame" - @frame-selection-changed="frameSelectionChanged" - /> + <div class="frame mb-3 active"> + <div class="frame mt-0" id="lexical-unit"> + <meaning-component + :key="frame.lexical_units" + :lexicalUnits="frame.lexical_units" + @meaning-lu-selected="meaningLuSelected" + ></meaning-component> + </div> + <slowal-frame-component + :frame="frame" + :key="frame" + :selectedExamples="selectedExamples" + @frame-selection-changed="frameSelectionChanged" + /> + </div> </div> <div class="text-center mb-3"> @@ -221,11 +252,27 @@ export default { :alternations="alternations" :realisation_phrases="realisation_phrases" :realisation_descriptions="realisation_descriptions" + :selectedExamples="selectedExamples" @schemata-selected="schemataSelected" /> + <div id="semantics-schemata"></div> </div> </div> <div id="vue-examples" class="row overflow-auto"> + <div class="col w-100 p-0 tab-pane overflow-auto" id="examples"> + <table id="semantics-examples" class="table table-sm table-hover"> + <thead> + <tr> + <th scope="col">{{ gettext("Przykład") }}<i id="examples-argument"></i><i id="examples-lu"></i><i id="examples-schema"></i></th> + <th scope="col">{{ gettext("Źródło") }}</th> + <th scope="col">{{ gettext("Opinia") }}</th> + </tr> + </thead> + <tbody id="semantics-examples-list"> + </tbody> + </table> + <p class="mx-1 my-1" id="semantics-no-examples">{{ gettext("Brak przykładów") }}</p> + </div> <div class="col w-100 pr-4 overflow-auto"> <examples-component v-if="examples" :examples="examples" @@ -234,6 +281,7 @@ export default { :lus="selectedLus" :schemas="selectedSchemas" :key="examples" + @example-selected="exampleSelected" /> </div> </div> diff --git a/entries/static/entries/js/components/LexicalUnitEdit.js b/entries/static/entries/js/components/LexicalUnitEdit.js index 2556cbba142468dbf35d06f96985760de9f820f6..119325dcbaddffff8fee24f56826ba285c064842 100644 --- a/entries/static/entries/js/components/LexicalUnitEdit.js +++ b/entries/static/entries/js/components/LexicalUnitEdit.js @@ -4,6 +4,7 @@ import UnificationSwitchableList from "./UnificationSwitchableList.js"; import ExamplesComponent from "./frame-components/ExamplesComponent.js"; import SlowalFrameComponent from "./frame-components/SlowalFrameComponent.js"; import SemanticsSchemataComponent from "./frame-components/SemanticsSchemataComponent.js"; +import MeaningComponent from "./frame-components/MeaningComponent.js"; let LexicalUnitEdit = {}; @@ -102,10 +103,11 @@ Object.assign(LexicalUnitEdit, { frame_arguments_or_type: false, selectedLus: null, selectedSchemas: null, + selectedExamples: null, hidden_frames: [], } }, - components: {InfoTooltip, Spinner, FramePreview, SlowalFrameComponent, ExamplesComponent, SemanticsSchemataComponent}, + components: {InfoTooltip, Spinner, FramePreview, SlowalFrameComponent, ExamplesComponent, SemanticsSchemataComponent, MeaningComponent}, emits: ['goToDisplay', 'refresh', 'swapFrames', 'refreshEntriesList', 'clearUnifiedFrameView'], watch: { forceRefresh(newVal, oldVal) { @@ -720,9 +722,13 @@ Object.assign(LexicalUnitEdit, { argument.selected = false; }); }); + this.examples.forEach(example => { + example.selected = false; + }); this.selectedLus = []; this.selectedFrameArguments = []; this.selectedSchemas = []; + this.selectedExamples = []; }, slowalFrameSelected(frame) { this.deselectSlowalFrameSelectedElements(); @@ -837,13 +843,18 @@ Object.assign(LexicalUnitEdit, { getArgumentCSS(argument) { return (argument.role ? argument.role.str + ' ' : '') + (argument == this.active_unified_frame_argument ? 'active' : ''); }, - insideFrameSelectionChanged (selectedFrameArguments, selectedLus) { + meaningLuSelected(selectedLus) { this.selectedLus = selectedLus; + }, + insideFrameSelectionChanged (selectedFrameArguments) { this.selectedFrameArguments = selectedFrameArguments; }, schemataSelected(schemas) { this.selectedSchemas = schemas; }, + exampleSelected(selectedExamples) { + this.selectedExamples = selectedExamples; + }, deleteUnifiedFrames() { if (!confirm(gettext("Czy na pewno chcesz zunifikowaną ramę?"))) return false; $.ajax({ @@ -1075,10 +1086,22 @@ Object.assign(LexicalUnitEdit, { @click="slowalFrameSelected(frame)" :class="frame === active_slowal_frame ? 'active-frame' : frame.hover ? 'bg-highlight' : ''" > - <slowal-frame-component - :frame="frame" :key="frame" - @frame-selection-changed="insideFrameSelectionChanged" - /> + <div class="frame mb-3 active"> + <div class="frame mt-0" id="lexical-unit"> + <meaning-component + :key="frame.lexical_units" + :lexicalUnits="frame.lexical_units" + :selectedExamples="selectedExamples" + @meaning-lu-selected="meaningLuSelected" + ></meaning-component> + </div> + <slowal-frame-component + :frame="frame" + :key="frame" + :selectedExamples="selectedExamples" + @frame-selection-changed="insideFrameSelectionChanged" + /> + </div> </div> <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="col pl-0 pt-4" style="max-width: 60px;"> <div class="row"> @@ -1120,6 +1143,7 @@ Object.assign(LexicalUnitEdit, { :lus="selectedLus" :schemas="selectedSchemas" :key="examples" + @example-selected="exampleSelected" /> <!-- <table id="semantics-examples" class="table table-sm table-hover">--> <!-- <thead>--> @@ -1154,6 +1178,7 @@ Object.assign(LexicalUnitEdit, { :alternations="alternations" :realisation_phrases="realisation_phrases" :realisation_descriptions="realisation_descriptions" + :selectedExamples="selectedExamples" @schemata-selected="schemataSelected" /> </div> diff --git a/entries/static/entries/js/components/frame-components/ExamplesComponent.js b/entries/static/entries/js/components/frame-components/ExamplesComponent.js index 3a384d8ee154aaf30ed12918a55de215dfc95893..81ff812bcc524d306a81605638949cd65e3c3c02 100644 --- a/entries/static/entries/js/components/frame-components/ExamplesComponent.js +++ b/entries/static/entries/js/components/frame-components/ExamplesComponent.js @@ -15,6 +15,7 @@ export default { img_prefix: String } }, + emits: ['exampleSelected'], methods: { getExamples () { let ret = this.examples; @@ -40,6 +41,10 @@ export default { }, getSchemaStr(schema) { return schema.positions.map(e => e.phrases.map(p => p.str).join(",")).join('|'); + }, + selectExample(example) { + example.selected = !example.selected; + this.$emit('exampleSelected', this.examples.filter(example => example.selected)); } }, mounted () { @@ -63,16 +68,21 @@ export default { </tr> </thead> <tbody id="semantics-examples-list"> - - <tr v-for="example in getExamples()" class="example"> - <td class="py-1"> - {{example.sentence}} - <info-tooltip v-if="example.note" :text="example.note" /> - </td> - <td class="py-1">{{example.source}}</td> - <td class="py-1">{{example.opinion}}</td> - </tr> - + <template v-for="example in getExamples()"> + <tr class="example" + @mouseenter="example.hover=true" + @mouseleave="example.hover=false" + @click.stop="selectExample(example)" + :class="example.selected ? 'active table-primary' : example.hover ? 'bg-highlight' : ''" + > + <td class="py-1"> + {{example.sentence}} + <info-tooltip v-if="example.note" :text="example.note" /> + </td> + <td class="py-1">{{example.source}}</td> + <td class="py-1">{{example.opinion}}</td> + </tr> + </template> </tbody> </table> <p v-else class="mx-1 my-1" id="semantics-no-examples" style="display: none;">Brak przykładów</p> diff --git a/entries/static/entries/js/components/frame-components/MeaningComponent.js b/entries/static/entries/js/components/frame-components/MeaningComponent.js index faefcf9e84bf72e78992bb3b4916f934987d470e..d497ec18e0fef485cd0b5174434eea6762305579 100644 --- a/entries/static/entries/js/components/frame-components/MeaningComponent.js +++ b/entries/static/entries/js/components/frame-components/MeaningComponent.js @@ -3,6 +3,7 @@ import InfoTooltip from "../InfoTooltip.js"; export default { props: { lexicalUnits: Object, + selectedExamples: Object }, emits: ['meaningLuSelected'], data () { diff --git a/entries/static/entries/js/components/frame-components/SemanticsSchemataComponent.js b/entries/static/entries/js/components/frame-components/SemanticsSchemataComponent.js index b72993d168fed225731456505ec33f7c4431bda8..9f1d160d3841e8c830221e0024d32c0a89bf1501 100644 --- a/entries/static/entries/js/components/frame-components/SemanticsSchemataComponent.js +++ b/entries/static/entries/js/components/frame-components/SemanticsSchemataComponent.js @@ -7,6 +7,7 @@ export default { alternations: Object, realisation_phrases: Object, realisation_descriptions: Object, + selectedExamples: Object }, components: {InfoTooltip}, emits: ['schemataSelected'], @@ -43,8 +44,8 @@ export default { } return '<i>' + alternationDescList + '</i>'; }, - getRoleCss(schema, position) { - const roles = []; + getPhraseCss(schema, position) { + const styles = []; if(this.alternations) { const argumentIdSet = new Set(); @@ -65,11 +66,16 @@ export default { argumentIdSet.forEach(argumentId => { const argument = this.frame.arguments.find(arg => argumentId.endsWith(arg.argument_id)); const role = argument.role; - roles.push(role); + styles.push(role); }); } - return roles; + const selectedExampleFrameArguments = this.selectedExamples && this.selectedExamples.length > 0 ? new Set(this.selectedExamples.map(e => e.positions).flat()) : null; + + if(selectedExampleFrameArguments != null) { + styles.push(selectedExampleFrameArguments.has(position.id) ? 'example-yes' : 'example-no'); + } + return styles; }, getPositionPhrases(schema, position) { const phrases = []; @@ -148,7 +154,7 @@ export default { <th scope="row" class="py-0 px-1 text-secondary">Typy fraz</th> <td v-for="position in schema.positions" class="px-0 py-0 border-top border-left border-secondary"> <div v-for="phrase in position.phrases" class="phrase px-1 py-2" - :class="getRoleCss(schema, position)"> + :class="getPhraseCss(schema, position)"> <info-tooltip :text="phrase.desc" :visibleText="phrase.str"/> </div> <div v-for="phrase in getPositionPhrases(schema, position)" class="realisation-phrase px-1 py-2"><i>{{phrase}}</i></div> diff --git a/entries/static/entries/js/components/frame-components/SlowalFrameComponent.js b/entries/static/entries/js/components/frame-components/SlowalFrameComponent.js index 71e985b4b34016de848d98cdb059f45181f8f933..f7fec2a7420604ef9d85479e6ce01fa8b9164dce 100644 --- a/entries/static/entries/js/components/frame-components/SlowalFrameComponent.js +++ b/entries/static/entries/js/components/frame-components/SlowalFrameComponent.js @@ -1,16 +1,15 @@ import InfoTooltip from "../InfoTooltip.js"; -import MeaningComponent from "./MeaningComponent.js"; export default { props: { frame: Object, + selectedExamples: Object }, - components: {InfoTooltip, MeaningComponent}, + components: {InfoTooltip}, emits: ['frameSelectionChanged'], data() { return { img_prefix: String, - selectedLus: null } }, methods: { @@ -24,70 +23,60 @@ export default { getArguments() { return this.frame.arguments; }, - triggerSelectedEvent() { - const selectedLus = this.frame.lexical_units.filter(lu => lu.selected); - const selectedArguments = this.frame.arguments.filter(argument => argument.selected) - this.$emit('frameSelectionChanged', selectedArguments, selectedLus); - }, - meaningLuSelected(selectedLus) { - this.triggerSelectedEvent(); - }, selectArgument(argument) { argument.selected = !argument.selected; - this.triggerSelectedEvent(); + 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' : ''); } }, mounted () { this.img_prefix = window.STATIC_URL; }, template: ` - <div class="frame mb-3 active"> - <div class="frame mt-0" id="lexical-unit"> - <meaning-component - :lexicalUnits="frame.lexical_units" - @meaning-lu-selected="meaningLuSelected" - ></meaning-component> - </div> - <table class="table m-0 table-borderless border border-secondary text-dark"> - <tbody> - <tr class="opinion-row" v-html="getOpinionHTML()"> - </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="argument.role + ' ' + (argument.selected ? 'active' : argument.hover ? 'bg-highlight' : '')" - > - {{argument.str}} - </td> - </template> - </tr> - <tr> - <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' : ''" + <table class="table m-0 table-borderless border border-secondary text-dark"> + <tbody> + <tr class="opinion-row" v-html="getOpinionHTML()"> + </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)" > - <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> - </td> + {{argument.str}} + </td> + </template> + </tr> + <tr> + <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> - </div> + </td> + </template> + </tr> + </tbody> + </table> ` }