blob: 808165b88e89af1fa9259621d51493b2ccd60038 [file] [log] [blame]
hebasta75cfca52019-02-19 13:15:27 +01001/**
2 * Guided Tour to explain the UI
3 *
4 * @author Helge Stallkamp
5 */
6
hebasta87f1b1f2019-07-30 13:03:23 +02007
8define(['lib/intro', 'vc', 'hint', 'menu', 'vc/doc', 'vc/docgroup'], function(introClass, vcClass, hintClass, menuClass, docClass, docGroup) {
hebasta5df796f2019-05-21 15:27:12 +02009
hebasta75cfca52019-02-19 13:15:27 +010010 //needed for localization of labels and contents of the tour
11 const loc = KorAP.Locale;
hebasta5df796f2019-05-21 15:27:12 +020012
hebasta75cfca52019-02-19 13:15:27 +010013 //labels for nextStep, previousStep, done and abort
14 loc.TOUR_lskip = loc.TOUR_lskip || "Abort";
15 loc.TOUR_lprev = loc.TOUR_lprev || "Back";
16 loc.TOUR_lnext = loc.TOUR_lnext || "Next";
17 loc.TOUR_ldone = loc.TOUR_ldone || "Done";
hebastaca61f812019-11-11 22:25:27 +010018 loc.TOUR_ldoneSearch = loc.TOUR_ldoneSearch || "Search";
19
hebasta5df796f2019-05-21 15:27:12 +020020 //localization guided tour gTstartSearch
hebasta1e2d98e2019-10-30 15:58:17 +010021 loc.TOUR_welc = loc.TOUR_welc || "<span class='tgreeting'> Welcome to our guided tour!</span>" +
hebastaee7b8a82020-01-20 12:45:04 +010022 "<p class='pfirstStep'> This tour should give you a quick introduction to KorAP. " +
23 "We lead you step by step through an example. </p>";
24 loc.TOUR_sear1 = loc.TOUR_sear1 || "Input field for the query, for example the search for '" + loc.TOUR_Qexample + "'.";
hebastaf95226b2019-09-19 11:37:00 +020025 loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper";
26 loc.TOUR_annotAss = loc.TOUR_annotAss || "The assistant displays the annotations of the different layers and helps to formulate queries.";
hebasta94e47cb2019-07-24 22:24:27 +020027 loc.TOUR_vccho1 = loc.TOUR_vccho1 || "Choose corpus";
hebasta75cfca52019-02-19 13:15:27 +010028 loc.TOUR_vccho2 = loc.TOUR_vccho2 || "Define your corpus here.";
hebasta94e47cb2019-07-24 22:24:27 +020029 loc.TOUR_vcStat1 = loc.TOUR_vcStat1 || "Click here to display corpus statistic.";
30 loc.TOUR_vcStat2 = loc.TOUR_vcStat2 || "Corpus statistic";
hebasta1e2d98e2019-10-30 15:58:17 +010031 loc.TOUR_qlfield = loc.TOUR_qlfield|| "Selection of the query language: You can use KorAP with different query languages.";
32 loc.TOUR_help = loc.TOUR_help || "Help and information about KorAP.";
hebastaca61f812019-11-11 22:25:27 +010033 loc.TOUR_glimpse = loc.TOUR_glimpse || "Select this to show only the first hits in undefined order.";
hebasta1e2d98e2019-10-30 15:58:17 +010034 loc.TOUR_seargo = loc.TOUR_seargo || "Start the search";
hebasta87f1b1f2019-07-30 13:03:23 +020035
hebasta5df796f2019-05-21 15:27:12 +020036 //localization guided Tour gTshowResults
hebasta87f1b1f2019-07-30 13:03:23 +020037 loc.TOUR_kwic = loc.TOUR_kwic || "KWIC result (keyword in context)";
38 loc.TOUR_snippet = loc.TOUR_snippet || "Click on a match to show a larger snippet.";
hebasta1e2d98e2019-10-30 15:58:17 +010039 loc.TOUR_snippetb = loc.TOUR_snippetb || "Snippet";
40 loc.TOUR_metadatab = loc.TOUR_metadatab || "Display of metadata";
hebasta87f1b1f2019-07-30 13:03:23 +020041 loc.TOUR_metadata = loc.TOUR_metadata || "Metadata";
hebasta1e2d98e2019-10-30 15:58:17 +010042 loc.TOUR_tokenb = loc.TOUR_tokenb || "Display of token annotations";
hebasta87f1b1f2019-07-30 13:03:23 +020043 loc.TOUR_token = loc.TOUR_token || "KorAP supports multiple annotations.";
hebasta1e2d98e2019-10-30 15:58:17 +010044 loc.TOUR_treeb = loc.TOUR_treeb || "Display further annotations"
hebasta87f1b1f2019-07-30 13:03:23 +020045 loc.TOUR_tree = loc.TOUR_tree || "Further annotations can be displayed as tree and arch views."
46 loc.TOUR_tourdone = loc.TOUR_tourdone || "Have fun with KorAP!";
hebasta75cfca52019-02-19 13:15:27 +010047
48 //localization of button labels
hebastaee7b8a82020-01-20 12:45:04 +010049 let labelOpts= {
hebasta5df796f2019-05-21 15:27:12 +020050 'skipLabel': loc.TOUR_lskip,
51 'prevLabel': loc.TOUR_lprev,
52 'nextLabel': loc.TOUR_lnext,
53 'doneLabel': loc.TOUR_ldone,
hebastaee7b8a82020-01-20 12:45:04 +010054 'showStepNumbers': false
55 };
56
57 //usability options of tours
58 let usabilityOpts ={
59 'showBullets': false,
60 'overlayOpacity': 0.7,
61 'exitOnOverlayClick': false,
62 'disableInteraction': true,
63 'hideNext': true,
64 'hidePrev': true
hebasta75cfca52019-02-19 13:15:27 +010065 };
hebasta87f1b1f2019-07-30 13:03:23 +020066
67 var doe = document;
hebasta5df796f2019-05-21 15:27:12 +020068
hebasta75cfca52019-02-19 13:15:27 +010069 return{
hebasta5df796f2019-05-21 15:27:12 +020070
hebasta75cfca52019-02-19 13:15:27 +010071 /**
hebasta5df796f2019-05-21 15:27:12 +020072 * Guided Tour gTstartSearch: Explains the search functionality
hebasta75cfca52019-02-19 13:15:27 +010073 */
hebasta5df796f2019-05-21 15:27:12 +020074 gTstartSearch:function(elparam){
hebasta5df796f2019-05-21 15:27:12 +020075 let intro = introClass();
hebastaee7b8a82020-01-20 12:45:04 +010076 intro.setOptions(labelOpts);
hebasta1e2d98e2019-10-30 15:58:17 +010077 intro.setOption('tooltipClass', 'gTstartSearch');
hebastaca61f812019-11-11 22:25:27 +010078 /*
79 * Sets button labels for the last step of the tour
80 * Because Kalamar is a multipage webapplication, this tours starts by
81 * completion the gTshowResults Tour. Therefore the label of the done button changed.
82 */
83 intro.setOption('doneLabel', loc.TOUR_ldoneSearch );
hebastaee7b8a82020-01-20 12:45:04 +010084 intro.setOptions(usabilityOpts);
hebastaca61f812019-11-11 22:25:27 +010085
hebasta5df796f2019-05-21 15:27:12 +020086 //for testing purposes
hebasta75cfca52019-02-19 13:15:27 +010087 if(elparam){
88 doe = elparam;
89 }
hebasta5df796f2019-05-21 15:27:12 +020090
hebasta75cfca52019-02-19 13:15:27 +010091 let input = doe.querySelector("#q-field");
92 input.value="";
93
hebasta5df796f2019-05-21 15:27:12 +020094
hebasta75cfca52019-02-19 13:15:27 +010095 //steps of the example tour
96 let Steps =[
97 {
hebasta1e2d98e2019-10-30 15:58:17 +010098 intro: loc.TOUR_welc,
99 },
100 {
hebastaf95226b2019-09-19 11:37:00 +0200101 element: '#q-field',
hebasta75cfca52019-02-19 13:15:27 +0100102 intro: loc.TOUR_sear1,
103 position: 'bottom'
104 },
105 {
hebasta75cfca52019-02-19 13:15:27 +0100106 element: '#hint',
107 intro: loc.TOUR_searAnnot,
108 position: 'bottom'
hebasta5df796f2019-05-21 15:27:12 +0200109 },
110 {
hebastaf95226b2019-09-19 11:37:00 +0200111 element: doe.querySelector("#hint > .menu.hint"),
112 intro: loc.TOUR_annotAss,
113 position: 'bottom',
114 },
115 {
hebasta75cfca52019-02-19 13:15:27 +0100116 element:'#vc-choose',
117 intro: loc.TOUR_vccho1,
118 position: "bottom",
hebasta5df796f2019-05-21 15:27:12 +0200119 },
120 {
121 element:'#vc-view',
122 intro: loc.TOUR_vccho2,
123 position: "bottom",
124 },
125 {
hebastad090a512019-07-10 16:36:01 +0200126 element: doe.querySelector('.statistic'),
hebasta94e47cb2019-07-24 22:24:27 +0200127 intro: loc.TOUR_vcStat1,
hebastad090a512019-07-10 16:36:01 +0200128 position: "left",
129 },
130 {
hebasta94e47cb2019-07-24 22:24:27 +0200131 element: doe.querySelector('.stattable'),
132 intro: loc.TOUR_vcStat2,
133 position: "bottom",
134 },
135 {
hebasta5df796f2019-05-21 15:27:12 +0200136 element: doe.querySelector('#ql-field').parentNode,
137 intro: loc.TOUR_qlfield,
138 position: "bottom",
139 },
140 {
141 element:'#glimpse',
142 intro: loc.TOUR_glimpse,
143 position: "bottom",
144 },
145 {
146 element:'#view-tutorial',
147 intro: loc.TOUR_help,
148 position: "bottom",
149 },
150 {
151 element: '#qsubmit',
152 intro: loc.TOUR_seargo,
153 position: "bottom",
154 },
155 ];
156
hebasta75cfca52019-02-19 13:15:27 +0100157 //pass in the Steps array created earlier
hebasta87f1b1f2019-07-30 13:03:23 +0200158 intro.setOptions({steps: Steps});
159 this.testPrerequ(Steps, intro);
hebastaca61f812019-11-11 22:25:27 +0100160
hebasta5df796f2019-05-21 15:27:12 +0200161 //changes before executing the single steps
162 intro.onbeforechange(function(targetedElement){
163 switch(targetedElement.id){
hebastaf95226b2019-09-19 11:37:00 +0200164 case "q-field":
hebastad090a512019-07-10 16:36:01 +0200165 /*
166 * TODO:
167 * #268 is not merged at the time beeing:
168 * introJs.currentStep() merge requested https://github.com/usablica/intro.js/pull/268/files
169 */
hebastaf95226b2019-09-19 11:37:00 +0200170 targetedElement.value = loc.TOUR_Qexample;
hebasta5df796f2019-05-21 15:27:12 +0200171 break;
hebasta5df796f2019-05-21 15:27:12 +0200172 case "vc-view":
173 vchoo = doe.querySelector("#vc-choose");
174 vcv = doe.querySelector("#vc-view");
175 KorAP._delete.apply(KorAP.vc.root());
hebasta94e47cb2019-07-24 22:24:27 +0200176
177 KorAP.vc.fromJson(loc.TOUR_vcQuery);
hebasta5df796f2019-05-21 15:27:12 +0200178 if(!(vcv.querySelector(".active"))){
179 vchoo.click();
hebastad090a512019-07-10 16:36:01 +0200180 /*
181 * Intro.js caches elements at the beginning, so element and position has to be set again.
182 */
hebastaee7b8a82020-01-20 12:45:04 +0100183 intro._introItems[6].element = doe.querySelector('.statistic');
184 intro._introItems[6].position = "left";
hebasta5df796f2019-05-21 15:27:12 +0200185 }
186 break;
hebasta75cfca52019-02-19 13:15:27 +0100187
hebasta5df796f2019-05-21 15:27:12 +0200188 }
hebasta94e47cb2019-07-24 22:24:27 +0200189
hebastaee7b8a82020-01-20 12:45:04 +0100190 if(this._currentStep == 7){
hebasta94e47cb2019-07-24 22:24:27 +0200191 let statbut = doe.querySelector('.statistic');
192 statbut.click();
hebastaee7b8a82020-01-20 12:45:04 +0100193 intro._introItems[7].element = doe.querySelector(".stattable");
194 intro._introItems[7].position = "bottom";
hebasta94e47cb2019-07-24 22:24:27 +0200195 }
hebasta75cfca52019-02-19 13:15:27 +0100196 });
hebasta5df796f2019-05-21 15:27:12 +0200197
hebastaf95226b2019-09-19 11:37:00 +0200198 intro.onbeforeexit(function(){
199 if(KorAP.Hint.active() && KorAP.Hint.active().dontHide){
200 KorAP.Hint.unshow();
201 }
202 });
203
204 intro.onchange(function(targetElement) {
205 var that = this;
206 switch(this._currentStep){
207 //hides Hint if back button is pressed
hebastaee7b8a82020-01-20 12:45:04 +0100208 case 2:
hebastaf95226b2019-09-19 11:37:00 +0200209 if(KorAP.Hint.active()){
210 KorAP.Hint.unshow();
211 }
212 break;
hebastaee7b8a82020-01-20 12:45:04 +0100213 case 3:
hebastaf95226b2019-09-19 11:37:00 +0200214 KorAP.Hint.show(false);
215 KorAP.Hint.active().dontHide = true;
hebastaee7b8a82020-01-20 12:45:04 +0100216 intro._introItems[3].element = doe.querySelector(".menu.roll.hint");
217 intro._introItems[3].position = doe.querySelector("bottom");
hebastaf95226b2019-09-19 11:37:00 +0200218 break;
hebastaee7b8a82020-01-20 12:45:04 +0100219 case 4:
hebastaf95226b2019-09-19 11:37:00 +0200220 KorAP.Hint.unshow();
221 break;
222 }
223 });
224
hebasta5df796f2019-05-21 15:27:12 +0200225 // Execute at the end of the tour (By clicking at the done-Button)
226 intro.oncomplete(function(){
227 KorAP.session.set("tour", true);
hebasta94e47cb2019-07-24 22:24:27 +0200228 doe.getElementById("qsubmit").click();
hebasta5df796f2019-05-21 15:27:12 +0200229 });
230
231 return intro;
hebasta75cfca52019-02-19 13:15:27 +0100232 },
hebasta5df796f2019-05-21 15:27:12 +0200233
234
235 /* Guided Tour to explain the different views of the results */
hebastaca61f812019-11-11 22:25:27 +0100236 gTshowResults: function(elparam){
237
238 let tourR = introClass();
hebastaee7b8a82020-01-20 12:45:04 +0100239 tourR.setOptions(usabilityOpts);
hebastaca61f812019-11-11 22:25:27 +0100240
hebasta87f1b1f2019-07-30 13:03:23 +0200241 //for testing purposes
hebasta5df796f2019-05-21 15:27:12 +0200242 if(elparam){
243 doe = elparam;
244 }
hebasta5df796f2019-05-21 15:27:12 +0200245 let StepsSR = [
hebasta87f1b1f2019-07-30 13:03:23 +0200246 //Step 1, intro_item 0
247 {
248 element: '#search',
249 intro: loc.TOUR_kwic ,
250 position: "auto",
251 },
252 //Step 2, intro_item 1
253 {
254 element: doe.querySelector("#search > ol > li"),
255 intro: loc.TOUR_snippet,
256 position: "bottom",
257 },
258 //Step 3, intro_item 2
259 {
260 element: doe.querySelector("#search > ol > li"),
261 intro: loc.TOUR_snippetb,
262 position: "bottom",
263 },
264 //Step 4, intro_item 3
265 {
266 element: doe.querySelector(".action > .metatable"),
267 intro: loc.TOUR_metadatab,
268 position: "bottom",
269 },
270 //Step 5, intro_item 4
271 {
272 element: doe.querySelector(".view.metatable"),
273 intro: loc.TOUR_metadata,
274 position: "auto",
275 },
276 //Step 6, intro_item 5
277 {
278 element: doe.querySelector(".action > .info"),
279 intro: loc.TOUR_tokenb,
280 position: "bottom",
281 },
282 //Step 7, intro_item 6
283 {
284 element: doe.querySelector(".view.tokentable"),
285 intro: loc.TOUR_token,
286 position: "auto",
287 },
288 //Step 8, intro_item 7
hebasta5df796f2019-05-21 15:27:12 +0200289 {
hebasta87f1b1f2019-07-30 13:03:23 +0200290 element: doe.querySelector(".tree"),
291 intro: loc.TOUR_treeb,
292 position: "bottom",
293 },
294 //Step 9, intro_item 8
295 {
hebastaf95226b2019-09-19 11:37:00 +0200296 element: doe.querySelector(".view.relations"),
hebasta87f1b1f2019-07-30 13:03:23 +0200297 intro: loc.TOUR_tree,
hebastaf95226b2019-09-19 11:37:00 +0200298 position: "bottom",
hebasta87f1b1f2019-07-30 13:03:23 +0200299 },
300 //Step 10, intro_item 9
301 {
302 intro: loc.TOUR_tourdone,
303 }
hebasta5df796f2019-05-21 15:27:12 +0200304 ]
hebasta5df796f2019-05-21 15:27:12 +0200305
hebasta87f1b1f2019-07-30 13:03:23 +0200306 tourR.setOptions({steps:StepsSR});
hebastaee7b8a82020-01-20 12:45:04 +0100307 tourR.setOptions(labelOpts);
hebastaf95226b2019-09-19 11:37:00 +0200308
309 tourR.onbeforeexit(function(){
310 KorAP.session.set("tour", false);
hebasta87f1b1f2019-07-30 13:03:23 +0200311 });
hebasta87f1b1f2019-07-30 13:03:23 +0200312 //See also: https://introjs.com/docs/intro/options/
313 tourR.setOption('scrollToElement', true);
314 tourR.setOption('scrollTo','tooltip');
315 this.testPrerequ(StepsSR, tourR);
316
317 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
318 tourR.onbeforechange(function(targetedElement){
319
320 if(this._currentStep == 1){
321 KorAP.session.set("tour", false);
322 }
323
324 if(this._currentStep == 2){
325 doe.querySelector("#search > ol > li").click();
326 tourR._introItems[3].element = doe.querySelector('.action > .metatable');
327 tourR._introItems[3].position = "bottom";
328 }
329
330 if(this._currentStep == 4){
331 doe.querySelector(".metatable").click();
332 tourR._introItems[4].element = doe.querySelector('.view.metatable');
333 tourR._introItems[5].element = doe.querySelector('.action > .info');
334 tourR._introItems[5].position = "bottom";
335 }
336
337 if(this._currentStep == 6){
338 doe.querySelector(".info").click();
339 tourR._introItems[6].element = doe.querySelector('.view.tokentable');
340 tourR._introItems[7].element = doe.querySelector('.tree');
341 tourR._introItems[7].position = "bottom";
342 }
343
344 if(this._currentStep == 8){
345 doe.querySelector(".tree").click();
hebasta7fa6f082019-11-17 19:00:52 +0100346 let collect = document.querySelectorAll(".button-group-list")[0].querySelectorAll('li');
347 for(let i = 0; i < collect.length; i++){
348 if (collect[i].innerText == loc.TOUR_Relations) {
349 collect[i].click();
350 break;
351 }
352 }
hebastaf95226b2019-09-19 11:37:00 +0200353 tourR._introItems[8].element = doe.querySelector(".view.relations");
hebasta87f1b1f2019-07-30 13:03:23 +0200354 }
355 });
hebastaf95226b2019-09-19 11:37:00 +0200356
hebasta5df796f2019-05-21 15:27:12 +0200357 return tourR;
358 },
hebasta87f1b1f2019-07-30 13:03:23 +0200359 /*
360 * The total number of steps and the text of the tooltips are needed for jasmine testing.
361 */
362 testPrerequ: function(steps, tour){
363 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
364 let StepsT = steps;
365 let gtour = tour;
366 gtour.stepCount = StepsT.length;
367
368 //Array of intro content needed for efficient testing
369 gtour.testIntros = [];
370
371 for(let i = 0; i< StepsT.length; i++){
372 gtour.testIntros.push(StepsT[i].intro);
373 }
374 },
hebasta5df796f2019-05-21 15:27:12 +0200375
hebasta75cfca52019-02-19 13:15:27 +0100376 }
377});