diff --git a/entries/static/entries/js/components/LexicalUnitDisplay.js b/entries/static/entries/js/components/LexicalUnitDisplay.js index dd27685d646977cb1e5acd54ffaf129e69b9d312..a1bbbce6948bd242aa9452390a592c51076de7d3 100644 --- a/entries/static/entries/js/components/LexicalUnitDisplay.js +++ b/entries/static/entries/js/components/LexicalUnitDisplay.js @@ -1,15 +1,95 @@ +import Spinner from './Spinner.js'; + export default { + components: {Spinner}, props: { + entryId: Number, lexicalUnitId: Number }, data() { - return { count: 0 } + return { frame: null, unifiedFrame: undefined, gettext: window.gettext, hasPermission: window.has_permission } }, + emits: ['goToEdit', 'refresh'], methods: { - clicked () { - this.count++; - addSelectivePreference(); + markAsInvalid () { + $.ajax({ + type: 'post', + url: `/${lang}/semantics/frame_mark_as_invalid/${this.frame.id}/`, + dataType: 'json', + timeout: 60000, + }).then(() => { this.$emit('refresh'); }); + }, + take () { + $.ajax({ + type : 'post', + url : `/${lang}/semantics/frame_assign/${this.frame.id}/`, + dataType : 'json', + timeout : 60000, + }).then(() => { this.$emit('goToEdit'); }); + }, + confirmInvalid () { + $.ajax({ + type: 'post', + url: `/${lang}/semantics/frame_confirm_invalid/${this.frame.id}/`, + dataType: 'json', + timeout: 60000, + }).then(() => { this.$emit('refresh'); }); + }, + rejectInvalid () { + $.ajax({ + type: 'post', + url: `/${lang}/semantics/frame_reject_invalid/${this.frame.id}/`, + dataType: 'json', + timeout: 60000, + }).then(() => { this.$emit('refresh'); }); } }, - template: `<div @click="clicked">display {{ lexicalUnitId }} is {{ count }}</div> <div @click="$emit('goToEdit')">idź do edycji</div>` + created () { + $('#lexical-unit-notes').html(''); + get_entry(this.entryId, false, this.lexicalUnitId).then(entry => { + this.frame = entry.frames[0]; + this.unifiedFrame = entry.unified_frame; + setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), this.lexicalUnitId, this.entryId); + }); + }, + template: ` + <spinner /> + <div id="semantics-frames"></div> + <div class="text-center mb-3"> + <div v-if="unifiedFrame"> + <a class="btn btn-sm btn-outline-dark mr-2" v-if="frame?.status === 'N'" @click="markAsInvalid">{{ gettext('Błędna') }}</a> + <a class="btn btn-sm btn-outline-dark mr-2" v-if="frame?.status === 'N'" @click="take">{{ gettext('Pobierz') }}</a> + <a + class="btn btn-sm btn-outline-dark mr-2" + v-if="frame?.status === 'O' || frame?.status === 'G' && unifiedFrame?.status === 'O'" + @click="$emit('goToEdit')" + > + {{ gettext('Obrabiaj') }} + </a> + <a + class="btn btn-sm btn-outline-dark mr-2" + v-if="frame?.status === 'S' && unifiedFrame?.status === 'S'" + @click="$emit('goToEdit')" + > + {{ gettext('Obejrzyj') }} + </a> + <a + class="btn btn-sm btn-outline-dark mr-2" + v-if="frame?.status === 'B' && hasPermission('semantics.manage_invalid_lexical_units')" + @click="confirmInvalid" + > + {{ gettext('Potwierdź') }} + </a> + <a + class="btn btn-sm btn-outline-dark mr-2" + v-if="frame?.status === 'B' && hasPermission('semantics.manage_invalid_lexical_units')" + @click="rejectInvalid" + > + {{ gettext('Odrzuć') }} + </a> + </div> + <span v-if="unifiedFrame === null">{{ gettext('Brak ramy unifikacyjnej') }}</span> + </div> + <div id="lexical-unit-notes"></div> + ` } diff --git a/entries/static/entries/js/components/Spinner.js b/entries/static/entries/js/components/Spinner.js new file mode 100644 index 0000000000000000000000000000000000000000..a4ac913a5ac7bf63b5db38266f9846e9839850cf --- /dev/null +++ b/entries/static/entries/js/components/Spinner.js @@ -0,0 +1,12 @@ +export default { + data() { + return { gettext: window.gettext } + }, + template: ` + <div class="d-flex justify-content-center wait-spinner"> + <div class="spinner-border text-primary m-5" style="width: 3rem; height: 3rem;" role="status"> + <span class="sr-only">{{ gettext('Proszę czekać...') }}</span> + </div> + </div> + ` +} diff --git a/entries/static/entries/js/components/main.js b/entries/static/entries/js/components/main.js index 4f2d4ddb92a43d36e49b0286b43ed60fcfe455a5..46fbc9da47df0bcc55bf1c583137b63ab5913d29 100644 --- a/entries/static/entries/js/components/main.js +++ b/entries/static/entries/js/components/main.js @@ -2,42 +2,47 @@ import LexicalUnitDisplay from './LexicalUnitDisplay.js'; import LexicalUnitEdit from './LexicalUnitEdit.js'; export default { + components: {LexicalUnitDisplay, LexicalUnitEdit}, props: { - lexicalUnitId: Number + entryId: Number, + lexicalUnitId: Number, }, data () { return this.getInitialData(); }, methods: { getInitialData () { - return { isEdit: false } + return { isEdit: false, key: this.lexicalUnitId }; }, goToEdit () { this.isEdit = true; - } - }, - computed: { - leftPaneComponent () { - if (!this.lexicalUnitId) return null; - if (this.isEdit) return LexicalUnitEdit; - return LexicalUnitDisplay; }, - leftPaneComponentProps () { - return { - lexicalUnitId: this.lexicalUnitId - }; + refresh () { + this.key = null; + setTimeout(() => { this.key = this.lexicalUnitId; }, 0); + update_entries(); } }, watch: { lexicalUnitId () { - const freshData = this.getInitialData(); - Object.keys(freshData).map(key => { - this[key] = freshData[key]; - }); + Object.assign(this, this.getInitialData()); } }, template: ` - <div @click="isEdit = !isEdit">kliknij mnie, jestem LU {{ this.lexicalUnitId }}</div> - <component :is="leftPaneComponent" v-bind="leftPaneComponentProps" @go-to-edit="goToEdit" /> + <div class="col h-100 px-1 pt-0 pb-2 overflow-auto" id="semantics-frames-pane"> + <div v-if="key" :key="key"> + <lexical-unit-display + v-if="lexicalUnitId && !isEdit" + :entryId="entryId" + :lexicalUnitId="lexicalUnitId" + @go-to-edit="goToEdit" + @refresh="refresh" + /> + <lexical-unit-edit v-if="isEdit" :lexicalUnitId="lexicalUnitId" /> + </div> + </div> + <div class="col h-100 px-1 pt-0 pb-0 overflow-auto" id="semantics-schemata-pane"> + <div id="semantics-schemata"></div> + </div> ` } diff --git a/entries/static/entries/js/unification_entries_list.js b/entries/static/entries/js/unification_entries_list.js index dd8b00b95c4b044681f9600447f2c39297d942be..4589fba051c857c19875ed7cc10ba286a0608758 100644 --- a/entries/static/entries/js/unification_entries_list.js +++ b/entries/static/entries/js/unification_entries_list.js @@ -51,8 +51,8 @@ function setup_lexical_units_table(drilldown, lexical_units, can_see_assignees) </tr> `).click(function () { $(this).addClass('table-primary').siblings().removeClass("table-primary"); + window.unificationApp.$.props.entryId = $(drilldown.data("row")).data("entry"); window.unificationApp.$.props.lexicalUnitId = lexical_unit.pk; - get_lexical_unit(lexical_unit.pk, $(drilldown.data("row")).data("entry")); }); } var table = $(` @@ -83,7 +83,6 @@ function setup_notes($container, $template, lexical_unit_pk, entry_pk) { $('.note-form', $container).html($('#note-form-template > div', $container).clone()); $('.hide-note-form', $container).click(function () { $('.note-form', $container).html(''); }); $('.add-note', $container).click(function () { - console.log($('textarea[name=note]', $container).val()); $.ajax({ type : 'post', url : $('#note-form-template').data('url').replace('MODEL', 'meanings.LexicalUnit').replace('PK', lexical_unit_pk), @@ -91,7 +90,7 @@ function setup_notes($container, $template, lexical_unit_pk, entry_pk) { data : { note: $('.note-form textarea[name=note]').val() }, timeout : 5000, success : function (response) { - get_lexical_unit(lexical_unit_pk, entry_pk); + window.unificationApp.refresh(); }, error : function () { alert(gettext('Nie udało się dodać notatki.')); @@ -110,77 +109,3 @@ function setup_notes($container, $template, lexical_unit_pk, entry_pk) { } }) } - -function setup_unified_frame($container, frame, unified_frame, refresh) { - $container.html(''); - if (unified_frame) { - var $button_container = $('<div>').addClass("text-center"); - var $button = $('<a>').addClass('btn btn-sm btn-outline-dark mr-2'); - function go_to_unified_frame () { - window.location = `/${window.lang}/entries/unification_frames`; // TODO redirect properly - } - function invalid () { - $.ajax({ - type : 'post', - url : `/${lang}/semantics/frame_mark_as_invalid/${frame.id}/`, - dataType : 'json', - timeout : 60000, - }).then(refresh); - } - function take () { - $.ajax({ - type : 'post', - url : `/${lang}/semantics/frame_assign/${frame.id}/`, - dataType : 'json', - timeout : 60000, - }).then(go_to_unified_frame); - } - function confirm_invalid () { - $.ajax({ - type : 'post', - url : `/${lang}/semantics/frame_confirm_invalid/${frame.id}/`, - dataType : 'json', - timeout : 60000, - }).then(refresh); - } - function reject_invalid () { - $.ajax({ - type : 'post', - url : `/${lang}/semantics/frame_reject_invalid/${frame.id}/`, - dataType : 'json', - timeout : 60000, - }).then(refresh); - } - if (frame.status === 'N') { - $button_container.append($button.clone().html(gettext("Błędna")).click(invalid)); - $button_container.append($button.clone().html(gettext("Pobierz")).click(take)); - } else if (frame.status === 'O') { - $button_container.append($button.clone().html(gettext("Obrabiaj")).click(go_to_unified_frame)); - } else if (frame.status === 'G' && unified_frame.status === 'O') { - $button_container.append($button.clone().html(gettext("Obrabiaj")).click(go_to_unified_frame)); - } else if (frame.status === 'S' && unified_frame.status === 'S') { - $button_container.append($button.clone().html(gettext("Obejrzyj")).click(go_to_unified_frame)); - } else if (frame.status === 'B' && has_permission('semantics.manage_invalid_lexical_units')) { - $button_container.append($button.clone().html(gettext("Potwierdź")).click(confirm_invalid)); - $button_container.append($button.clone().html(gettext("Odrzuć")).click(reject_invalid)); - } - $container.append($button_container); - } else { - $container.append($('<p>').html(gettext("Brak ramy unifikacyjnej."))); - } -} - -function get_lexical_unit(lexical_unit_pk, entry_pk) { - $('#lexical-unit-notes').html(''); - $('#unified-frame').html(''); - get_entry(entry_pk, false, lexical_unit_pk).then(function (entry) { - var frame = entry.frames[0]; - setup_unified_frame( - $('#unified-frame'), - frame, - entry.unified_frame, - function () { get_lexical_unit(lexical_unit_pk, entry_pk); update_entries(); } - ); - setup_notes($('#lexical-unit-notes'), $('#lexical-unit-notes-template'), lexical_unit_pk, entry_pk); - }); -} diff --git a/entries/static/entries/js/unification_index.js b/entries/static/entries/js/unification_index.js index ac4cd9f63c36bbfb77cb811addfc7dced7424c6c..227b3b6beeefdb652b10c9f7c750e992f28e144c 100644 --- a/entries/static/entries/js/unification_index.js +++ b/entries/static/entries/js/unification_index.js @@ -1,4 +1,4 @@ import Main from './components/main.js'; const { createApp } = Vue; -window.unificationApp = createApp(Main).mount('#app'); +window.unificationApp = createApp(Main).mount('#semantics-top-pane'); diff --git a/entries/templates/unification_lexical_unit_display.html b/entries/templates/unification_lexical_unit_display.html index 0db26ffaa12a1abf5fd06901c25c1e51f8db7afc..fbf28ae628cc0dd039bad136bf92e35974f96a69 100644 --- a/entries/templates/unification_lexical_unit_display.html +++ b/entries/templates/unification_lexical_unit_display.html @@ -1,71 +1,61 @@ {% load i18n static %} -<script src="https://unpkg.com/vue@3"></script> -<script src="https://unpkg.com/vuex@3"></script> -<!--<script type="module" src="https://unpkg.com/vue-axios@3/dist/vue-axios.min.js"></script>--> -<script src="https://unpkg.com/axios/dist/axios.min.js"></script> -<div id="app"></div> -<script type="module" src="{% static 'entries/js/unification_index.js' %}"></script> +<div id="lexical-unit-notes-template" class="d-none">{% include 'notes.html' %}</div> -<!--<div class="tab-content h-100 w-100 p-0" id="entryTabsContent">--> -<!-- <div class="col h-100 w-100 p-0 tab-pane show active" id="semantics" role="tabpanel" aria-labelledby="semantics-tab">--> -<!-- <div class="row m-0 p-0" id="semantics-top-pane">--> -<!-- <div class="col h-100 px-1 pt-0 pb-0 overflow-auto" id="semantics-frames-pane">--> -<!-- <div id="semantics-frames"></div>--> -<!-- <div id="unified-frame" class="mb-3"></div>--> -<!-- <div id="lexical-unit-notes-template" class="d-none">{% include 'notes.html' %}</div>--> -<!-- <div id="lexical-unit-notes"></div>--> -<!-- </div>--> -<!-- <div class="col h-100 px-1 pt-0 pb-0 overflow-auto" id="semantics-schemata-pane">--> -<!-- <div id="semantics-schemata"></div>--> -<!-- </div>--> -<!-- </div>--> -<!-- <div class="row m-0 p-0 overflow-auto" id="semantics-examples-pane">--> -<!-- <table id="semantics-examples" class="table table-sm table-hover">--> -<!-- <thead>--> -<!-- <tr>--> -<!-- <th scope="col">{% trans "Przykład" %}<i id="examples-argument"></i><i id="examples-lu"></i><i id="examples-schema"></i></th>--> -<!-- <th scope="col">{% trans "Źródło" %}</th>--> -<!-- <th scope="col">{% trans "Opinia" %}</th>--> -<!-- </tr>--> -<!-- </thead>--> -<!-- <tbody id="semantics-examples-list">--> -<!-- </tbody>--> -<!-- </table>--> -<!-- <p class="mx-1 my-1"id="semantics-no-examples">{% trans "Brak przykładów" %}</p>--> -<!-- </div>--> -<!-- </div>--> -<!-- <div class="col h-100 w-100 p-0 tab-pane" id="syntax" role="tabpanel" aria-labelledby="syntax-tab">--> -<!-- <div class="col w-100 px-1 pt-0 pb-0 overflow-auto" id="syntax-schemata-pane">--> -<!-- <div id="syntax-schemata"></div>--> -<!-- </div>--> -<!-- <div class="col w-100 p-0 overflow-auto" id="syntax-examples-pane">--> -<!-- <table id="syntax-examples" class="table table-sm table-hover">--> -<!-- <thead>--> -<!-- <tr>--> -<!-- <th scope="col">{% trans "Przykład" %}</th>--> -<!-- <th scope="col">{% trans "Źródło" %}</th>--> -<!-- <th scope="col">{% trans "Opinia" %}</th>--> -<!-- </tr>--> -<!-- </thead>--> -<!-- <tbody id="syntax-examples-list">--> -<!-- </tbody>--> -<!-- </table>--> -<!-- <p class="mx-1 my-1"id="syntax-no-examples">{% trans "Brak przykładów" %}</p>--> -<!-- </div>--> -<!-- </div>--> -<!-- <div class="col h-100 w-100 p-0 tab-pane" id="examples" role="tabpanel" aria-labelledby="examples-tab">--> -<!-- <table id="unmatched-examples" class="table table-sm table-hover">--> -<!-- <thead>--> -<!-- <tr>--> -<!-- <th scope="col">{% trans "Przykład" %}</th>--> -<!-- <th scope="col">{% trans "Źródło" %}</th>--> -<!-- <th scope="col">{% trans "Opinia" %}</th>--> -<!-- </tr>--> -<!-- </thead>--> -<!-- <tbody id="unmatched-examples-list">--> -<!-- </tbody>--> -<!-- </table>--> -<!-- <p class="mx-1 my-1"id="unmatched-no-examples">{% trans "Brak przykładów" %}</p>--> -<!-- </div>--> -<!--</div>--> +<div class="tab-content h-100 w-100 p-0" id="entryTabsContent"> + <div class="col h-100 w-100 p-0 tab-pane show active" id="semantics" role="tabpanel" aria-labelledby="semantics-tab"> + <!-- Vue.js app --> + <script src="https://unpkg.com/vue@3"></script> + <div class="row m-0 p-0 overflow-auto" id="semantics-top-pane"></div> + <script type="module" src="{% static 'entries/js/unification_index.js' %}"></script> + <!-- Vue.js app --> + + <div class="row m-0 p-0 overflow-auto" id="semantics-examples-pane"> + <table id="semantics-examples" class="table table-sm table-hover"> + <thead> + <tr> + <th scope="col">{% trans "Przykład" %}<i id="examples-argument"></i><i id="examples-lu"></i><i id="examples-schema"></i></th> + <th scope="col">{% trans "Źródło" %}</th> + <th scope="col">{% trans "Opinia" %}</th> + </tr> + </thead> + <tbody id="semantics-examples-list"> + </tbody> + </table> + <p class="mx-1 my-1"id="semantics-no-examples">{% trans "Brak przykładów" %}</p> + </div> + </div> + <div class="col h-100 w-100 p-0 tab-pane" id="syntax" role="tabpanel" aria-labelledby="syntax-tab"> + <div class="col w-100 px-1 pt-0 pb-0 overflow-auto" id="syntax-schemata-pane"> + <div id="syntax-schemata"></div> + </div> + <div class="col w-100 p-0 overflow-auto" id="syntax-examples-pane"> + <table id="syntax-examples" class="table table-sm table-hover"> + <thead> + <tr> + <th scope="col">{% trans "Przykład" %}</th> + <th scope="col">{% trans "Źródło" %}</th> + <th scope="col">{% trans "Opinia" %}</th> + </tr> + </thead> + <tbody id="syntax-examples-list"> + </tbody> + </table> + <p class="mx-1 my-1"id="syntax-no-examples">{% trans "Brak przykładów" %}</p> + </div> + </div> + <div class="col h-100 w-100 p-0 tab-pane" id="examples" role="tabpanel" aria-labelledby="examples-tab"> + <table id="unmatched-examples" class="table table-sm table-hover"> + <thead> + <tr> + <th scope="col">{% trans "Przykład" %}</th> + <th scope="col">{% trans "Źródło" %}</th> + <th scope="col">{% trans "Opinia" %}</th> + </tr> + </thead> + <tbody id="unmatched-examples-list"> + </tbody> + </table> + <p class="mx-1 my-1"id="unmatched-no-examples">{% trans "Brak przykładów" %}</p> + </div> +</div> diff --git a/users/templates/notes.html b/users/templates/notes.html index 361ded95cf2f1e47497fec921f34af323550442a..75a7198118d195d30eac3b3082d48c72fe82d9ff 100644 --- a/users/templates/notes.html +++ b/users/templates/notes.html @@ -19,7 +19,7 @@ <h6 class="mt-4 d-inline">{% trans 'Notatki' %}</h6> <a href="#" class="show-note-form btn btn-xs btn-outline-dark ml-2">{% trans 'Dodaj' %}</a> </div> - <table class="table table-sm table-striped border notes-table" data-url="{% url 'users:get_notes' model='MODEL' pk='PK' %}"> + <table class="table table-sm table-striped border notes-table mb-0" data-url="{% url 'users:get_notes' model='MODEL' pk='PK' %}"> <tbody></tbody> </table> </div>