blob: 49f8e4b9df452bd668eb90915a98d1f4361f6715 [file] [log] [blame]
hebasta75cfca52019-02-19 13:15:27 +01001/**
2 * Guided Tour to explain the UI
3 *
4 * @author Helge Stallkamp
5 */
Akrone51eaa32020-11-10 09:35:53 +01006"use strict";
hebasta75cfca52019-02-19 13:15:27 +01007
Akrone51eaa32020-11-10 09:35:53 +01008define(['lib/intro', 'vc', 'hint', 'menu', 'vc/doc', 'vc/docgroup'],
9 function(introClass, vcClass, hintClass, menuClass, docClass, docGroup) {
hebasta5df796f2019-05-21 15:27:12 +020010
hebasta75cfca52019-02-19 13:15:27 +010011 //needed for localization of labels and contents of the tour
12 const loc = KorAP.Locale;
hebasta5df796f2019-05-21 15:27:12 +020013
hebastaa84c7a92021-10-26 21:12:40 +020014 //labels for nextStep, previousStep and done
hebasta75cfca52019-02-19 13:15:27 +010015 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
hebastaa84c7a92021-10-26 21:12:40 +020021 loc.TOUR_welcti = loc.TOUR_welcti || "<span class='tgreeting'> Welcome to our guided tour! </span>";
22 loc.TOUR_welc = loc.TOUR_welc || "This tour should give you a quick introduction to KorAP. " +
hebasta84a7e0e2021-11-03 19:11:33 +010023 "We lead you step by step through an example.";
hebastaee7b8a82020-01-20 12:45:04 +010024 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.";
hebasta84a7e0e2021-11-03 19:11:33 +010027 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";
hebasta84a7e0e2021-11-03 19:11:33 +010031 loc.TOUR_qlfield = loc.TOUR_qlfield|| "Selection of the query language: You can use KorAP with different query languages.";
hebasta1e2d98e2019-10-30 15:58:17 +010032 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 'prevLabel': loc.TOUR_lprev,
51 'nextLabel': loc.TOUR_lnext,
52 'doneLabel': loc.TOUR_ldone,
hebastaee7b8a82020-01-20 12:45:04 +010053 'showStepNumbers': false
54 };
55
56 //usability options of tours
57 let usabilityOpts ={
58 'showBullets': false,
hebastaa84c7a92021-10-26 21:12:40 +020059 'overlayOpacity': 0.5,
hebastaee7b8a82020-01-20 12:45:04 +010060 'exitOnOverlayClick': false,
hebastaa84c7a92021-10-26 21:12:40 +020061 'disableInteraction': true,
62 'tooltipClass': 'customTooltip',
hebastaee7b8a82020-01-20 12:45:04 +010063 'hidePrev': true
hebasta75cfca52019-02-19 13:15:27 +010064 };
hebasta87f1b1f2019-07-30 13:03:23 +020065
66 var doe = document;
hebasta5df796f2019-05-21 15:27:12 +020067
hebasta75cfca52019-02-19 13:15:27 +010068 return{
hebasta5df796f2019-05-21 15:27:12 +020069
hebasta75cfca52019-02-19 13:15:27 +010070 /**
hebasta5df796f2019-05-21 15:27:12 +020071 * Guided Tour gTstartSearch: Explains the search functionality
hebasta75cfca52019-02-19 13:15:27 +010072 */
hebasta5df796f2019-05-21 15:27:12 +020073 gTstartSearch:function(elparam){
hebasta5df796f2019-05-21 15:27:12 +020074 let intro = introClass();
hebastaee7b8a82020-01-20 12:45:04 +010075 intro.setOptions(labelOpts);
hebastaca61f812019-11-11 22:25:27 +010076 /*
77 * Sets button labels for the last step of the tour
78 * Because Kalamar is a multipage webapplication, this tours starts by
79 * completion the gTshowResults Tour. Therefore the label of the done button changed.
80 */
81 intro.setOption('doneLabel', loc.TOUR_ldoneSearch );
hebastaee7b8a82020-01-20 12:45:04 +010082 intro.setOptions(usabilityOpts);
hebastaca61f812019-11-11 22:25:27 +010083
hebasta5df796f2019-05-21 15:27:12 +020084 //for testing purposes
hebasta75cfca52019-02-19 13:15:27 +010085 if(elparam){
86 doe = elparam;
87 }
hebasta5df796f2019-05-21 15:27:12 +020088
hebasta75cfca52019-02-19 13:15:27 +010089 let input = doe.querySelector("#q-field");
90 input.value="";
91
hebasta5df796f2019-05-21 15:27:12 +020092
hebasta75cfca52019-02-19 13:15:27 +010093 //steps of the example tour
94 let Steps =[
hebasta2f7e5402021-11-02 20:09:38 +010095 {
96 element: '#link-guided-tour',
hebastaa84c7a92021-10-26 21:12:40 +020097 title: loc.TOUR_welcti,
hebasta1e2d98e2019-10-30 15:58:17 +010098 intro: loc.TOUR_welc,
hebasta2f7e5402021-11-02 20:09:38 +010099 position: 'right',
hebasta1e2d98e2019-10-30 15:58:17 +0100100 },
101 {
hebasta84a7e0e2021-11-03 19:11:33 +0100102 title: loc.TOUR_sear1ti,
hebastaf95226b2019-09-19 11:37:00 +0200103 element: '#q-field',
hebasta75cfca52019-02-19 13:15:27 +0100104 intro: loc.TOUR_sear1,
105 position: 'bottom'
106 },
107 {
hebasta84a7e0e2021-11-03 19:11:33 +0100108 title: loc.TOUR_searAnnotti,
hebasta75cfca52019-02-19 13:15:27 +0100109 element: '#hint',
110 intro: loc.TOUR_searAnnot,
111 position: 'bottom'
hebasta5df796f2019-05-21 15:27:12 +0200112 },
113 {
hebasta84a7e0e2021-11-03 19:11:33 +0100114 title: loc.TOUR_annotAssti,
hebastaf95226b2019-09-19 11:37:00 +0200115 element: doe.querySelector("#hint > .menu.hint"),
116 intro: loc.TOUR_annotAss,
117 position: 'bottom',
hebasta84a7e0e2021-11-03 19:11:33 +0100118 },
hebastaf95226b2019-09-19 11:37:00 +0200119 {
hebasta84a7e0e2021-11-03 19:11:33 +0100120 title:loc.TOUR_vccho1ti,
hebasta75cfca52019-02-19 13:15:27 +0100121 element:'#vc-choose',
122 intro: loc.TOUR_vccho1,
123 position: "bottom",
hebasta5df796f2019-05-21 15:27:12 +0200124 },
125 {
hebasta84a7e0e2021-11-03 19:11:33 +0100126 title: loc.TOUR_vccho2ti,
hebasta5df796f2019-05-21 15:27:12 +0200127 element:'#vc-view',
128 intro: loc.TOUR_vccho2,
129 position: "bottom",
130 },
131 {
hebasta84a7e0e2021-11-03 19:11:33 +0100132 title: loc.TOUR_vcStat1ti,
hebastad090a512019-07-10 16:36:01 +0200133 element: doe.querySelector('.statistic'),
hebasta94e47cb2019-07-24 22:24:27 +0200134 intro: loc.TOUR_vcStat1,
hebastad090a512019-07-10 16:36:01 +0200135 position: "left",
136 },
137 {
hebasta84a7e0e2021-11-03 19:11:33 +0100138 title: loc.TOUR_vcStat2ti,
hebasta94e47cb2019-07-24 22:24:27 +0200139 element: doe.querySelector('.stattable'),
140 intro: loc.TOUR_vcStat2,
141 position: "bottom",
142 },
143 {
hebasta84a7e0e2021-11-03 19:11:33 +0100144 title: loc.TOUR_qlfieldti,
hebasta5df796f2019-05-21 15:27:12 +0200145 element: doe.querySelector('#ql-field').parentNode,
146 intro: loc.TOUR_qlfield,
147 position: "bottom",
148 },
149 {
hebasta84a7e0e2021-11-03 19:11:33 +0100150 title: loc.TOUR_glimpseti,
hebastabd53f822021-10-26 21:50:06 +0200151 element: doe.querySelector('#glimpse').parentNode,
hebasta5df796f2019-05-21 15:27:12 +0200152 intro: loc.TOUR_glimpse,
153 position: "bottom",
154 },
155 {
hebasta84a7e0e2021-11-03 19:11:33 +0100156 title: loc.TOUR_helpti,
hebasta5df796f2019-05-21 15:27:12 +0200157 element:'#view-tutorial',
158 intro: loc.TOUR_help,
159 position: "bottom",
160 },
161 {
hebasta84a7e0e2021-11-03 19:11:33 +0100162 title: loc.TOUR_seargoti,
hebasta5df796f2019-05-21 15:27:12 +0200163 element: '#qsubmit',
164 intro: loc.TOUR_seargo,
165 position: "bottom",
166 },
167 ];
168
hebasta75cfca52019-02-19 13:15:27 +0100169 //pass in the Steps array created earlier
hebasta87f1b1f2019-07-30 13:03:23 +0200170 intro.setOptions({steps: Steps});
171 this.testPrerequ(Steps, intro);
hebastaca61f812019-11-11 22:25:27 +0100172
hebasta5df796f2019-05-21 15:27:12 +0200173 //changes before executing the single steps
174 intro.onbeforechange(function(targetedElement){
175 switch(targetedElement.id){
hebastaf95226b2019-09-19 11:37:00 +0200176 case "q-field":
hebastad090a512019-07-10 16:36:01 +0200177 /*
178 * TODO:
179 * #268 is not merged at the time beeing:
180 * introJs.currentStep() merge requested https://github.com/usablica/intro.js/pull/268/files
181 */
hebastaf95226b2019-09-19 11:37:00 +0200182 targetedElement.value = loc.TOUR_Qexample;
hebasta5df796f2019-05-21 15:27:12 +0200183 break;
hebasta5df796f2019-05-21 15:27:12 +0200184 case "vc-view":
Akron0b37f3e2021-02-09 10:32:03 +0100185 let vchoo = doe.querySelector("#vc-choose");
186 let vcv = doe.querySelector("#vc-view");
hebasta5df796f2019-05-21 15:27:12 +0200187 KorAP._delete.apply(KorAP.vc.root());
hebasta94e47cb2019-07-24 22:24:27 +0200188
189 KorAP.vc.fromJson(loc.TOUR_vcQuery);
hebasta5df796f2019-05-21 15:27:12 +0200190 if(!(vcv.querySelector(".active"))){
191 vchoo.click();
hebastad090a512019-07-10 16:36:01 +0200192 /*
193 * Intro.js caches elements at the beginning, so element and position has to be set again.
194 */
hebastaee7b8a82020-01-20 12:45:04 +0100195 intro._introItems[6].element = doe.querySelector('.statistic');
196 intro._introItems[6].position = "left";
hebasta5df796f2019-05-21 15:27:12 +0200197 }
198 break;
hebasta75cfca52019-02-19 13:15:27 +0100199
hebasta5df796f2019-05-21 15:27:12 +0200200 }
hebasta94e47cb2019-07-24 22:24:27 +0200201
hebastaee7b8a82020-01-20 12:45:04 +0100202 if(this._currentStep == 7){
hebasta94e47cb2019-07-24 22:24:27 +0200203 let statbut = doe.querySelector('.statistic');
204 statbut.click();
hebastaee7b8a82020-01-20 12:45:04 +0100205 intro._introItems[7].element = doe.querySelector(".stattable");
206 intro._introItems[7].position = "bottom";
hebasta94e47cb2019-07-24 22:24:27 +0200207 }
hebasta75cfca52019-02-19 13:15:27 +0100208 });
hebasta5df796f2019-05-21 15:27:12 +0200209
hebastaf95226b2019-09-19 11:37:00 +0200210 intro.onbeforeexit(function(){
211 if(KorAP.Hint.active() && KorAP.Hint.active().dontHide){
212 KorAP.Hint.unshow();
213 }
214 });
215
216 intro.onchange(function(targetElement) {
217 var that = this;
218 switch(this._currentStep){
219 //hides Hint if back button is pressed
hebastaee7b8a82020-01-20 12:45:04 +0100220 case 2:
hebastaf95226b2019-09-19 11:37:00 +0200221 if(KorAP.Hint.active()){
222 KorAP.Hint.unshow();
223 }
224 break;
hebastaee7b8a82020-01-20 12:45:04 +0100225 case 3:
hebastaf95226b2019-09-19 11:37:00 +0200226 KorAP.Hint.show(false);
227 KorAP.Hint.active().dontHide = true;
hebastaee7b8a82020-01-20 12:45:04 +0100228 intro._introItems[3].element = doe.querySelector(".menu.roll.hint");
229 intro._introItems[3].position = doe.querySelector("bottom");
hebastaf95226b2019-09-19 11:37:00 +0200230 break;
hebastaee7b8a82020-01-20 12:45:04 +0100231 case 4:
hebastaf95226b2019-09-19 11:37:00 +0200232 KorAP.Hint.unshow();
233 break;
234 }
235 });
236
hebasta5df796f2019-05-21 15:27:12 +0200237 // Execute at the end of the tour (By clicking at the done-Button)
238 intro.oncomplete(function(){
239 KorAP.session.set("tour", true);
hebasta94e47cb2019-07-24 22:24:27 +0200240 doe.getElementById("qsubmit").click();
hebasta5df796f2019-05-21 15:27:12 +0200241 });
242
243 return intro;
hebasta75cfca52019-02-19 13:15:27 +0100244 },
hebasta5df796f2019-05-21 15:27:12 +0200245
246
247 /* Guided Tour to explain the different views of the results */
hebastaca61f812019-11-11 22:25:27 +0100248 gTshowResults: function(elparam){
249
250 let tourR = introClass();
hebastaee7b8a82020-01-20 12:45:04 +0100251 tourR.setOptions(usabilityOpts);
hebastaca61f812019-11-11 22:25:27 +0100252
hebasta87f1b1f2019-07-30 13:03:23 +0200253 //for testing purposes
hebasta5df796f2019-05-21 15:27:12 +0200254 if(elparam){
255 doe = elparam;
256 }
hebasta5df796f2019-05-21 15:27:12 +0200257 let StepsSR = [
hebasta87f1b1f2019-07-30 13:03:23 +0200258 //Step 1, intro_item 0
259 {
260 element: '#search',
261 intro: loc.TOUR_kwic ,
262 position: "auto",
263 },
264 //Step 2, intro_item 1
265 {
266 element: doe.querySelector("#search > ol > li"),
267 intro: loc.TOUR_snippet,
268 position: "bottom",
269 },
270 //Step 3, intro_item 2
271 {
272 element: doe.querySelector("#search > ol > li"),
273 intro: loc.TOUR_snippetb,
274 position: "bottom",
275 },
276 //Step 4, intro_item 3
277 {
278 element: doe.querySelector(".action > .metatable"),
279 intro: loc.TOUR_metadatab,
280 position: "bottom",
281 },
282 //Step 5, intro_item 4
283 {
284 element: doe.querySelector(".view.metatable"),
285 intro: loc.TOUR_metadata,
286 position: "auto",
287 },
288 //Step 6, intro_item 5
289 {
290 element: doe.querySelector(".action > .info"),
291 intro: loc.TOUR_tokenb,
292 position: "bottom",
293 },
294 //Step 7, intro_item 6
295 {
296 element: doe.querySelector(".view.tokentable"),
297 intro: loc.TOUR_token,
298 position: "auto",
299 },
300 //Step 8, intro_item 7
hebasta5df796f2019-05-21 15:27:12 +0200301 {
hebasta87f1b1f2019-07-30 13:03:23 +0200302 element: doe.querySelector(".tree"),
303 intro: loc.TOUR_treeb,
304 position: "bottom",
305 },
306 //Step 9, intro_item 8
307 {
hebastaf95226b2019-09-19 11:37:00 +0200308 element: doe.querySelector(".view.relations"),
hebasta87f1b1f2019-07-30 13:03:23 +0200309 intro: loc.TOUR_tree,
hebastaf95226b2019-09-19 11:37:00 +0200310 position: "bottom",
hebasta87f1b1f2019-07-30 13:03:23 +0200311 },
312 //Step 10, intro_item 9
313 {
314 intro: loc.TOUR_tourdone,
315 }
hebasta5df796f2019-05-21 15:27:12 +0200316 ]
hebasta5df796f2019-05-21 15:27:12 +0200317
hebasta87f1b1f2019-07-30 13:03:23 +0200318 tourR.setOptions({steps:StepsSR});
hebastaee7b8a82020-01-20 12:45:04 +0100319 tourR.setOptions(labelOpts);
hebastaf95226b2019-09-19 11:37:00 +0200320
321 tourR.onbeforeexit(function(){
322 KorAP.session.set("tour", false);
hebasta87f1b1f2019-07-30 13:03:23 +0200323 });
hebasta87f1b1f2019-07-30 13:03:23 +0200324 //See also: https://introjs.com/docs/intro/options/
325 tourR.setOption('scrollToElement', true);
326 tourR.setOption('scrollTo','tooltip');
327 this.testPrerequ(StepsSR, tourR);
328
329 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
330 tourR.onbeforechange(function(targetedElement){
331
332 if(this._currentStep == 1){
333 KorAP.session.set("tour", false);
334 }
335
336 if(this._currentStep == 2){
337 doe.querySelector("#search > ol > li").click();
338 tourR._introItems[3].element = doe.querySelector('.action > .metatable');
339 tourR._introItems[3].position = "bottom";
340 }
341
342 if(this._currentStep == 4){
343 doe.querySelector(".metatable").click();
344 tourR._introItems[4].element = doe.querySelector('.view.metatable');
345 tourR._introItems[5].element = doe.querySelector('.action > .info');
346 tourR._introItems[5].position = "bottom";
347 }
348
349 if(this._currentStep == 6){
350 doe.querySelector(".info").click();
351 tourR._introItems[6].element = doe.querySelector('.view.tokentable');
352 tourR._introItems[7].element = doe.querySelector('.tree');
353 tourR._introItems[7].position = "bottom";
354 }
355
356 if(this._currentStep == 8){
357 doe.querySelector(".tree").click();
hebasta7fa6f082019-11-17 19:00:52 +0100358 let collect = document.querySelectorAll(".button-group-list")[0].querySelectorAll('li');
359 for(let i = 0; i < collect.length; i++){
360 if (collect[i].innerText == loc.TOUR_Relations) {
361 collect[i].click();
362 break;
363 }
364 }
hebastaf95226b2019-09-19 11:37:00 +0200365 tourR._introItems[8].element = doe.querySelector(".view.relations");
hebasta87f1b1f2019-07-30 13:03:23 +0200366 }
367 });
hebastaf95226b2019-09-19 11:37:00 +0200368
hebasta5df796f2019-05-21 15:27:12 +0200369 return tourR;
370 },
hebasta87f1b1f2019-07-30 13:03:23 +0200371 /*
372 * The total number of steps and the text of the tooltips are needed for jasmine testing.
373 */
374 testPrerequ: function(steps, tour){
375 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
376 let StepsT = steps;
377 let gtour = tour;
378 gtour.stepCount = StepsT.length;
379
380 //Array of intro content needed for efficient testing
381 gtour.testIntros = [];
382
383 for(let i = 0; i< StepsT.length; i++){
384 gtour.testIntros.push(StepsT[i].intro);
385 }
386 },
hebasta5df796f2019-05-21 15:27:12 +0200387
hebasta75cfca52019-02-19 13:15:27 +0100388 }
389});