diff --git a/common/templates/base.html b/common/templates/base.html index c36d1faf7c178e524cabb2f8e2745a9ac0b28e1e..79b5451bc90007d845843447cb85a8f6c04ddd60 100644 --- a/common/templates/base.html +++ b/common/templates/base.html @@ -9,7 +9,7 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <title>{% block title %}{% endblock %} – Shell Unifier [BETA]</title> + <title>{% block title %}{% endblock %} – Val Unifier [BETA]</title> <link rel="icon" href="{% static 'common/favicon.ico' %}"> <link rel="stylesheet" type="text/css" href="https://bootswatch.com/4/lux/bootstrap.min.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@300;400;700&display=swap"> @@ -43,7 +43,7 @@ <!--z-index 2 above sticky-top--> <nav id="page-nav" class="navbar navbar-expand-lg sticky-top navbar-dark bg-dark font-weight-bold p-2" style="z-index: 1022;"> - <a class="navbar-brand" href="{% url 'dash' %}">Shell Unifier [BETA]</a> + <a class="navbar-brand" href="{% url 'dash' %}">Val Unifier [BETA]</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> diff --git a/entries/static/entries/css/entries.css b/entries/static/entries/css/entries.css index 58732e3f3119192c0d2d17da7f715e2d24db937b..94d3042006f76e734c60b6f7a224f97ebb09fbf5 100644 --- a/entries/static/entries/css/entries.css +++ b/entries/static/entries/css/entries.css @@ -255,3 +255,9 @@ legend { .tr-hover { background-color: rgba(0,0,0,.075) !important; } + +.ok-checkbox { + width: 80px; + accent-color: green; + pointer-events: none; +} diff --git a/entries/static/entries/js/components/LexicalUnitDisplay.js b/entries/static/entries/js/components/LexicalUnitDisplay.js index 498d6add868cfc73787faf888699fb8a610de0af..99b3fcb279c23f0dccb34c0f4f2cdc88d1d04f98 100644 --- a/entries/static/entries/js/components/LexicalUnitDisplay.js +++ b/entries/static/entries/js/components/LexicalUnitDisplay.js @@ -100,10 +100,10 @@ export default { this.statusChange('frame_reject_as_not_matching_unified_frame'); }, isReadyToProcess () { - return (!this.isLeksykograf() && this.unifiedFrame?.status === 'G') || (this.isLeksykograf() && this.frame?.status === 'O'); + return (!this.isLeksykograf() && this.unifiedFrame?.status === 'G') || (this.frame?.status === 'O' && this.unifiedFrame.assignee_username === window.USER_USERNAME); }, isReadyToGet () { - return this.isLeksykograf() && this.frame?.status === 'N'; + return this.frame?.status === 'N'; }, isLeksykograf () { return !has_permission("users.view_assignment"); @@ -186,7 +186,7 @@ export default { v-if="isReadyToProcess()" @click="goToEdit(this.unifiedFrame.pk, this.entryId, this.lexicalUnitId)" > - {{ isLeksykograf() ? gettext('Obrabiaj') : gettext('Sprawdź') }} + {{ this.frame?.status === 'O' ? gettext('Obrabiaj') : gettext('Sprawdź') }} </a> <a class="btn btn-sm btn-outline-dark mr-2" diff --git a/entries/static/entries/js/components/LexicalUnitEdit.js b/entries/static/entries/js/components/LexicalUnitEdit.js index e66b6d9060ec7197df99fdb6b1d2ec637e4f8042..2556cbba142468dbf35d06f96985760de9f820f6 100644 --- a/entries/static/entries/js/components/LexicalUnitEdit.js +++ b/entries/static/entries/js/components/LexicalUnitEdit.js @@ -31,7 +31,7 @@ const FramePreview = { mounted () { Split(['#frame-preview-left-pane', '#frame-preview-right-pane'], { sizes: [60, 40], - minSize: 10, + minSize: 20, gutterSize: 4, elementStyle: (dimension, size, gutterSize) => { return { @@ -862,10 +862,14 @@ Object.assign(LexicalUnitEdit, { }); }, isReadOnlyForSuperLeksykograf () { - return this.isSuperLeksykograf() && this.unified_frame.status === 'O'; + return (this.isSuperLeksykograf() && this.unified_frame.status === 'O') && this.unified_frame.assignee_username !== window.USER_USERNAME; }, hideFrame (frame) { this.hidden_frames.push(frame); + }, + getSlowalReadyFrameCnt () { + const readyFrames = this.frames.filter(frame => frame.status == 'G'); + return readyFrames.length; } }, mounted() { @@ -909,7 +913,7 @@ Object.assign(LexicalUnitEdit, { <td id="change-title" @click="changeTitle" style="padding: 10px 15px 10px 15px; color: #000000;">ZmieÅ„ nazwÄ™</td> <td id="add-arg" @click="addArgument" style="padding: 10px 15px 10px 15px; color: #000000;">Dodaj argum.</td> <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="addSelectivePreference">Dodaj prefer.</td> - <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeUnifiedFrameStatusToReady">Gotowe</td> + <td style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeUnifiedFrameStatusToReady">{{isSuperLeksykograf() ? 'Sprawdzone' : 'Gotowe'}}</td> <td id="duplicates" @click="duplicate" style="padding: 10px 15px 10px 15px; color: #000000;">Duplikuj</td> </tr> <tr style="background-color: white;"> @@ -917,9 +921,16 @@ Object.assign(LexicalUnitEdit, { <td id="remove-arg" @click="removeArgument" style="padding: 10px 15px 10px 15px; color: #000000;">UsuÅ„ argum.</td> <td id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="removeSelectionalPreference">UsuÅ„ prefer.</td> <td id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="swapUnifiedFrames">ZamieÅ„ okna</td> - <td v-if="frames.length == 0" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">UsuÅ„</td> + <td v-if="frames.length == 0 || isSuperLeksykograf()" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">UsuÅ„ ramÄ™</td> + </tr> + </table> + + <table v-if="!readOnly && isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" style="width: 100px;" cellspacing="1"> + <tr style="background-color: white;"> + <td v-if="frames.length == 0 || isSuperLeksykograf()" id="change-windows" style="padding: 10px 15px 10px 15px; color: #000000;" @click="deleteUnifiedFrames">UsuÅ„ ramÄ™</td> </tr> </table> + <spinner /> <div align="center"> <div align="left" style="display: table;"> @@ -958,7 +969,7 @@ Object.assign(LexicalUnitEdit, { </tr> <tr> <th scope="row" class="py-0 px-1 text-secondary role-header">Selectional preferences</th> - <td class="preferences py-0 px-0 border-top border-left border-secondary role-column" + <td class="preferences py-0 px-0 border-top border-left border-secondary role-column align-top" v-for='argument in unified_frame_arguments' :key='argument.id' > @@ -1015,7 +1026,7 @@ Object.assign(LexicalUnitEdit, { <table v-if="!readOnly && unified_frame.id && !isReadOnlyForSuperLeksykograf()" class="table-button-menu sticky-top" cellspacing="1"> <tr style="background-color: white;"> <td id="wrong-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="change_slowal_frame_status('B')">Błędna</td> - <td id="hide-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeShowVerifiedFrames(false)">Ukryj gotowe</td> + <td id="hide-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="changeShowVerifiedFrames(false)">Ukryj gotowe {{showVerifiedFrames ? '' : getSlowalReadyFrameCnt() > 0 ? '(ukrytych: ' + getSlowalReadyFrameCnt() + ')' : ''}}</td> <td id="ready-slowal-frame" style="padding: 10px 15px 10px 15px; color: #000000;" @click="slowal_frame_ready_rollback">{{ statusButtonTitle }}</td> <td id="filter-slowal-frames" style="padding: 10px 15px 10px 15px; color: #000000;">Filtruj</td> </tr> @@ -1041,15 +1052,22 @@ Object.assign(LexicalUnitEdit, { <tbody> <tr> <td> - <div class="row"> - <div class="col close" style=" - cursor: pointer; + <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="row"> + <div class="col" style=" display: flex; justify-content: flex-end;" - @click="hideFrame(frame)" - >×</div> + > + <div class="close" style=" + width: 15px; + cursor: pointer; + text-align: end;" + @click="hideFrame(frame)" + title="Ukryj ramÄ™" + >×</div> + </div> + <div class="col" style="max-width: 40px;"></div> </div> - <div class="row"> + <div class="row" style="flex-wrap: nowrap;"> <div class="col" @mouseenter="frame.hover=true" @@ -1061,26 +1079,31 @@ Object.assign(LexicalUnitEdit, { :frame="frame" :key="frame" @frame-selection-changed="insideFrameSelectionChanged" /> - </div> + </div> + <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()" class="col pl-0 pt-4" style="max-width: 60px;"> + <div class="row"> + <div class="col"> + <button v-if="!isFrameVerified(frame)" + 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 class="row"> + <div v-if="isFrameVerified(frame)" class="col pt-2" style="display: flex;"> + <input + type="checkbox" + :checked="isFrameVerified(frame)" + class="custom-control custom-checkbox ok-checkbox" + > + </div> + </div> + </div> + </div> </td> - <th scope="row"> - <div v-if="!readOnly && !isReadOnlyForSuperLeksykograf()"> - <div v-if="isFrameVerified(frame)"> - <input - type="checkbox" - :checked="isFrameVerified(frame)" - class="custom-control custom-checkbox" - disabled="disabled" - > - </div> - <br><br> - <button v-if="!isFrameVerified(frame)" - class="btn btn-sm btn-dark" role="button" - @click="change_slowal2unified_frame_argument_mapping(frame)" - >Z</button> - </div> - </th> </tr> </tbody> </table> diff --git a/entries/static/entries/js/components/UnificationRightPane.js b/entries/static/entries/js/components/UnificationRightPane.js index 5cb116a761a0b7fa91a1659caa16a01062507d9b..9f99ede3508ff8323a9239c4948ff3388e1306a3 100644 --- a/entries/static/entries/js/components/UnificationRightPane.js +++ b/entries/static/entries/js/components/UnificationRightPane.js @@ -68,7 +68,7 @@ export default { :readOnly="false" :unifiedFrameId="unifiedFrameId" :previewedUnifiedFrameId="previewedUnifiedFrameId" - :initialRightPaneTab="unifiedFrameId !== previewedUnifiedFrameId ? 'frame_preview' : null" + :initialRightPaneTab="previewedUnifiedFrameId && unifiedFrameId !== previewedUnifiedFrameId ? 'frame_preview' : 'schemata'" @go-to-display="goToDisplay" @swap-frames="swapFrames" @refresh-entries-list="refreshEntriesList" diff --git a/entries/views.py b/entries/views.py index 2a2d2f5875a863e1a799ad69651fa1345644aa47..947632ab4f60006f32437d853d88d0a2290eead1 100644 --- a/entries/views.py +++ b/entries/views.py @@ -872,6 +872,7 @@ def get_entry(request): unified_frame = { 'pk': unified_frame.pk, 'status': unified_frame.status, + 'assignee_username' : assignment.user.username if (assignment := unified_frame.assignments.first()) else None, } # https://docs.djangoproject.com/en/2.2/topics/http/sessions/#when-sessions-are-saved if [entry.name, entry.id] in request.session['last_visited']: diff --git a/unifier/models.py b/unifier/models.py index 2fd744c3d705d61294d0ad4f65947441767d533c..e31db9f2334f0a09046ad22f9ad02332397571fd 100644 --- a/unifier/models.py +++ b/unifier/models.py @@ -1,4 +1,6 @@ from copy import deepcopy + +from django.contrib.contenttypes.fields import GenericRelation from typing import List, Optional from django.db import models, transaction @@ -23,6 +25,8 @@ class UnifiedFrame(models.Model): ) title = models.CharField(max_length=200, default=None, blank=True, null=True) + assignments = GenericRelation("users.Assignment", content_type_field="subject_ct", object_id_field="subject_id") + objects = models.Manager.from_queryset(UnifiedFrameQueryset)() def sorted_arguments(self): # TODO: zaimplementowac wlasciwe sortowanie diff --git a/unifier/views.py b/unifier/views.py index c7f309075aef24fdd5189837172d058281d7baee..036dc0043f898837f1a9f0280b81ca0970ad1f6f 100644 --- a/unifier/views.py +++ b/unifier/views.py @@ -79,18 +79,9 @@ def get_unified_frames(request): 'id': str(unifiedFrame.id), 'title': unifiedFrame.title, 'status': unifiedFrame.status, - 'assignee_username': None, + 'assignee_username': assignment.user.username if (assignment := unifiedFrame.assignments.first()) else None, } - unifiedFrame2SlowalFrameMappings = UnifiedFrame2SlowalFrameMapping.objects.all(); - - for mapping in unifiedFrame2SlowalFrameMappings: - unifiedFrame = res[mapping.unified_frame.id] - title = unifiedFrame['title'] if unifiedFrame['title'] is not None else '['+mapping.slowal_frame.lexical_units.first().base+']' - unifiedFrame['title'] = title - if unifiedFrame['assignee_username'] is None: - unifiedFrame['assignee_username'] = assignment.user.username if (assignment := mapping.slowal_frame.assignments.first()) else None - resProcessed = [] for key, value in res.items(): if (exclude_status == None or value['status'] != exclude_status) and \ @@ -114,6 +105,7 @@ def unifiedFrame2dict(frame): 'id' : frame.id, 'title' : frame.title, 'status' : str(frame.status), + 'assignee_username' : assignment.user.username if (assignment := frame.assignments.first()) else None, 'arguments' : [ { 'str' : str(a), @@ -488,6 +480,8 @@ def frame_assign(request): unifiedFrame.title = unified_frame_title unifiedFrame.save() + Assignment.assign(user=request.user, subject=unifiedFrame) + slowal_frames = [connection.slowal_frame for connection in unifiedFrame.unified_frame_2_slowal_frame.all()] for slowal_frame in slowal_frames: @@ -506,6 +500,9 @@ def removeUnifiedFrameMappingsAndAssigments(unified_frame_id): #odpianie z ramy zunifikowanej unifiedFrame2SlowalFrameMappings = UnifiedFrame2SlowalFrameMapping.objects.filter(unified_frame_id=unified_frame_id) for unifiedFrame2SlowalFrameMapping in unifiedFrame2SlowalFrameMappings: + unifiedFrame2SlowalFrameMapping.slowal_frame.status = 'N' + unifiedFrame2SlowalFrameMapping.slowal_frame.save() + Assignment.delete(subject_id=unifiedFrame2SlowalFrameMapping.slowal_frame.id) unifiedFrameArgumentSlowalFrameMappings = UnifiedFrameArgumentSlowalFrameMapping.objects.filter(unified_frame_mapping=unifiedFrame2SlowalFrameMapping) unifiedFrameArgumentSlowalFrameMappings.delete() unifiedFrame2SlowalFrameMapping.delete()