From 2dec17b1b9d47d82dcba667821063e280ea0b354 Mon Sep 17 00:00:00 2001
From: Inga Kirschnick <inga.kirschnick@uni-bielefeld.de>
Date: Mon, 9 Oct 2023 15:42:01 +0200
Subject: [PATCH] Editing Entity Type

---
 app/static/js/CorpusAnalysis/QueryBuilder.js  | 12 +++
 .../ElementReferencesQueryBuilder.js          |  3 +
 .../GeneralFunctionsQueryBuilder.js           | 94 +++++++++++++------
 ...alAttributeBuilderFunctionsQueryBuilder.js | 58 +++++++-----
 ...enAttributeBuilderFunctionsQueryBuilder.js | 82 ++++++++--------
 .../query_builder/_query_builder.html.j2      | 67 +++++++------
 6 files changed, 192 insertions(+), 124 deletions(-)

diff --git a/app/static/js/CorpusAnalysis/QueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder.js
index c51bc4a5..379a39ea 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder.js
@@ -33,7 +33,19 @@ class ConcordanceQueryBuilder {
       document.querySelector('#corpus-analysis-concordance-positional-attr-modal'), 
       {
         onOpenStart: () => {
+          this.tokenAttributeBuilderFunctions.preparePositionalAttrModal();
           this.tokenAttributeBuilderFunctions.optionToggleHandler();
+        },
+        onCloseStart: () => {
+          this.tokenAttributeBuilderFunctions.resetPositionalAttrModal();
+        }
+      }
+    );
+    this.elements.structuralAttrModal = M.Modal.init(
+      document.querySelector('#corpus-analysis-concordance-structural-attr-modal'), 
+      {
+        onCloseStart: () => {
+          this.structuralAttributeBuilderFunctions.resetStructuralAttrModal();
         }
       }
     );
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
index 17df5ed2..bfd6fd86 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
@@ -3,6 +3,8 @@ class ElementReferencesQueryBuilder {
     // General Elements
     this.queryInputField = document.querySelector('#corpus-analysis-concordance-query-builder-input-field');
     this.queryChipElements = [];
+    this.editingModusOn = false;
+    this.editedQueryChipElementIndex = undefined;
 
     // Structural Attribute Builder Elements
     this.structuralAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-structural-attr-modal'));
@@ -12,6 +14,7 @@ class ElementReferencesQueryBuilder {
     this.englishEntTypeSelection = document.querySelector('#corpus-analysis-concordance-english-ent-type-selection');
     this.germanEntTypeSelection = document.querySelector('#corpus-analysis-concordance-german-ent-type-selection');
     this.textAnnotationSelection = document.querySelector('#corpus-analysis-concordance-text-annotation-options');
+    this.textAnnotationInput = document.querySelector('#corpus-analysis-concordance-text-annotation-input');
 
     // Token Attribute Builder Elements
     this.positionalAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-positional-attr-modal'));
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
index 28f2aeea..6ab84169 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
@@ -5,7 +5,7 @@ class GeneralFunctionsQueryBuilder {
 
   toggleClass(elements, className, action){
     elements.forEach(element => {
-      document.querySelector('[data-toggle-area="' + element + '"]').classList[action](className);
+      document.querySelector(`[data-toggle-area="${element}"]`).classList[action](className);
     });
   }
 
@@ -22,7 +22,7 @@ class GeneralFunctionsQueryBuilder {
 
   removePlaceholder() {
     let placeholder = this.elements.queryInputField.querySelector('#corpus-analysis-concordance-query-builder-input-field-placeholder');  
-    if (placeholder) {
+    if (placeholder && this.elements.queryInputField !== undefined) {
       this.elements.queryInputField.innerHTML = '';
     }
   }
@@ -41,21 +41,33 @@ class GeneralFunctionsQueryBuilder {
     })
   }
 
+  submitQueryChipElement(dataType = undefined, prettyQueryText = undefined, queryText = undefined, index = null, isClosingTag = false, isEditable = false) {
+    if (this.elements.editingModusOn) {
+      let editedQueryChipElement = this.elements.queryChipElements[this.elements.editedQueryChipElementIndex];
+      editedQueryChipElement.dataset.type = dataType;
+      editedQueryChipElement.dataset.query = queryText;
+      editedQueryChipElement.firstChild.textContent = prettyQueryText;
+      this.updateChipList();
+      this.queryPreviewBuilder();
+    } else {
+      this.queryChipFactory(dataType, prettyQueryText, queryText, index, isClosingTag, isEditable);
+    }
+  }
 
-  queryChipFactory(dataType, prettyQueryText, queryText, index = null, isClosingTag = false) {
+
+  queryChipFactory(dataType, prettyQueryText, queryText, index = null, isClosingTag = false, isEditable = false) {
     // Creates a new query chip element, adds Eventlisteners for selection, deletion and drag and drop and appends it to the query input field.
-    
     queryText = Utils.escape(queryText);
     prettyQueryText = Utils.escape(prettyQueryText);
     let queryChipElement = Utils.HTMLToElement(
       `
         <span class="chip query-component" data-type="${dataType}" data-query="${queryText}" draggable="true" data-closing-tag="${isClosingTag}">
-          ${prettyQueryText}
-          ${isClosingTag ? '<i class="material-icons" style="padding-top:5px; font-size:20px; cursor:pointer;">lock_open</i>' : '<i class="material-icons close">close</i>'}
+          ${prettyQueryText}${isEditable ? '<i class="material-icons chip-action-button" data-chip-action="edit" style="padding-left:5px; font-size:18px; cursor:pointer;">edit</i>': ''}
+          ${isClosingTag ? '<i class="material-icons chip-action-button" data-chip-action="lock" style="padding-top:5px; font-size:20px; cursor:pointer;">lock_open</i>' : '<i class="material-icons close chip-action-button" data-chip-action="delete">close</i>'}
         </span>
       `
     );
-    this.actionListeners(queryChipElement, isClosingTag);
+    this.actionListeners(queryChipElement);
     queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement));
     queryChipElement.addEventListener('dragend', this.handleDragEnd);
 
@@ -80,7 +92,7 @@ class GeneralFunctionsQueryBuilder {
     this.queryPreviewBuilder();
   }
 
-  actionListeners(queryChipElement, isClosingTag) {
+  actionListeners(queryChipElement) {
     let notQuantifiableDataTypes = ['start-sentence', 'end-sentence', 'start-entity', 'start-empty-entity', 'end-entity', 'token-incidence-modifier'];
     queryChipElement.addEventListener('click', (event) => {
       if (event.target.classList.contains('chip')) {
@@ -89,22 +101,60 @@ class GeneralFunctionsQueryBuilder {
         }
       }
     });
-    queryChipElement.querySelector('i').addEventListener('click', () => {
-      if (isClosingTag) {
-        this.lockClosingChipElement(queryChipElement);
-      } else {
+    let chipActionButtons = queryChipElement.querySelectorAll('.chip-action-button');
+    chipActionButtons.forEach(button => {
+      button.addEventListener('click', (event) => {
+      if (event.target.dataset.chipAction === 'delete') {
         this.deleteChipElement(queryChipElement);
+      } else if (event.target.dataset.chipAction === 'edit') {
+        this.editChipElement(queryChipElement);
+      } else if (event.target.dataset.chipAction === 'lock') {
+        this.lockClosingChipElement(queryChipElement);
       }
+      });
     });
   }
 
+  editChipElement(queryChipElement) {
+    this.elements.editingModusOn = true;
+    this.elements.editedQueryChipElementIndex = Array.from(this.elements.queryInputField.children).indexOf(queryChipElement);
+    switch (queryChipElement.dataset.type) {
+      case 'start-entity':
+        this.elements.structuralAttrModal.open();
+        this.toggleClass(['entity-builder'], 'hide', 'remove');
+        this.toggleEditingAreaStructureAttrModal('add');
+        let entType = queryChipElement.dataset.query.replace(/<ent_type="|">/g, '');
+        let isEnglishEntType = this.elements.englishEntTypeSelection.querySelector(`option[value=${entType}]`) !== null;
+        let selection = isEnglishEntType ? this.elements.englishEntTypeSelection : this.elements.germanEntTypeSelection;
+        this.resetMaterializeSelection([selection], entType);
+        break;
+      default:
+        break;
+    }
+  }
+
   lockClosingChipElement(queryChipElement) {
     let chipIndex = Array.from(this.elements.queryInputField.children).indexOf(queryChipElement);
-    this.queryChipFactory(queryChipElement.dataset.type, queryChipElement.firstChild.textContent, queryChipElement.dataset.query, chipIndex+1);
+    this.submitQueryChipElement(queryChipElement.dataset.type, queryChipElement.firstChild.textContent, queryChipElement.dataset.query, chipIndex+1);
     this.deleteChipElement(queryChipElement);
     this.updateChipList();
   }
 
+  
+  deleteChipElement(attr) {
+    if (attr.dataset.type === "start-sentence") {
+      this.elements.sentenceElement.innerHTML = 'Sentence';
+    } else if (attr.dataset.type === "start-entity" || attr.dataset.type === "start-empty-entity") {
+      this.elements.entityElement.innerHTML = 'Entity';
+    }
+    this.elements.queryInputField.removeChild(attr);
+    if (this.elements.queryInputField.children.length === 0) {
+      this.addPlaceholder();
+    }
+    this.updateChipList();
+    this.queryPreviewBuilder();
+  }
+
   handleDragStart(queryChipElement, event) {
     // is called when a query chip is dragged. It creates a dropzone (in form of a chip) for the dragged chip and adds it to the query input field.
     let queryChips = this.elements.queryInputField.querySelectorAll('.query-component');
@@ -176,20 +226,6 @@ class GeneralFunctionsQueryBuilder {
     queryPreview.parentNode.classList.toggle('hide', queryString === ';');
   }
 
-  deleteChipElement(attr) {
-    if (attr.dataset.type === "start-sentence") {
-      this.elements.sentenceElement.innerHTML = 'Sentence';
-    } else if (attr.dataset.type === "start-entity" || attr.dataset.type === "start-empty-entity") {
-      this.elements.entityElement.innerHTML = 'Entity';
-    }
-    this.elements.queryInputField.removeChild(attr);
-    if (this.elements.queryInputField.children.length === 0) {
-      this.addPlaceholder();
-    }
-    this.updateChipList();
-    this.queryPreviewBuilder();
-  }
-
   selectChipElement(attr) {
     document.querySelectorAll('.chip.teal').forEach(element => {
         if (element !== attr) {
@@ -207,7 +243,7 @@ class GeneralFunctionsQueryBuilder {
     // Adds a token incidence modifier to the query input field.
     let selectedChip = this.elements.queryInputField.querySelector('.chip.teal');
     let selectedChipIndex = Array.from(this.elements.queryInputField.children).indexOf(selectedChip);
-    this.queryChipFactory('token-incidence-modifier', incidenceModifierPretty, incidenceModifier, selectedChipIndex+1);
+    this.submitQueryChipElement('token-incidence-modifier', incidenceModifierPretty, incidenceModifier, selectedChipIndex+1);
     this.selectChipElement(selectedChip);
   }
 
@@ -243,7 +279,7 @@ class GeneralFunctionsQueryBuilder {
     let expertModeInputFieldValue = document.querySelector('#corpus-analysis-concordance-form-query').value;
     let chipElements = this.parseTextToChip(expertModeInputFieldValue);
     for (let chipElement of chipElements) {
-      this.queryChipFactory(chipElement['type'], chipElement['pretty'], chipElement['query']);
+      this.submitQueryChipElement(chipElement['type'], chipElement['pretty'], chipElement['query']);
     }
   }
   
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
index c9bb402c..15f7bc57 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
@@ -9,23 +9,48 @@ class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQu
       });
     });
     document.querySelector('.ent-type-selection-action[data-ent-type="any"]').addEventListener('click', () => {
-      this.queryChipFactory('start-empty-entity', 'Entity Start', '<ent>');
-      this.queryChipFactory('end-entity', 'Entity End', '</ent>', null, true);
-      this.resetAndCloseStructuralAttrModal();
+      this.submitQueryChipElement('start-empty-entity', 'Entity Start', '<ent>');
+      this.submitQueryChipElement('end-entity', 'Entity End', '</ent>', null, true);
+      this.elements.structuralAttrModal.close();
     });
     document.querySelector('.ent-type-selection-action[data-ent-type="english"]').addEventListener('change', (event) => {
-      this.queryChipFactory('start-entity', `Entity Type=${event.target.value}`, `<ent_type="${event.target.value}">`);
-      this.queryChipFactory('end-entity', 'Entity End', '</ent_type>', null, true);
-      this.resetAndCloseStructuralAttrModal();
+      this.submitQueryChipElement('start-entity', `Entity Type=${event.target.value}`, `<ent_type="${event.target.value}">`, null, false, true);
+      if (!this.elements.editingModusOn) {
+        this.submitQueryChipElement('end-entity', 'Entity End', '</ent_type>', null, true);
+      }
+      this.elements.structuralAttrModal.close();
     });
+    document.querySelector('.ent-type-selection-action[data-ent-type="german"]').addEventListener('change', (event) => {
+      this.submitQueryChipElement('start-entity', `Entity Type=${event.target.value}`, `<ent_type="${event.target.value}">`, null, false, true); 
+      if (!this.elements.editingModusOn) {
+        this.submitQueryChipElement('end-entity', 'Entity End', '</ent_type>', null, true);
+      }
+      this.elements.structuralAttrModal.close();
+    });
+  }
+
+  resetStructuralAttrModal() {
+    this.resetMaterializeSelection([this.elements.englishEntTypeSelection, this.elements.germanEntTypeSelection]);
+    this.resetMaterializeSelection([this.elements.textAnnotationSelection], 'address');
+    this.elements.textAnnotationInput.value = '';
+
+    this.toggleClass(['entity-builder', 'text-annotation-builder'], 'hide', 'add');
+    this.toggleEditingAreaStructureAttrModal('remove');
+    this.elements.editingModusOn = false;
+    this.elements.editedQueryChipElementIndex = undefined;
+  }
+
+  toggleEditingAreaStructureAttrModal(action) {
+    // If the user edits a query chip element, the corresponding editing area is displayed and the other areas are hidden or disabled.
+    this.toggleClass(['sentence-button', 'entity-button', 'text-annotation-button', 'any-type-entity-button'], 'disabled', action);
   }
 
   actionButtonInStrucAttrModalHandler(action) {
     switch (action) {
       case 'sentence':
-        this.queryChipFactory('start-sentence', 'Sentence Start', '<s>');
-        this.queryChipFactory('end-sentence', 'Sentence End', '</s>', null, true);
-        this.resetAndCloseStructuralAttrModal();
+        this.submitQueryChipElement('start-sentence', 'Sentence Start', '<s>');
+        this.submitQueryChipElement('end-sentence', 'Sentence End', '</s>', null, true);
+        this.elements.structuralAttrModal.close();
         break;
       case 'entity':
         this.toggleClass(['entity-builder'], 'hide', 'toggle');
@@ -57,19 +82,8 @@ class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQu
       }, 3000);
     } else {
       let queryText = `:: match.text_${textAnnotationOptions.value}="${textAnnotationInput.value}"`;
-      this.queryChipFactory('text-annotation', `${textAnnotationOptions.value}=${textAnnotationInput.value}`, queryText);
-      this.resetAndCloseStructuralAttrModal();
+      this.submitQueryChipElement('text-annotation', `${textAnnotationOptions.value}=${textAnnotationInput.value}`, queryText);
+      this.elements.structuralAttrModal.close();
     }
   }
-
-  resetAndCloseStructuralAttrModal() {
-    let textAnnotatinInput = document.querySelector('#corpus-analysis-concordance-text-annotation-input');
-    textAnnotatinInput.value = '';
-    this.resetMaterializeSelection([this.elements.englishEntTypeSelection, this.elements.germanEntTypeSelection]);
-    this.resetMaterializeSelection([this.elements.textAnnotationSelection], 'address');
-
-    this.toggleClass(['entity-builder', 'text-annotation-builder'], 'hide', 'add');
-    this.elements.structuralAttrModal.close();
-  }
-
 }
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
index 1ac6835a..0e4c4bd1 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
@@ -3,20 +3,8 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
     super(elements);
     this.elements = elements;
 
-    this.elements.positionalAttrSelection.addEventListener('change', (event) => {
-      this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
-      if (event.target.value !== 'empty-token') {
-        this.toggleClass([event.target.value], 'hide', 'remove');
-        this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
-        this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
-      }
-      if (event.target.value === 'word' || event.target.value === 'lemma') {
-        this.toggleClass(['input-field-options'], 'hide', 'remove');
-      } else if (event.target.value === 'empty-token'){
-        this.addTokenToQuery();
-      } else {
-        this.toggleClass(['input-field-options'], 'hide', 'add');
-      }
+    this.elements.positionalAttrSelection.addEventListener('change', () => {
+      this.preparePositionalAttrModal();
     });
 
     // Options for positional attribute selection
@@ -33,6 +21,46 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
     this.elements.simplePosSelection.addEventListener('change', () => {this.optionToggleHandler();});
   }
 
+  resetPositionalAttrModal() {
+    let originalSelectionList = 
+      `
+        <option value="word" selected>word</option>
+        <option value="lemma" >lemma</option>
+        <option value="english-pos">english pos</option>
+        <option value="german-pos">german pos</option>
+        <option value="simple-pos">simple_pos</option>
+        <option value="empty-token">empty token</option>
+      `;
+    this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
+    this.elements.tokenQuery.innerHTML = '';
+    this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
+    this.toggleClass(['word', 'input-field-options'], 'hide', 'remove');
+    this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
+
+    document.querySelector('#corpus-analysis-concordance-positional-attr-selection option[value="word"]').selected = true;
+
+    this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
+    this.resetMaterializeSelection([this.elements.positionalAttrSelection], "word");
+    this.elements.editingModusOn = false;
+    this.elements.editedQueryChipElementIndex = undefined;
+  }
+  
+  preparePositionalAttrModal() {
+    let selection = this.elements.positionalAttrSelection.value;
+    if (selection !== 'empty-token') {
+      this.toggleClass([selection], 'hide', 'remove');
+      this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
+      this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
+    }
+    if (selection === 'word' || selection === 'lemma') {
+      this.toggleClass(['input-field-options'], 'hide', 'remove');
+    } else if (selection === 'empty-token'){
+      this.addTokenToQuery();
+    } else {
+      this.toggleClass(['input-field-options'], 'hide', 'add');
+    }
+  }
+
   tokenInputCheck() {
     let input;
 
@@ -154,8 +182,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
     // isTokenQueryInvalid looks if a valid value is passed. If the input fields/dropdowns are empty (isTokenQueryInvalid === true), no token is added.
     if (this.elements.isTokenQueryInvalid === false) {
       tokenQueryCQLText = '[' + tokenQueryCQLText + ']';
-      this.queryChipFactory('token', tokenQueryPrettyText, tokenQueryCQLText);
-      this.resetPositionalAttrModal();
+      this.submitQueryChipElement('token', tokenQueryPrettyText, tokenQueryCQLText);
       this.elements.positionalAttrModal.close();
     }
   }
@@ -308,27 +335,4 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
       this.toggleClass(['input-field-options'], 'hide', 'add');
     }
   }
-
-  
-  resetPositionalAttrModal() {
-    let originalSelectionList = 
-      `
-        <option value="word" selected>word</option>
-        <option value="lemma" >lemma</option>
-        <option value="english-pos">english pos</option>
-        <option value="german-pos">german pos</option>
-        <option value="simple-pos">simple_pos</option>
-        <option value="empty-token">empty token</option>
-      `;
-    this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
-    this.elements.tokenQuery.innerHTML = '';
-    this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
-    this.toggleClass(['word', 'input-field-options'], 'hide', 'remove');
-    this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
-
-    document.querySelector('#corpus-analysis-concordance-positional-attr-selection option[value="word"]').selected = true;
-
-    this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
-    this.resetMaterializeSelection([this.elements.positionalAttrSelection], "word");
-  }
 }
diff --git a/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2
index c4f63943..836bdf83 100644
--- a/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2
+++ b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2
@@ -65,49 +65,49 @@
     <br>
     <div class="row">
       <div class="col s12">
-        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="sentence">sentence</a>
-        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="entity">entity</a>
-        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="meta-data">Meta Data</a>
+        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="sentence" data-toggle-area="sentence-button">sentence</a>
+        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="entity" data-toggle-area="entity-button">entity</a>
+        <a class="btn-small waves-effect waves-light" data-structural-attr-modal-action-button="meta-data" data-toggle-area="text-annotation-button">Meta Data</a>
       </div>
     </div>
     <div id="corpus-analysis-concordance-entity-builder" data-toggle-area="entity-builder" class="hide">
       <p></p>
       <br>
       <div class="row">
-        <a class="btn waves-effect waves-light col ent-type-selection-action" data-ent-type="any">Add Entity of any type</a>
+        <a class="btn waves-effect waves-light col ent-type-selection-action" data-ent-type="any" data-toggle-area="any-type-entity-button">Add Entity of any type</a>
         <p class="col s1 l1"></p>
         <div class= "input-field col s3">
-            <select id="corpus-analysis-concordance-english-ent-type-selection" name="englishenttype" class="ent-type-selection-action" data-ent-type="english">
-              <option value="default" disabled selected>English ent_type</option>
-              <option value="CARDINAL">CARDINAL</option>
-              <option value="DATE">DATE</option>
-              <option value="EVENT">EVENT</option>
-              <option value="FAC">FAC</option>
-              <option value="GPE">GPE</option>
-              <option value="LANGUAGE">LANGUAGE</option>
-              <option value="LAW">LAW</option>
-              <option value="LOC">LOC</option>
-              <option value="MONEY">MONEY</option>
-              <option value="NORP">NORP</option>
-              <option value="ORDINAL">ORDINAL</option>
-              <option value="ORG">ORG</option>
-              <option value="PERCENT">PERCENT</option>
-              <option value="PERSON">PERSON</option>
-              <option value="PRODUCT">PRODUCT</option>
-              <option value="QUANTITY">QUANTITY</option>
-              <option value="TIME">TIME</option>
-              <option value="WORK_OF_ART">WORK_OF_ART</option>
-            </select>
-            <label>Entity Type</label>
+          <select id="corpus-analysis-concordance-english-ent-type-selection" name="englishenttype" class="ent-type-selection-action" data-ent-type="english">
+            <option value="default" disabled selected>English ent_type</option>
+            <option value="CARDINAL">CARDINAL</option>
+            <option value="DATE">DATE</option>
+            <option value="EVENT">EVENT</option>
+            <option value="FAC">FAC</option>
+            <option value="GPE">GPE</option>
+            <option value="LANGUAGE">LANGUAGE</option>
+            <option value="LAW">LAW</option>
+            <option value="LOC">LOC</option>
+            <option value="MONEY">MONEY</option>
+            <option value="NORP">NORP</option>
+            <option value="ORDINAL">ORDINAL</option>
+            <option value="ORG">ORG</option>
+            <option value="PERCENT">PERCENT</option>
+            <option value="PERSON">PERSON</option>
+            <option value="PRODUCT">PRODUCT</option>
+            <option value="QUANTITY">QUANTITY</option>
+            <option value="TIME">TIME</option>
+            <option value="WORK_OF_ART">WORK_OF_ART</option>
+          </select>
+          <label>Entity Type</label>
         </div>
         <div class= "input-field col s3">
-            <select id="corpus-analysis-concordance-german-ent-type-selection" name="germanenttype" class="ent-type-selection-action" data-ent-type="german">
-              <option value="default" disabled selected>German ent_type</option>
-              <option value="LOC">LOC</option>
-              <option value="MISC">MISC</option>
-              <option value="ORG">ORG</option>
-              <option value="PER">PER</option>
-            </select>
+          <select id="corpus-analysis-concordance-german-ent-type-selection" name="germanenttype" class="ent-type-selection-action" data-ent-type="german">
+            <option value="default" disabled selected>German ent_type</option>
+            <option value="LOC">LOC</option>
+            <option value="MISC">MISC</option>
+            <option value="ORG">ORG</option>
+            <option value="PER">PER</option>
+          </select>
         </div>
       </div>
     </div>
@@ -385,7 +385,6 @@
     {{ exactly_n_modal_content("character") }}
     {{ exactly_nm_modal_content("character") }}
       
-    </div>
   </div>
 </div>
 {% endmacro %}
-- 
GitLab