From ab2012d4d022e6c670b8d6ccb009e88057bc4b9e Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia Date: Wed, 12 May 2021 19:18:33 +0200 Subject: [PATCH 01/42] bug fix for new annotation model --- web/server/matilda_app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index b31e77d..73b79f5 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -150,7 +150,8 @@ def handle_configuration_file(annotationStyle=None, option=None): data = request.get_json() newFile = data["json"] - newFile = json.loads(newFile) + if type(newFile) != dict: + newFile = json.loads(newFile) #normalize name if ".json" in annotationStyle: From 9cd2afa29f69f8f13128096a6c2d09d1354247f9 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Thu, 13 May 2021 21:17:37 +0200 Subject: [PATCH 02/42] Update login_components.js --- web/server/gui/source/components/login_components.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web/server/gui/source/components/login_components.js b/web/server/gui/source/components/login_components.js index 06b601d..e93d8b6 100644 --- a/web/server/gui/source/components/login_components.js +++ b/web/server/gui/source/components/login_components.js @@ -54,7 +54,6 @@ Vue.component("login-view", {
@@ -160,8 +160,12 @@ Vue.component("collection-view", { .then( (response) => { console.log("==== DIALOGUES IMPORT ===="); console.log(response); + if (response.data.error) { + document.body.style.cursor = null; + return; + } if (response.data.created == true) { - console.log("=== CREATED NEW DOCUMENT ====") + console.log("=== CREATED NEW DOCUMENT FOR ANNOTATOR ====") } databaseEventBus.$emit("collection_active", clickedEntry); document.body.style.cursor = null; @@ -271,7 +275,7 @@ Vue.component("collection-view", {
@@ -305,7 +309,7 @@ Vue.component("collection-view", { {{name.assignedTo.join(", ")}}
- {{name.lastUpdate.slice(0,-3)}} + {{name.lastUpdate.slice(0,-3)}}
{{name.annotationStyle.split(".")[0]}}
diff --git a/web/server/gui/source/components/configuration_components.js b/web/server/gui/source/components/configuration_components.js index a65c884..e78c698 100644 --- a/web/server/gui/source/components/configuration_components.js +++ b/web/server/gui/source/components/configuration_components.js @@ -237,7 +237,6 @@ Vue.component("configuration-view", {

Matilda

{{guiMessages.selected.database.location}}: {{settings.app.address}}

{{guiMessages.selected.database.port}}: {{settings.app.port}}

-

Docker: {{settings.app.docker}}

Session Guard: {{settings.app.session_guard}}

Full Server log:

diff --git a/web/server/gui/source/components/modal_components.js b/web/server/gui/source/components/modal_components.js index 731bd94..ddeb045 100644 --- a/web/server/gui/source/components/modal_components.js +++ b/web/server/gui/source/components/modal_components.js @@ -435,7 +435,7 @@ Vue.component('help-general-config-modal', { diff --git a/web/server/gui/source/lida_view.js b/web/server/gui/source/lida_view.js index 044a5dd..00f3c80 100644 --- a/web/server/gui/source/lida_view.js +++ b/web/server/gui/source/lida_view.js @@ -305,7 +305,7 @@ var mainApp = new Vue({ v-bind:userName="userName"> - diff --git a/web/server/gui/source/utils/backend.js b/web/server/gui/source/utils/backend.js index c6be34a..f35d024 100644 --- a/web/server/gui/source/utils/backend.js +++ b/web/server/gui/source/utils/backend.js @@ -528,6 +528,13 @@ async function load_dialogues(doc) { try { var response = await axios.put(apiLink) + + if (response["data"]["error"] != undefined) { + alert(response["data"]["error"]) + if (response["data"]["status"] == "logout") { + mainApp.force_logout() + } + } return response } catch(error) { diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index 73b79f5..7b35c8d 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -84,8 +84,6 @@ def handle_configuration_file(annotationStyle=None, option=None): for setting in section: responseObject[setting][section] = setting - responseObject["app"]["docker"] = Configuration.DOCKER - #default mongodb databases not listed ignoreList = ["admin","config","local"] @@ -591,10 +589,16 @@ def handle_switch_collection_request(user, doc): #import and format new dialogues for docCollection in docRetrieved: - __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) + annotationStyle = retrieve_annotation_style_name(doc) + if annotationStyle != False: + __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) + else: + responseObject["error"] = "The linked annotation model is not currently loaded." + return jsonify( responseObject ) - dialogueFile.change_collection(user, doc) - responseObject["status"] = "success" + if responseObject["status"] != "error": + dialogueFile.change_collection(user, doc) + responseObject["status"] = "success" return jsonify( responseObject ) @@ -1198,6 +1202,11 @@ def __add_new_dialogues_from_json_dict(user, fileName, currentResponseObject, di annotationStyle = retrieve_annotation_style_name(fileName) + if annotationStyle == False: + currentResponseObject["error"] = "The selected annotation style is no more in the database." + currentResponseObject["status"] = "error" + return currentResponseObject + for dialogue_name, dialogue in dialogueDict.items(): dialogue = Configuration.validate_dialogue(annotationStyle,dialogue) @@ -1365,10 +1374,16 @@ def retrieve_annotation_style_name(collection): annotationStyle = search[0]["annotationStyle"] #if annotation model name not valid or empty system falls back to default model - if len(annotationStyle) <= 1: + if len(annotationStyle) == 0: annotationStyle = Configuration.annotation_styles[0] - return annotationStyle + try: + print(Configuration.annotation_styles[annotationStyle]) + return annotationStyle + except: + logging.warning(" * The annotation style referenced is not loaded. Maybe it was deleted?") + return False + ################################ # STATIC METHODS From d4bcc8eab1e745139a7a6ae7561a4c94b3efad2d Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 12:05:57 +0200 Subject: [PATCH 15/42] Update all_dialogues.css --- web/server/gui/assets/css/all_dialogues.css | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web/server/gui/assets/css/all_dialogues.css b/web/server/gui/assets/css/all_dialogues.css index 18ee77b..d54ee76 100644 --- a/web/server/gui/assets/css/all_dialogues.css +++ b/web/server/gui/assets/css/all_dialogues.css @@ -254,8 +254,12 @@ background-color: rgb(0 0 0 / 10%); } -.container-bar .annotated-bar:nth-child(2n) { - border-left:4px solid black; +.container-bar .annotated-bar:nth-child(1) { + border-left:none; +} + +.container-bar .annotated-bar:nth-child(n) { + border-left:4px solid #000000ab; } .annotated-fill { From b9667ba81e4cac21631e099f2dfe751677de0283 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 12:10:59 +0200 Subject: [PATCH 16/42] Update annotation_app.css --- web/server/gui/assets/css/annotation_app.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/server/gui/assets/css/annotation_app.css b/web/server/gui/assets/css/annotation_app.css index 6e2e62d..7ab58b4 100644 --- a/web/server/gui/assets/css/annotation_app.css +++ b/web/server/gui/assets/css/annotation_app.css @@ -533,7 +533,7 @@ WluperDark: 0e181e } .slider { - height: 8px; + height: 7px; background: #c2d5e3; outline: none; opacity: 0.7; @@ -595,4 +595,4 @@ WluperDark: 0e181e -moz-user-select: none; /* Old versions of Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; -} \ No newline at end of file +} From abe12be6f9333677882acca826f6e934d46a72fa Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 17:29:28 +0200 Subject: [PATCH 17/42] Update annotation_app.css --- web/server/gui/assets/css/annotation_app.css | 1 + 1 file changed, 1 insertion(+) diff --git a/web/server/gui/assets/css/annotation_app.css b/web/server/gui/assets/css/annotation_app.css index 7ab58b4..a39ba2e 100644 --- a/web/server/gui/assets/css/annotation_app.css +++ b/web/server/gui/assets/css/annotation_app.css @@ -589,6 +589,7 @@ WluperDark: 0e181e outline: none; border: 1px solid #e1e1e3; padding: 10px 15px; + overflow-y: scroll; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ From 5f520d8c5fb640d0793b288df5e3533f97882e9e Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 17:42:23 +0200 Subject: [PATCH 18/42] Update languages.js --- web/server/gui/source/utils/languages.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/server/gui/source/utils/languages.js b/web/server/gui/source/utils/languages.js index 8acbf1a..d4a065a 100644 --- a/web/server/gui/source/utils/languages.js +++ b/web/server/gui/source/utils/languages.js @@ -150,7 +150,7 @@ guiMessages = { switchAnnotationView: "Expanded Slots View", annotationPref:"Annotation Preferences", turnWidth:"Turn Width", - scrollAfter:"Scroll-bar after", + scrollAfter:"Scroll-bar with sentence longer than", chars:"characters", autoSave:"Auto-save on turn changed", }, @@ -512,7 +512,7 @@ guiMessages = { switchAnnotationView: "Visuale Slot-Espansi", annotationPref:"Preferenze di Annotazione", turnWidth:"Larghezza finestra turni", - scrollAfter:"Scroll-bar dopo", + scrollAfter:"Scroll-bar con frasi più lunghe di", chars:"caratteri", autoSave:"Auto-save al cambio di turno", }, From 104540eee600aa269e39f8a34ba64b10c1cb1a1c Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 18:06:19 +0200 Subject: [PATCH 19/42] Update unipi_model_v2.json --- configuration/unipi_model_v2.json | 505 ++++++++++++++---------------- 1 file changed, 227 insertions(+), 278 deletions(-) diff --git a/configuration/unipi_model_v2.json b/configuration/unipi_model_v2.json index b064b59..d3b1e4d 100644 --- a/configuration/unipi_model_v2.json +++ b/configuration/unipi_model_v2.json @@ -1,279 +1,228 @@ { - - "sys": { - "description" : "The system's query", - "label_type" : "string", - "required" : true - }, - - "usr": { - "description" : "The user's query", - "label_type" : "string", - "required" : true - }, - - "sys_greet": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none" - ] - - }, - - "usr_greet": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none" - ] - - }, - - "sys_inform_basic": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_inform_basic": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "sys_inform_proactive": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "sys_request": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_size", - "location" - ] - - }, - - "usr_inform_proactive": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_size", - "location", - "other" - ] - - }, - - "usr_request": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_size", - "location" - ] - - }, - - "sys_select": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description" - ] - - }, - - "usr_select": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description" - ] - - }, - - "sys_deny": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_size", - "location" - ] - - }, - - "usr_deny": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "none", - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_size", - "location" - ] - - }, - - "async": { - - "description": "To annotate async messages", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - "turn_ref" - ] - }, - - "global_slot": { - - "description" : "General info related to the dialogue", - "label_type" : "multilabel_global_string", - "required" : false, - "labels" : [ - "result" - ] - - } - - } + "async": { + "description": "To annotate async messages", + "label_type": "multilabel_classification_string", + "labels": [ + "turn_ref" + ], + "required": false + }, + "global_slot": { + "description": "General info related to the dialogue", + "label_type": "multilabel_global_string", + "labels": [ + "result" + ], + "required": false + }, + "sys": { + "description": "The system's query", + "label_type": "string", + "required": true + }, + "sys_deny": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_size", + "location" + ], + "required": false + }, + "sys_greet": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none" + ], + "required": false + }, + "sys_inform_basic": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_name", + "company_size", + "location", + "contact", + "other" + ], + "required": false + }, + "sys_inform_proactive": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_name", + "company_size", + "location", + "contact", + "other" + ], + "required": false + }, + "sys_request": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "other", + "company_name", + "age", + "languages", + "area", + "company_size", + "location" + ], + "required": false + }, + "sys_select": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description" + ], + "required": false + }, + "usr": { + "description": "The user's query", + "label_type": "string", + "required": true + }, + "usr_deny": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_size", + "location" + ], + "required": false + }, + "usr_greet": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none" + ], + "required": false + }, + "usr_inform_basic": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_name", + "company_size", + "location", + "contact", + "other" + ], + "required": false + }, + "usr_inform_proactive": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_size", + "location", + "other" + ], + "required": false + }, + "usr_request": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description", + "contract", + "contact", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_size", + "company_name", + "location", + "other" + ], + "required": false + }, + "usr_select": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "none", + "job_description" + ], + "required": false + } +} From 04f5d595a57d435bf7160ad9c71fccd9b135f852 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Mon, 24 May 2021 18:06:30 +0200 Subject: [PATCH 20/42] Delete unipi_v2.json --- configuration/unipi_v2.json | 277 ------------------------------------ 1 file changed, 277 deletions(-) delete mode 100644 configuration/unipi_v2.json diff --git a/configuration/unipi_v2.json b/configuration/unipi_v2.json deleted file mode 100644 index 5e81eab..0000000 --- a/configuration/unipi_v2.json +++ /dev/null @@ -1,277 +0,0 @@ -{ - - "sys": { - "description" : "The user's query", - "label_type" : "string", - "required" : true - }, - - "usr": { - "description" : "The user's query", - "label_type" : "string", - "required" : true - }, - - - "sys_inform_basic": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_inform_basic": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "sys_inform_proactive": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "sys_request": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "sys_select": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_greet": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_inform_proactive": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_request": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_select": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "usr_deny": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "global_slot": { - - "description" : "General info related to the dialogue", - "label_type" : "multilabel_global_string", - "required" : false, - "labels" : [ - "goal" - ] - - } - - } From 8fadbbc6ec99de266492e3917c92c0cfd1723d03 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Tue, 25 May 2021 17:16:10 +0200 Subject: [PATCH 21/42] Update supervision_components.js --- web/server/gui/source/components/supervision_components.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/server/gui/source/components/supervision_components.js b/web/server/gui/source/components/supervision_components.js index 6e113b9..7fbfbe7 100644 --- a/web/server/gui/source/components/supervision_components.js +++ b/web/server/gui/source/components/supervision_components.js @@ -91,7 +91,7 @@ Vue.component("supervision-view", { gridStyle(columnNum) { return { - gridTemplateColumns: `repeat(${columnNum}, minmax(100px, 1fr))`, + gridTemplateColumns: `repeat(${columnNum}, minmax(0px, 1fr))`, display: 'grid' } }, From 5282e08718c43d9cd2eace5d296e2f1474d8818e Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Tue, 25 May 2021 17:28:32 +0200 Subject: [PATCH 22/42] temporary fix --- web/server/matilda_app.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index 7b35c8d..51f35e3 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -589,12 +589,14 @@ def handle_switch_collection_request(user, doc): #import and format new dialogues for docCollection in docRetrieved: - annotationStyle = retrieve_annotation_style_name(doc) - if annotationStyle != False: - __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) - else: - responseObject["error"] = "The linked annotation model is not currently loaded." - return jsonify( responseObject ) + __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) + + #annotationStyle = retrieve_annotation_style_name(doc) + #if annotationStyle != False: + # __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) + #else: + # responseObject["error"] = "The linked annotation model is not currently loaded." + # return jsonify( responseObject ) if responseObject["status"] != "error": dialogueFile.change_collection(user, doc) @@ -1633,4 +1635,4 @@ def guard(): logging.disable(logging.INFO) if __name__ == "__main__": - MatildaApp.run(port=jsonConf["port"],host=jsonConf["address"]) \ No newline at end of file + MatildaApp.run(port=jsonConf["port"],host=jsonConf["address"]) From f33653b38ad40d8d68c0426db9a042b34ddf295c Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Tue, 25 May 2021 17:35:55 +0200 Subject: [PATCH 23/42] Update matilda_app.py --- web/server/matilda_app.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index 51f35e3..3dd7c1b 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -1204,10 +1204,10 @@ def __add_new_dialogues_from_json_dict(user, fileName, currentResponseObject, di annotationStyle = retrieve_annotation_style_name(fileName) - if annotationStyle == False: - currentResponseObject["error"] = "The selected annotation style is no more in the database." - currentResponseObject["status"] = "error" - return currentResponseObject + #if annotationStyle == False: + # currentResponseObject["error"] = "The selected annotation style is no more in the database." + # currentResponseObject["status"] = "error" + # return currentResponseObject for dialogue_name, dialogue in dialogueDict.items(): From b715a5e49c1087e49c55227dfb14c9160b931463 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia Date: Tue, 25 May 2021 19:09:31 +0200 Subject: [PATCH 24/42] fix for annotation modal check --- .../gui/source/components/configuration_components.js | 3 ++- web/server/matilda_app.py | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/web/server/gui/source/components/configuration_components.js b/web/server/gui/source/components/configuration_components.js index e78c698..0bf5cf0 100644 --- a/web/server/gui/source/components/configuration_components.js +++ b/web/server/gui/source/components/configuration_components.js @@ -396,8 +396,9 @@ Vue.component("create-annotation-model", { .then( (response) => { if (response.data.status == "done") { this.changesSaved = 'true'; - alert("Upload OK"); databaseEventBus.$emit("annotation_styles_changed"); + + alert("Upload OK"); } else { alert(response.data.error); } diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index 3dd7c1b..94c9124 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -1380,8 +1380,11 @@ def retrieve_annotation_style_name(collection): annotationStyle = Configuration.annotation_styles[0] try: - print(Configuration.annotation_styles[annotationStyle]) - return annotationStyle + if annotationStyle in Configuration.annotation_styles: + return annotationStyle + else: + logging.warning(" * The annotation style referenced is not loaded. Maybe it was deleted?") + return False except: logging.warning(" * The annotation style referenced is not loaded. Maybe it was deleted?") return False From 0a805e89f1c6cd2ab42ce47168cf18e536903ab7 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia Date: Tue, 25 May 2021 20:04:30 +0200 Subject: [PATCH 25/42] bugfix for an empty database update request --- .../components/all_dialogues_components.js | 2 +- web/server/matilda_app.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/web/server/gui/source/components/all_dialogues_components.js b/web/server/gui/source/components/all_dialogues_components.js index 52c193a..df76eee 100644 --- a/web/server/gui/source/components/all_dialogues_components.js +++ b/web/server/gui/source/components/all_dialogues_components.js @@ -70,7 +70,7 @@ Vue.component("all-dialogues", { mainApp.collectionRate = "0%" } if (mainApp.collectionRate != tempRate) { - backend.update_collection_fields(mainApp.activeCollection,{"status":mainApp.collectionRate}, false); + backend.update_collection_fields(mainApp.activeCollection,{"status":mainApp.collectionRate}); } }, diff --git a/web/server/matilda_app.py b/web/server/matilda_app.py index 94c9124..7e49ca9 100644 --- a/web/server/matilda_app.py +++ b/web/server/matilda_app.py @@ -591,12 +591,12 @@ def handle_switch_collection_request(user, doc): for docCollection in docRetrieved: __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) - #annotationStyle = retrieve_annotation_style_name(doc) - #if annotationStyle != False: - # __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) - #else: - # responseObject["error"] = "The linked annotation model is not currently loaded." - # return jsonify( responseObject ) + annotationStyle = retrieve_annotation_style_name(doc) + if annotationStyle != False: + __add_new_dialogues_from_json_dict(user, doc, responseObject, dialogueDict=docCollection["document"]) + else: + responseObject["error"] = "The linked annotation model is not currently loaded." + return jsonify( responseObject ) if responseObject["status"] != "error": dialogueFile.change_collection(user, doc) @@ -1204,10 +1204,10 @@ def __add_new_dialogues_from_json_dict(user, fileName, currentResponseObject, di annotationStyle = retrieve_annotation_style_name(fileName) - #if annotationStyle == False: - # currentResponseObject["error"] = "The selected annotation style is no more in the database." - # currentResponseObject["status"] = "error" - # return currentResponseObject + if annotationStyle == False: + currentResponseObject["error"] = "The selected annotation style is no more in the database." + currentResponseObject["status"] = "error" + return currentResponseObject for dialogue_name, dialogue in dialogueDict.items(): @@ -1383,10 +1383,10 @@ def retrieve_annotation_style_name(collection): if annotationStyle in Configuration.annotation_styles: return annotationStyle else: - logging.warning(" * The annotation style referenced is not loaded. Maybe it was deleted?") + logging.warning(" * The annotation style "+annotationStyle+" referenced is not loaded. Maybe it was deleted?") return False except: - logging.warning(" * The annotation style referenced is not loaded. Maybe it was deleted?") + logging.warning(" * The annotation style "+annotationStyle+" referenced is not passing the new check. Maybe it was changed since last reboot?") return False From 51b3b79944435ed3e09e2dfbafde59ac67bb68a1 Mon Sep 17 00:00:00 2001 From: davide cucurnia Date: Wed, 26 May 2021 14:52:14 +0200 Subject: [PATCH 26/42] datamanagement: shows only the number if more than 3 assigned users --- .../components/datamanagement_components.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/web/server/gui/source/components/datamanagement_components.js b/web/server/gui/source/components/datamanagement_components.js index 4db4d26..2394968 100644 --- a/web/server/gui/source/components/datamanagement_components.js +++ b/web/server/gui/source/components/datamanagement_components.js @@ -246,10 +246,16 @@ Vue.component("datamanagement-view", { {{collection.assignedTo.join(", ")}} + + Assigned: + {{collection.assignedTo.length}} + + Assigned: {{collection.assignedTo.length}} +
@@ -276,6 +282,11 @@ Vue.component("datamanagement-view", { {{collection.assignedTo.join(", ")}} + + Assigned: + {{collection.assignedTo.length}} + + Assigned: {{collection.assignedTo.length}} @@ -479,7 +490,12 @@ Vue.component('collection-users-reverse', { Gold: False
-
+ +
+ Assigned: {{collection.assignedTo.length}} +
+ +
Assigned: {{collection.assignedTo.join(", ")}}
From 8896d985002129bd3d8bc1aad3e5a719ddd27830 Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia Date: Tue, 1 Jun 2021 00:16:45 +0200 Subject: [PATCH 27/42] datamanagement: shows only the number if more than 3 assigned users --- configuration/unipi_model.json | 147 ++++++++---------- web/server/gui/assets/css/annotation_app.css | 2 +- web/server/gui/assets/css/database.css | 6 + web/server/gui/index.html | 70 ++++----- .../components/annotation_app_components.js | 2 +- .../components/datamanagement_components.js | 27 ++-- web/server/gui/source/utils/languages.js | 3 + 7 files changed, 130 insertions(+), 127 deletions(-) diff --git a/configuration/unipi_model.json b/configuration/unipi_model.json index 3c8065a..d7678c1 100644 --- a/configuration/unipi_model.json +++ b/configuration/unipi_model.json @@ -1,83 +1,68 @@ { - - "global_slot": { - - "description" : "General info related to the dialogue", - "label_type" : "multilabel_global_string", - "required" : false, - "labels" : [ - "result" - ] - }, - - "usr": { - "description" : "The user's query", - "label_type" : "string", - "required" : true - }, - - "sys": { - "description" : "The system's response", - "label_type" : "string", - "required" : true - }, - - "Dialogue_act": { - - "description" : "Type of dialogue act", - "label_type" : "multilabel_classification", - "required" : false, - "labels" :[ - "sys_greet", - "sys_inform_basic", - "sys_inform_proactive", - "sys_request", - "sys_select", - "sys_deny", - "usr_greet", - "usr_inform_basic", - "usr_inform_proactive", - "usr_request", - "usr_select", - "usr_deny" - ] - }, - - "Slot": { - - "description" : "Entity's value", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - - "job_description", - "contract", - "duties", - "skill", - "past_experience", - "degree", - "age", - "languages", - "area", - "company_name", - "company_size", - "location", - "contact", - "other" - ] - - }, - - "Async": { - - "description": "To annotate async messages", - "label_type" : "multilabel_classification_string", - "required" : false, - "labels" : [ - "turn_ref" - - ] - - } - + "Async": { + "description": "To annotate async messages", + "label_type": "multilabel_classification_string", + "labels": [ + "turn_ref" + ], + "required": false + }, + "Dialogue_act": { + "description": "Type of dialogue act", + "label_type": "multilabel_classification", + "labels": [ + "sys_greet", + "sys_inform_basic", + "sys_inform_proactive", + "sys_request", + "sys_select", + "sys_deny", + "usr_greet", + "usr_inform_basic", + "usr_inform_proactive", + "usr_request", + "usr_select", + "usr_deny" + ], + "required": false + }, + "Slot": { + "description": "Entity's value", + "label_type": "multilabel_classification_string", + "labels": [ + "job_description", + "contract", + "duties", + "skill", + "past_experience", + "degree", + "age", + "languages", + "area", + "company_name", + "company_size", + "location", + "contact", + "other" + ], + "required": false + }, + "global_slot": { + "description": "General info related to the dialogue", + "label_type": "multilabel_global_string", + "labels": [ + "result" + ], + "required": false + }, + "sys": { + "description": "The system's response", + "label_type": "string", + "required": true + }, + "usr": { + "description": "The user's query", + "label_type": "string", + "required": false } +} \ No newline at end of file diff --git a/web/server/gui/assets/css/annotation_app.css b/web/server/gui/assets/css/annotation_app.css index a39ba2e..f6ca534 100644 --- a/web/server/gui/assets/css/annotation_app.css +++ b/web/server/gui/assets/css/annotation_app.css @@ -123,7 +123,7 @@ textarea { resize: none; width: 100%; height: 100%; - overflow-y: scroll; + overflow-y: auto; display: inline-block; justify-self: center; margin: 0; diff --git a/web/server/gui/assets/css/database.css b/web/server/gui/assets/css/database.css index 0d45b5e..1f2b688 100644 --- a/web/server/gui/assets/css/database.css +++ b/web/server/gui/assets/css/database.css @@ -92,6 +92,12 @@ float:left; } +.collection-list .entry-assigned { + max-width: 27em; + overflow: hidden; + height: 1em; +} + .annotation-list .listed-entry { margin: 10px 0; color: white; diff --git a/web/server/gui/index.html b/web/server/gui/index.html index 9c7d6d8..ac698fe 100644 --- a/web/server/gui/index.html +++ b/web/server/gui/index.html @@ -17,21 +17,21 @@ CSS ---------------------------------------------------------------> - - + + - + - - - - - - - - + + + + + + + + @@ -70,7 +70,7 @@
- MATILDA v.1.5 · Copyright © 2020 Wluper Ltd. · Developed in collaboration with University of Pisa + MATILDA v.1.5.1 · Copyright © 2020 Wluper Ltd. · Developed in collaboration with University of Pisa
@@ -88,34 +88,34 @@ SCRIPTS ============================================= --> - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - + - - - - - - - + + + + + + + diff --git a/web/server/gui/source/components/annotation_app_components.js b/web/server/gui/source/components/annotation_app_components.js index cba6ac1..e8c8e4c 100644 --- a/web/server/gui/source/components/annotation_app_components.js +++ b/web/server/gui/source/components/annotation_app_components.js @@ -731,7 +731,7 @@ Vue.component('dialogue-turn',{ class="help-button btn btn-sm btn-primary" v-on:click="selection_done()" v-bind:id="'selection-done-'+currentId" - style="float:right">Done Selection + style="float:right">{{guiMessages.selected.annotation_app.doneSelection}}
diff --git a/web/server/gui/source/components/datamanagement_components.js b/web/server/gui/source/components/datamanagement_components.js index 2394968..e24fc8a 100644 --- a/web/server/gui/source/components/datamanagement_components.js +++ b/web/server/gui/source/components/datamanagement_components.js @@ -241,14 +241,18 @@ Vue.component("datamanagement-view", {
- + Assigned: - {{collection.assignedTo.join(", ")}} + + {{collection.assignedTo[0]}} + {{collection.assignedTo[1]}} + {{collection.assignedTo[2]}} + and {{collection.assignedTo.length-3}} more - + Assigned: - {{collection.assignedTo.length}} + {{collection.assignedTo.join(", ")}} @@ -277,14 +281,19 @@ Vue.component("datamanagement-view", {
- + + Assigned: - {{collection.assignedTo.join(", ")}} + + {{collection.assignedTo[0]}} + {{collection.assignedTo[1]}} + {{collection.assignedTo[2]}} + and {{collection.assignedTo.length-3}} more - - + + Assigned: - {{collection.assignedTo.length}} + {{collection.assignedTo.join(", ")}} diff --git a/web/server/gui/source/utils/languages.js b/web/server/gui/source/utils/languages.js index d4a065a..f45be73 100644 --- a/web/server/gui/source/utils/languages.js +++ b/web/server/gui/source/utils/languages.js @@ -153,6 +153,7 @@ guiMessages = { scrollAfter:"Scroll-bar with sentence longer than", chars:"characters", autoSave:"Auto-save on turn changed", + doneSelection:"Selection done", }, resolution_app: { errorId: "Error Id:", @@ -515,6 +516,7 @@ guiMessages = { scrollAfter:"Scroll-bar con frasi più lunghe di", chars:"caratteri", autoSave:"Auto-save al cambio di turno", + doneSelection: "Selezione completata", }, resolution_app: { errorId: "Id Conflitto:", @@ -848,6 +850,7 @@ guiMessages = { scrollAfter:"Scroll-bar after", chars:"characters", autoSave:"Auto-save on turn changed", + doneSelection: "Selction done", }, resolution_app: { errorId: "Error Id:", From e6f630eb3966803835f1fa76194da5a0635019df Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia <44603608+davivcu@users.noreply.github.com> Date: Thu, 10 Jun 2021 14:32:47 +0200 Subject: [PATCH 28/42] Update configuration_components.js --- web/server/gui/source/components/configuration_components.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/server/gui/source/components/configuration_components.js b/web/server/gui/source/components/configuration_components.js index 0bf5cf0..cddfad2 100644 --- a/web/server/gui/source/components/configuration_components.js +++ b/web/server/gui/source/components/configuration_components.js @@ -535,7 +535,7 @@ Vue.component('configuration-show-logs', { From 482e564450719ec85f759cb10360e281253d6cfe Mon Sep 17 00:00:00 2001 From: Davide Ivan Cucurnia Date: Sat, 3 Jul 2021 21:06:19 +0200 Subject: [PATCH 29/42] supervision view: editing turn content for all documents --- web/server/database.py | 6 +- web/server/gui/assets/css/main.css | 1 + .../components/all_dialogues_components.js | 23 ------ .../components/annotation_app_components.js | 79 ++++++++++++------- .../components/annotation_type_components.js | 31 +++++--- .../components/interannotator_components.js | 10 --- .../resolution_app_helper_components.js | 2 +- .../components/supervision_components.js | 69 +++++++++------- web/server/gui/source/lida_view.js | 4 +- web/server/gui/source/utils/backend.js | 70 ++++++---------- web/server/gui/source/utils/languages.js | 17 ++-- web/server/matilda_app.py | 17 +++- 12 files changed, 170 insertions(+), 159 deletions(-) diff --git a/web/server/database.py b/web/server/database.py index d04bb4c..c1db4fe 100644 --- a/web/server/database.py +++ b/web/server/database.py @@ -139,6 +139,11 @@ def updateDoc(searchFields, collection, updateFields): DatabaseManagement.selected(collection).update(searchFields, { "$set": updateFields }) + def updateDocs(searchFields, collection, updateFields): + + DatabaseManagement.selected(collection).update_many(searchFields, { "$set": updateFields }) + + def pullFromDoc(doc_id, collection, field): value = field["dialogue"] @@ -169,7 +174,6 @@ def pullFromDoc(doc_id, collection, field): def dumpDatabase(): - collections = DatabaseManagement.db.collection_names() dump = {} for i, collection_name in enumerate(collections): diff --git a/web/server/gui/assets/css/main.css b/web/server/gui/assets/css/main.css index e76a92a..ab1172a 100644 --- a/web/server/gui/assets/css/main.css +++ b/web/server/gui/assets/css/main.css @@ -359,6 +359,7 @@ select { #supervision #dialogue-menu { height:3em; + grid-column-start: 1; } #supervision #dialogue-menu .back-button { diff --git a/web/server/gui/source/components/all_dialogues_components.js b/web/server/gui/source/components/all_dialogues_components.js index df76eee..18e3485 100644 --- a/web/server/gui/source/components/all_dialogues_components.js +++ b/web/server/gui/source/components/all_dialogues_components.js @@ -191,30 +191,7 @@ Vue.component("all-dialogues", { - - - -
` diff --git a/web/server/gui/source/components/annotation_app_components.js b/web/server/gui/source/components/annotation_app_components.js index e8c8e4c..86febaa 100644 --- a/web/server/gui/source/components/annotation_app_components.js +++ b/web/server/gui/source/components/annotation_app_components.js @@ -65,7 +65,6 @@ Vue.component("annotation-app", { annotationAppEventBus.$on("go_back", this.go_back ); // DIALOGUE TURNS EVENTS - //annotationAppEventBus.$on( "turn_updated_string", this.turn_update ); annotationAppEventBus.$on( "update_turn_id", this.id_updated_from_ids_list ); annotationAppEventBus.$on( "delete_turn", this.remove_turn ); @@ -97,7 +96,6 @@ Vue.component("annotation-app", { annotationAppEventBus.$off("go_back", this.go_back ); // DIALOGUE TURNS EVENTS - //annotationAppEventBus.$off( "turn_updated_string", this.turn_update ); annotationAppEventBus.$off( "update_turn_id", this.id_updated_from_ids_list ); annotationAppEventBus.$off( "delete_turn", this.remove_turn ); @@ -306,6 +304,7 @@ Vue.component("annotation-app", { if (status == "success") { this.allDataSaved = true; //fields = {"status":mainApp.collectionRate}; + //this saves updated annotation rate together with each click on save button //backend.update_annotations(mainApp.activeCollection, fields, false); } else { this.allDataSaved = false; @@ -456,7 +455,7 @@ Vue.component('dialogue-menu',{ v-bind:value="dialogueTitle"> + v-on:focusout="toggleTitleEdit()"> --> @@ -550,7 +549,8 @@ Vue.component('dialogue-turns',{ v-bind:currentId="currentId" v-bind:myId="index" v-bind:selectingText="selectingText" - v-bind:style="{ maxWidth:maxWidth+'%' }"> + v-bind:style="{ maxWidth:maxWidth+'%' }" + v-bind:readOnly="readOnly">
@@ -570,24 +570,21 @@ Vue.component('dialogue-meta',{ } }, methods :{ - turn_updated_string : function(event){ - annotationAppEventBus.$emit("turn_updated_string", event ) - }, check_if_selected(){ return this.currentId==this.myId; }, update_id(){ annotationAppEventBus.$emit("update_turn_id", this.myId); }, - resize_turn_width(newValue) { + resize_turn_width: function(newValue) { this.maxWidth = newValue; annotationAppEventBus.$emit("change_option", "change_width", newValue); }, - change_max_chars(newValue) { + change_max_chars: function(newValue) { this.maxChars = newValue; annotationAppEventBus.$emit("change_option", "change_chars", newValue); }, - auto_save_value(event) { + auto_save_value: function(event) { annotationAppEventBus.$emit("change_auto_save", event.target.checked); }, }, @@ -641,18 +638,19 @@ Vue.component('dialogue-meta',{ Vue.component('dialogue-turn',{ // primaryElementClass is the class used to select the correct input field // to correctly set the focus when turns are changed with arrow keys or enter - props : ["turn","currentId","myId", "primaryElementClass", "selectingText"], + props : ["turn","currentId","myId", "primaryElementClass", "selectingText", "readOnly"], data: function (){ return { guiMessages, + editing:false, maxWidth: mainApp.maxWidth, maxChars: mainApp.maxChars, selectedWords:{"sys":{},"usr":{}} } }, methods :{ - turn_updated_string : function(event){ - annotationAppEventBus.$emit("turn_updated_string", event ) + turn_updated_string : function(){ + annotationAppEventBus.$emit("turn_updated_string") }, check_if_selected(){ return this.currentId==this.myId; @@ -698,6 +696,16 @@ Vue.component('dialogue-turn',{ this.selectedWords = null; this.selectedWords = {"sys":{},"usr":{}}; }, + editing_mode: function() { + console.log("Editing turn content..."); + this.editing = true; + }, + send_new_turn: function() { + if (confirm(guiMessages.selected.annotation_app.confirmEditing)) { + this.turn_updated_string(); + this.editing = false; + } + }, }, mounted(){ if (this.currentId==this.myId){ @@ -727,11 +735,18 @@ Vue.component('dialogue-turn',{
+ v-show="selectingText != false && readOnly != true" class="help-button btn btn-sm btn-primary" + v-on:click="selection_done()" v-bind:id="'selection-done-'+currentId" + style="float:right"> + {{guiMessages.selected.annotation_app.doneSelection}} + + +
@@ -746,11 +761,17 @@ Vue.component('dialogue-turn',{
+ + - + - + - - - - +
-
` @@ -814,13 +833,12 @@ Vue.component('annotations',{ template: `
-
- Current Turn: {{currentId}} -
+
Current Turn: {{currentId}}
+ v-bind:dialogueId="dialogueId" + v-bind:supervision="readOnly"> + v-bind:turn="currentId" + v-bind:supervision="readOnly"> -
+
{{uniqueName.replace(/_/g, ' ')}}
@@ -205,7 +205,7 @@ Vue.component('classification-string-annotation', { adminEventBus.$on("switch_slot_values", this.switchSlotValue); this.collapsed = "new"; } else { - if ((this.classes.length > 1) && (this.slotView == "new")) { + if ((this.classes.length > 1 || this.supervision) && (this.slotView == "new")) { this.collapsed = "new"; } } @@ -544,7 +544,7 @@ Vue.component('classification-string-annotation', {
- Label: - +