Tour: extend explanations to vc creation (fixes #147)

Change-Id: I50e41b9cb0d26082d1cdf9de6ad4571430f4ccd2
diff --git a/dev/js/spec/tourSpec.js b/dev/js/spec/tourSpec.js
index 86ae27b..2235561 100644
--- a/dev/js/spec/tourSpec.js
+++ b/dev/js/spec/tourSpec.js
@@ -4,7 +4,7 @@
  * @author Helge Stallkamp
  */
 
-define(['tour/tours', 'vc', 'session', 'match', 'hint',  'hint/foundries/cnx', 'selectMenu', 'loc/dereko'], function(tourClass, vcClass, sessionClass, matchClass, hintClass, hintArray, selectMenuClass){
+define(['tour/tours', 'vc', 'vc/unspecified', 'session', 'match', 'hint',  'hint/foundries/cnx', 'selectMenu', 'loc/dereko'], function(tourClass, vcClass, docClassUnspec, sessionClass, matchClass, hintClass, hintArray, selectMenuClass){
   const loc   = KorAP.Locale;
   
   var introKorAP =
@@ -14,7 +14,19 @@
       "<button type='submit' id='qsubmit' title='Los!'><span>Los!</span></button>" + 
     "</div>" + 
     "<!-- Search in the following virtual corpus -->"+
-    "<div id='vc-view'></div>" +
+    "<div id='vc-view'>" +
+      "<div class='vc'>"+
+        "<div class='builder'>"+
+          "<div class='doc unspecified'><span>⋯</span></div>" +
+        "</div>" +
+       "<div class='action button-view button-group'><span title='Zuklappen' class='button-icon minimize'><span>Zuklappen</span></span></div>" +
+       "<div>" +
+          "<div class='panel vcinfo'>" +
+            "<div></div>" +
+            "<div class='action button-panel vcinfo button-group'><span title='Korpusstatistik' class='statistic'><span>Korpusstatistik</span></span></div>" +
+          "</div>" +
+       "</div>" +
+      "</div>" + 
     "in" +
     "<span id='vc-choose' class='select'><span>allen Korpora</span></span>" +
     "<input id='cq' name='cq' type='text' style='display: none;'>" +
@@ -419,6 +431,7 @@
     
     KorAP.Hint = hintClass.create({inputField: intrkorap.getElementById("q-field")});
     
+
     it('IDs and classes, that are needed for the guided tour should be in existence', function(){
       //gTstartSearch
       expect(intrkorap.querySelector('#searchbar')).not.toBeNull();
@@ -426,6 +439,7 @@
       expect(intrkorap.querySelector('#hint')).not.toBeNull();
       expect(intrkorap.querySelector('#vc-choose')).not.toBeNull();     
       expect(intrkorap.querySelector('#vc-view')).not.toBeNull();
+      expect(intrkorap.querySelector('#vc-view * .doc')).not.toBeNull();
       expect(intrkorap.querySelector('#ql-field').parentNode).not.toBeNull();
       expect(intrkorap.querySelector('#glimpse').parentNode).not.toBeNull();
       expect(intrkorap.querySelector('#view-tutorial')).not.toBeNull();
@@ -436,6 +450,13 @@
       expect(statbut).not.toBeNull();
       statbut.click();
       expect(show.querySelector('.stattable')).not.toBeNull();
+      let docUnspec = document.createElement('div');
+      let doc = docClassUnspec.create();
+      docUnspec.append(doc.element());
+      let vcbut = docUnspec.querySelector('.doc > span');
+      vcbut.click(); 
+      expect(docUnspec.querySelector('.menu.roll')).not.toBeNull();  
+      
       //IDs and classes, that are needed for the second guided tour(gTshowResults()) should be in existence, too
       expect(resultkor.querySelector('#search')).not.toBeNull();
       expect(resultkor.querySelector('#search > ol > li')).not.toBeNull();
@@ -447,6 +468,7 @@
       resultkor.querySelector(".info").click();
       expect(resultkor.querySelector('.view.tokentable')).not.toBeNull();
       expect(resultkor.querySelector('.tree')).not.toBeNull(); 
+
     });
       
    it('Guided Tour should be started and display steps and labels in the right order', function(){
@@ -464,30 +486,43 @@
      expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
      searchTour.exit();
      
+     let show = document.createElement('div');
+     show.appendChild(vc.element());
+     let statbut = show.querySelector('.statistic');
+     statbut.click();
+     let corpstat = show.querySelector('.stattable');
+     intrkorap.appendChild(corpstat);
+     
      for(let i = 2; i <= totalSteps; i++){
        searchTour.goToStepNumber(i);
        expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(searchTour.testIntros[i-1]);
-
        switch(i){
        case 4:
-       expect(intrkorap.querySelector('#hint')).not.toBeNull(); 
-       expect(KorAP.Hint).not.toBeNull();
-       expect(KorAP.Hint.active().dontHide).toBe(true); 
-       expect(KorAP.Hint._active).not.toBeNull();
-       break;
-       
+         expect(intrkorap.querySelector('#hint')).not.toBeNull(); 
+         expect(KorAP.Hint).not.toBeNull();
+         expect(KorAP.Hint.active().dontHide).toBe(true); 
+         expect(KorAP.Hint._active).not.toBeNull();
+         break;
        case 5:
-       expect(KorAP.Hint._active).toBeNull();
-       break;
-                     
+         expect(KorAP.Hint._active).toBeNull();
+         break;
+       case 6:
+          expect(KorAP._vcKeyMenu.dontHide).toBe(false); 
+         break;
+      case 7:
+         expect(KorAP._vcKeyMenu.dontHide).toBe(true); 
+         break;
+        case 8:
+          expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+          break;
        case totalSteps:
-       expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_ldoneSearch);
-       expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
-       expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
-       break;
+         expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_ldoneSearch);
+         expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
+         expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
+         break;
        }
        searchTour.exit();
-     } 
+    } 
      
      let resultTour = tourClass.gTshowResults(resultkor);
      KorAP.session = sessionClass.create('KalamarJSDem'); 
@@ -509,7 +544,7 @@
      } 
    });
    
-   it('Guided Tour should hide Hint and QL Menu if aborted',  function(){
+   it('Guided Tour should hide Hint if aborted',  function(){
      let tourAbort = tourClass.gTstartSearch(intrkorap);
      tourAbort.start(); 
      expect(KorAP.Hint._active).toBeNull();
@@ -520,6 +555,30 @@
      tourAbort.exit();
      expect(KorAP.Hint._active).toBeNull();
    });
+
+   it('Guided Tour should hide vcKeyMenu if aborted',  function(){
+     let tourAbort = tourClass.gTstartSearch(intrkorap);
+     tourAbort.start(); 
+     expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+     tourAbort.goToStepNumber(6);
+     expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+     tourAbort.goToStepNumber(7);
+     expect(KorAP._vcKeyMenu.dontHide).toBe(true);
+     tourAbort.exit();
+     expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+   });
+   
+   it('Guided Tour should hide vcKeyMenu in the next step ',  function(){
+     let tourNext = tourClass.gTstartSearch(intrkorap);
+     tourNext.start(); 
+     expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+     tourNext.goToStepNumber(7);
+     expect(KorAP._vcKeyMenu.dontHide).toBe(true);
+     tourNext.goToStepNumber(8);
+     expect(KorAP._vcKeyMenu.dontHide).toBe(false);
+   });
+
+   
    
   });
 });
diff --git a/dev/js/src/loc/de.js b/dev/js/src/loc/de.js
index 25ce94b..f6c9668 100644
--- a/dev/js/src/loc/de.js
+++ b/dev/js/src/loc/de.js
@@ -49,7 +49,6 @@
   loc.TOUR_welcti = " <span class='tgreeting'> Willkommen zur KorAP Tour! </span>";
   loc.TOUR_welc = "Hier zeigen wir Ihnen einige wichtige Funktionalitäten von KorAP. " +
                   "Wir führen Sie Schritt für Schritt anhand eines Beispiels durch die Anwendung.";
-  
   loc.TOUR_sear1ti = "Suchanfrage";
   loc.TOUR_sear1 = "Hier können Sie die Suchanfrage eingeben, zum Beispiel die Suche nach '" + loc.TOUR_Qexample + "'." ;
   loc.TOUR_searAnnotti = "Annotationsassistent (1)";
@@ -58,10 +57,15 @@
             "oder die Pfeiltaste nach unten &darr; betätigen. </p>";
   loc.TOUR_annotAssti = "Annotationsassistent (2)";
   loc.TOUR_annotAss = "Der Annotationsassistent erleichert die Formulierung von Suchanfragen mit Annotationen.";
+  
   loc.TOUR_vccho1ti = "Auswahl der Korpora",
   loc.TOUR_vccho1 = "Hier gelangen Sie zum Korpusassistenten.";
-  loc.TOUR_vccho2ti = "Korpusassistent",
+  loc.TOUR_vccho2ti = "Korpusassistent (1)";
   loc.TOUR_vccho2 = "Im Korpusassistenten ist die Definition von Subkorpora durch die Verknüpfung beliebiger Metadatenfelder möglich.";
+  loc.TOUR_vccho3ti = "Korpusassistent (2)";
+  loc.TOUR_vccho3 = "Einige der bekannten Metadatenfelder werden in einem DropDown-Menü angezeigt.";
+  loc.TOUR_vccho4ti = "Korpusassistent (3)";
+  loc.TOUR_vccho4 = "Ein Beispiel: Bilden eines virtuellen Korpus, der alle Texte mit der Dokumentsigle " + loc.TOUR_DocSigle + " enthält.";
   loc.TOUR_vcStat1ti =  "Korpusstatistik (1)",
   loc.TOUR_vcStat1 = "Anzeige der Korpusstatistik.";
   loc.TOUR_vcStat2ti = "Korpusstatistik (2)",
@@ -89,4 +93,5 @@
 
   // Pagination panel
   loc.RANDOM_PAGE = 'Zufallsseite';
+
 });
diff --git a/dev/js/src/loc/dereko.js b/dev/js/src/loc/dereko.js
index 2cdae7d..6912f9b 100644
--- a/dev/js/src/loc/dereko.js
+++ b/dev/js/src/loc/dereko.js
@@ -22,4 +22,5 @@
   
   loc.TOUR_Relations = "corenlp/c";
 
+  loc.TOUR_DocSigle = "WPD17/D01"; 
 });
diff --git a/dev/js/src/tour/tours.js b/dev/js/src/tour/tours.js
index 49f8e4b..afe2c83 100644
--- a/dev/js/src/tour/tours.js
+++ b/dev/js/src/tour/tours.js
@@ -24,8 +24,13 @@
   loc.TOUR_sear1 = loc.TOUR_sear1 || "Input field for the query, for example the search for '" +  loc.TOUR_Qexample + "'.";
   loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper";
   loc.TOUR_annotAss =  loc.TOUR_annotAss || "The assistant displays the annotations of the different layers and helps to formulate queries.";
-  loc.TOUR_vccho1 = loc.TOUR_vccho1 || "Choose corpus";
+  loc.TOUR_vccho1 = loc.TOUR_vccho1 || "Choose corpus";  
+  loc.TOUR_vccho2ti = loc.TOUR_vccho2ti || "Corpus Assistant (1)";
   loc.TOUR_vccho2 = loc.TOUR_vccho2 || "Define your corpus here.";
+  loc.TOUR_vccho3ti = loc.TOUR_vccho3ti || "Corpus Assistant (2)";
+  loc.TOUR_vccho3 = loc.TOUR_vccho3 || "Several of the available metadata can be choosen in a drop down box.";
+  loc.TOUR_vccho4ti =  loc.TOUR_vccho4ti || "Corpus Assistant (3)";
+  loc.TOUR_vccho4 = loc.TOUR_vccho4 || "For example to request all documents with the document sigle " + loc.TOUR_DocSigle + " .";
   loc.TOUR_vcStat1 = loc.TOUR_vcStat1 || "Click here to display corpus statistic.";
   loc.TOUR_vcStat2 = loc.TOUR_vcStat2 || "Corpus statistic";
   loc.TOUR_qlfield = loc.TOUR_qlfield|| "Selection of the query language: You can use KorAP with different query languages.";
@@ -92,54 +97,77 @@
 
       //steps of the example tour
       let Steps =[
+        //Step 1, intro_item 0
         {  
           element: '#link-guided-tour',
           title: loc.TOUR_welcti,
           intro: loc.TOUR_welc,
           position: 'right',
         },
+        //Step 2, intro_item 1
         {
           title: loc.TOUR_sear1ti,
           element: '#q-field',
           intro: loc.TOUR_sear1,
           position: 'bottom'
         },
+        //Step 3, intro_item 2
         {
           title: loc.TOUR_searAnnotti,
           element: '#hint',
           intro: loc.TOUR_searAnnot,
-          position: 'bottom'
+          position: 'auto'
         },
+        //Step 4, intro_item 3
         {
           title: loc.TOUR_annotAssti,
           element: doe.querySelector("#hint > .menu.hint"),
           intro: loc.TOUR_annotAss,
           position: 'bottom',
-          },
+          }, 
+        //Step 5, intro_item 4
         {
-          title:loc.TOUR_vccho1ti,
+          title: loc.TOUR_vccho1ti, 
           element:'#vc-choose',
           intro: loc.TOUR_vccho1,
           position: "bottom",
         },
+        //Step 6, intro_item 5
         {
           title: loc.TOUR_vccho2ti,
           element:'#vc-view',
           intro: loc.TOUR_vccho2,
           position: "bottom",
         }, 
+        //Step 7, intro_item 6
+        {  
+          title: loc.TOUR_vccho3ti,
+          element: doe.querySelector('#vc-view * .doc > menu'),
+          intro: loc.TOUR_vccho3,
+          position: "left",
+        }, 
+        //Step 8, intro_item 7
+        {
+          title: loc.TOUR_vccho4ti,
+          element: doe.querySelector('#vc-view * .doc'),
+          intro: loc.TOUR_vccho4,
+          position: "left",
+        }, 
+        //Step 9, intro_item 8
         {
           title: loc.TOUR_vcStat1ti,
           element: doe.querySelector('.statistic'),
           intro: loc.TOUR_vcStat1,
           position: "left",
         },
+        //Step 10, intro_item 9
         {
           title: loc.TOUR_vcStat2ti,
           element: doe.querySelector('.stattable'),
           intro: loc.TOUR_vcStat2,
           position: "bottom",
         },
+        //Step 11, intro_item 10
         {
           title: loc.TOUR_qlfieldti,
           element: doe.querySelector('#ql-field').parentNode,
@@ -185,25 +213,23 @@
           let vchoo = doe.querySelector("#vc-choose");
           let vcv = doe.querySelector("#vc-view");  
           KorAP._delete.apply(KorAP.vc.root());
-    
-          KorAP.vc.fromJson(loc.TOUR_vcQuery);
           if(!(vcv.querySelector(".active"))){
             vchoo.click();
             /*
              * Intro.js caches elements at the beginning, so element and position has to be set again.
              */
-            intro._introItems[6].element = doe.querySelector('.statistic');
-            intro._introItems[6].position = "left";
+            intro._introItems[8].element = doe.querySelector('.statistic');
+            intro._introItems[8].position = "left";
           }   
-          break;   
-          
+          intro._introItems[7].element = doe.querySelector('#vc-view * .doc');
+          intro._introItems[7].position = "left";
+          break;    
         } 
-        
-        if(this._currentStep == 7){
+        if(this._currentStep == 9){
           let statbut = doe.querySelector('.statistic');
           statbut.click();
-          intro._introItems[7].element = doe.querySelector(".stattable");
-          intro._introItems[7].position = "bottom";
+          intro._introItems[9].element = doe.querySelector(".stattable");
+          intro._introItems[9].position = "bottom";
         }
       });
 
@@ -211,6 +237,10 @@
           if(KorAP.Hint.active() && KorAP.Hint.active().dontHide){
             KorAP.Hint.unshow();
           }
+          if (KorAP._vcKeyMenu.dontHide){
+          KorAP._vcKeyMenu.dontHide = false;
+          KorAP._vcKeyMenu.hide();
+          }
         });
       
       intro.onchange(function(targetElement) {
@@ -229,8 +259,22 @@
           intro._introItems[3].position = doe.querySelector("bottom");
           break;
         case 4: 
-          KorAP.Hint.unshow();      
+          KorAP.Hint.unshow();    
+          KorAP._vcKeyMenu.dontHide = false;
           break;
+        case 6:
+          let vccbut = doe.querySelector('#vc-view * .doc > span');  
+          vccbut.click();
+          KorAP._vcKeyMenu.dontHide = true;
+          intro._introItems[6].element = doe.querySelector('#vc-view * .menu.roll');
+          intro._introItems[6].position = "left";
+          break;
+        case 7: 
+          KorAP._vcKeyMenu.dontHide = false;
+          KorAP._vcKeyMenu.hide();
+          KorAP.vc.fromJson(loc.TOUR_vcQuery);
+          intro._introItems[7].element = doe.querySelector('#vc-view * .doc');
+          intro._introItems[7].position = "left";
         }
         });