blob: 8485ae6bf6913a65ba80b80ff9c553d745b51265 [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";
hebasta5df796f2019-05-21 15:27:12 +020018
19 //localization guided tour gTstartSearch
hebasta1e2d98e2019-10-30 15:58:17 +010020 loc.TOUR_welc = loc.TOUR_welc || "<span class='tgreeting'> Welcome to our guided tour!</span>" +
21 "<p class='pfirstStep'> This tour should give you a quick introduction to KorAP. </p>" +
22 "<p> Please note, that if you already defined a corpus or query, these definitions are deleted during the guided tour. " +
23 "If you don't want that, you can stop the tour now with <code>" +
24 loc.TOUR_lskip + "</code>. </p> </div>";
hebasta75cfca52019-02-19 13:15:27 +010025 loc.TOUR_sear1 = loc.TOUR_sear1 || "Enter your search enquiry here.";
hebastad090a512019-07-10 16:36:01 +020026 loc.TOUR_sear2 = loc.TOUR_sear2 || "For example the search for '" + loc.TOUR_Qexample + "'.";
hebastaf95226b2019-09-19 11:37:00 +020027 loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper";
28 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 +020029 loc.TOUR_vccho1 = loc.TOUR_vccho1 || "Choose corpus";
hebasta75cfca52019-02-19 13:15:27 +010030 loc.TOUR_vccho2 = loc.TOUR_vccho2 || "Define your corpus here.";
hebasta94e47cb2019-07-24 22:24:27 +020031 loc.TOUR_vcStat1 = loc.TOUR_vcStat1 || "Click here to display corpus statistic.";
32 loc.TOUR_vcStat2 = loc.TOUR_vcStat2 || "Corpus statistic";
hebasta1e2d98e2019-10-30 15:58:17 +010033 loc.TOUR_qlfield = loc.TOUR_qlfield|| "Selection of the query language: You can use KorAP with different query languages.";
34 loc.TOUR_help = loc.TOUR_help || "Help and information about KorAP.";
35 loc.TOUR_glimpse = loc.TOUR_glimpse || "Select this to show only the first hits in arbitrary order.";
36 loc.TOUR_seargo = loc.TOUR_seargo || "Start the search";
hebasta87f1b1f2019-07-30 13:03:23 +020037
hebasta5df796f2019-05-21 15:27:12 +020038 //localization guided Tour gTshowResults
hebasta87f1b1f2019-07-30 13:03:23 +020039 loc.TOUR_kwic = loc.TOUR_kwic || "KWIC result (keyword in context)";
40 loc.TOUR_snippet = loc.TOUR_snippet || "Click on a match to show a larger snippet.";
hebasta1e2d98e2019-10-30 15:58:17 +010041 loc.TOUR_snippetb = loc.TOUR_snippetb || "Snippet";
42 loc.TOUR_metadatab = loc.TOUR_metadatab || "Display of metadata";
hebasta87f1b1f2019-07-30 13:03:23 +020043 loc.TOUR_metadata = loc.TOUR_metadata || "Metadata";
hebasta1e2d98e2019-10-30 15:58:17 +010044 loc.TOUR_tokenb = loc.TOUR_tokenb || "Display of token annotations";
hebasta87f1b1f2019-07-30 13:03:23 +020045 loc.TOUR_token = loc.TOUR_token || "KorAP supports multiple annotations.";
hebasta1e2d98e2019-10-30 15:58:17 +010046 loc.TOUR_treeb = loc.TOUR_treeb || "Display further annotations"
hebasta87f1b1f2019-07-30 13:03:23 +020047 loc.TOUR_tree = loc.TOUR_tree || "Further annotations can be displayed as tree and arch views."
48 loc.TOUR_tourdone = loc.TOUR_tourdone || "Have fun with KorAP!";
hebasta75cfca52019-02-19 13:15:27 +010049
50 //localization of button labels
hebasta5df796f2019-05-21 15:27:12 +020051 let labelOptions = {
52 'skipLabel': loc.TOUR_lskip,
53 'prevLabel': loc.TOUR_lprev,
54 'nextLabel': loc.TOUR_lnext,
55 'doneLabel': loc.TOUR_ldone,
56 'showStepNumbers': false,
hebasta75cfca52019-02-19 13:15:27 +010057 };
hebasta87f1b1f2019-07-30 13:03:23 +020058
59 var doe = document;
hebasta5df796f2019-05-21 15:27:12 +020060
hebasta75cfca52019-02-19 13:15:27 +010061 return{
hebasta5df796f2019-05-21 15:27:12 +020062
hebasta75cfca52019-02-19 13:15:27 +010063 /**
hebasta5df796f2019-05-21 15:27:12 +020064 * Guided Tour gTstartSearch: Explains the search functionality
hebasta75cfca52019-02-19 13:15:27 +010065 */
hebasta5df796f2019-05-21 15:27:12 +020066 gTstartSearch:function(elparam){
hebasta5df796f2019-05-21 15:27:12 +020067 let intro = introClass();
68 intro.setOptions(labelOptions);
69 intro.setOption('doneLabel', loc.TOUR_seargo);
hebasta1e2d98e2019-10-30 15:58:17 +010070 intro.setOption('tooltipClass', 'gTstartSearch');
hebasta5df796f2019-05-21 15:27:12 +020071
72 //for testing purposes
hebasta75cfca52019-02-19 13:15:27 +010073 if(elparam){
74 doe = elparam;
75 }
hebasta5df796f2019-05-21 15:27:12 +020076
hebasta75cfca52019-02-19 13:15:27 +010077 let input = doe.querySelector("#q-field");
78 input.value="";
79
hebasta5df796f2019-05-21 15:27:12 +020080
hebasta75cfca52019-02-19 13:15:27 +010081 //steps of the example tour
82 let Steps =[
83 {
hebasta1e2d98e2019-10-30 15:58:17 +010084 intro: loc.TOUR_welc,
85 },
86 {
hebastaf95226b2019-09-19 11:37:00 +020087 element: '#q-field',
hebasta75cfca52019-02-19 13:15:27 +010088 intro: loc.TOUR_sear1,
89 position: 'bottom'
90 },
91 {
hebastaf95226b2019-09-19 11:37:00 +020092 element: '#q-field',
hebasta75cfca52019-02-19 13:15:27 +010093 intro: loc.TOUR_sear2,
94 position: 'bottom'
95 },
96 {
97 element: '#hint',
98 intro: loc.TOUR_searAnnot,
99 position: 'bottom'
hebasta5df796f2019-05-21 15:27:12 +0200100 },
101 {
hebastaf95226b2019-09-19 11:37:00 +0200102 element: doe.querySelector("#hint > .menu.hint"),
103 intro: loc.TOUR_annotAss,
104 position: 'bottom',
105 },
106 {
hebasta75cfca52019-02-19 13:15:27 +0100107 element:'#vc-choose',
108 intro: loc.TOUR_vccho1,
109 position: "bottom",
hebasta5df796f2019-05-21 15:27:12 +0200110 },
111 {
112 element:'#vc-view',
113 intro: loc.TOUR_vccho2,
114 position: "bottom",
115 },
116 {
hebastad090a512019-07-10 16:36:01 +0200117 element: doe.querySelector('.statistic'),
hebasta94e47cb2019-07-24 22:24:27 +0200118 intro: loc.TOUR_vcStat1,
hebastad090a512019-07-10 16:36:01 +0200119 position: "left",
120 },
121 {
hebasta94e47cb2019-07-24 22:24:27 +0200122 element: doe.querySelector('.stattable'),
123 intro: loc.TOUR_vcStat2,
124 position: "bottom",
125 },
126 {
hebasta5df796f2019-05-21 15:27:12 +0200127 element: doe.querySelector('#ql-field').parentNode,
128 intro: loc.TOUR_qlfield,
129 position: "bottom",
130 },
131 {
132 element:'#glimpse',
133 intro: loc.TOUR_glimpse,
134 position: "bottom",
135 },
136 {
137 element:'#view-tutorial',
138 intro: loc.TOUR_help,
139 position: "bottom",
140 },
141 {
142 element: '#qsubmit',
143 intro: loc.TOUR_seargo,
144 position: "bottom",
145 },
146 ];
147
hebasta75cfca52019-02-19 13:15:27 +0100148 //pass in the Steps array created earlier
hebasta87f1b1f2019-07-30 13:03:23 +0200149 intro.setOptions({steps: Steps});
150 this.testPrerequ(Steps, intro);
151
hebasta5df796f2019-05-21 15:27:12 +0200152 //changes before executing the single steps
153 intro.onbeforechange(function(targetedElement){
154 switch(targetedElement.id){
hebastaf95226b2019-09-19 11:37:00 +0200155 case "q-field":
hebastad090a512019-07-10 16:36:01 +0200156 /*
157 * TODO:
158 * #268 is not merged at the time beeing:
159 * introJs.currentStep() merge requested https://github.com/usablica/intro.js/pull/268/files
160 */
hebasta1e2d98e2019-10-30 15:58:17 +0100161 if(this._currentStep == 2){
hebastaf95226b2019-09-19 11:37:00 +0200162 targetedElement.value = loc.TOUR_Qexample;
hebasta5df796f2019-05-21 15:27:12 +0200163 }
164 break;
hebasta5df796f2019-05-21 15:27:12 +0200165 case "vc-view":
166 vchoo = doe.querySelector("#vc-choose");
167 vcv = doe.querySelector("#vc-view");
168 KorAP._delete.apply(KorAP.vc.root());
hebasta94e47cb2019-07-24 22:24:27 +0200169
170 KorAP.vc.fromJson(loc.TOUR_vcQuery);
hebasta5df796f2019-05-21 15:27:12 +0200171 if(!(vcv.querySelector(".active"))){
172 vchoo.click();
hebastad090a512019-07-10 16:36:01 +0200173 /*
174 * Intro.js caches elements at the beginning, so element and position has to be set again.
175 */
hebasta1e2d98e2019-10-30 15:58:17 +0100176 intro._introItems[7].element = doe.querySelector('.statistic');
177 intro._introItems[7].position = "left";
hebasta5df796f2019-05-21 15:27:12 +0200178 }
179 break;
hebasta75cfca52019-02-19 13:15:27 +0100180
hebasta5df796f2019-05-21 15:27:12 +0200181 /*
182 * Sets button labels for the last step of the tour
183 * Because Kalamar is a multipage webapplication, this tours starts by
184 * completion the gTshowResults Tour. Therefore, the skip-button is removed
185 * and the label of the done button changed.
186 */
hebasta5df796f2019-05-21 15:27:12 +0200187 case "qsubmit":
188 intro.setOption('hideNext', true);
189 break;
190 }
hebasta94e47cb2019-07-24 22:24:27 +0200191
hebasta1e2d98e2019-10-30 15:58:17 +0100192 if(this._currentStep == 8){
hebasta94e47cb2019-07-24 22:24:27 +0200193 let statbut = doe.querySelector('.statistic');
194 statbut.click();
hebasta1e2d98e2019-10-30 15:58:17 +0100195 intro._introItems[8].element = doe.querySelector(".stattable");
196 intro._introItems[8].position = "bottom";
hebasta94e47cb2019-07-24 22:24:27 +0200197 }
hebasta75cfca52019-02-19 13:15:27 +0100198 });
hebasta5df796f2019-05-21 15:27:12 +0200199
hebastaf95226b2019-09-19 11:37:00 +0200200 intro.onbeforeexit(function(){
201 if(KorAP.Hint.active() && KorAP.Hint.active().dontHide){
202 KorAP.Hint.unshow();
203 }
204 });
205
206 intro.onchange(function(targetElement) {
207 var that = this;
208 switch(this._currentStep){
209 //hides Hint if back button is pressed
hebasta1e2d98e2019-10-30 15:58:17 +0100210 case 3:
hebastaf95226b2019-09-19 11:37:00 +0200211 if(KorAP.Hint.active()){
212 KorAP.Hint.unshow();
213 }
214 break;
hebasta1e2d98e2019-10-30 15:58:17 +0100215 case 4:
hebastaf95226b2019-09-19 11:37:00 +0200216 KorAP.Hint.show(false);
217 KorAP.Hint.active().dontHide = true;
hebasta1e2d98e2019-10-30 15:58:17 +0100218 intro._introItems[4].element = doe.querySelector(".menu.roll.hint");
219 intro._introItems[4].position = doe.querySelector("bottom");
hebastaf95226b2019-09-19 11:37:00 +0200220 break;
hebasta1e2d98e2019-10-30 15:58:17 +0100221 case 5:
hebastaf95226b2019-09-19 11:37:00 +0200222 KorAP.Hint.unshow();
223 break;
224 }
225 });
226
hebasta5df796f2019-05-21 15:27:12 +0200227 // Execute at the end of the tour (By clicking at the done-Button)
228 intro.oncomplete(function(){
229 KorAP.session.set("tour", true);
hebasta94e47cb2019-07-24 22:24:27 +0200230 doe.getElementById("qsubmit").click();
hebasta5df796f2019-05-21 15:27:12 +0200231 });
232
233 return intro;
hebasta75cfca52019-02-19 13:15:27 +0100234 },
hebasta5df796f2019-05-21 15:27:12 +0200235
236
237 /* Guided Tour to explain the different views of the results */
hebasta87f1b1f2019-07-30 13:03:23 +0200238 gTshowResults: function(elparam){
239 //for testing purposes
hebasta5df796f2019-05-21 15:27:12 +0200240 if(elparam){
241 doe = elparam;
242 }
243 let tourR = introClass();
244 let StepsSR = [
hebasta87f1b1f2019-07-30 13:03:23 +0200245 //Step 1, intro_item 0
246 {
247 element: '#search',
248 intro: loc.TOUR_kwic ,
249 position: "auto",
250 },
251 //Step 2, intro_item 1
252 {
253 element: doe.querySelector("#search > ol > li"),
254 intro: loc.TOUR_snippet,
255 position: "bottom",
256 },
257 //Step 3, intro_item 2
258 {
259 element: doe.querySelector("#search > ol > li"),
260 intro: loc.TOUR_snippetb,
261 position: "bottom",
262 },
263 //Step 4, intro_item 3
264 {
265 element: doe.querySelector(".action > .metatable"),
266 intro: loc.TOUR_metadatab,
267 position: "bottom",
268 },
269 //Step 5, intro_item 4
270 {
271 element: doe.querySelector(".view.metatable"),
272 intro: loc.TOUR_metadata,
273 position: "auto",
274 },
275 //Step 6, intro_item 5
276 {
277 element: doe.querySelector(".action > .info"),
278 intro: loc.TOUR_tokenb,
279 position: "bottom",
280 },
281 //Step 7, intro_item 6
282 {
283 element: doe.querySelector(".view.tokentable"),
284 intro: loc.TOUR_token,
285 position: "auto",
286 },
287 //Step 8, intro_item 7
hebasta5df796f2019-05-21 15:27:12 +0200288 {
hebasta87f1b1f2019-07-30 13:03:23 +0200289 element: doe.querySelector(".tree"),
290 intro: loc.TOUR_treeb,
291 position: "bottom",
292 },
293 //Step 9, intro_item 8
294 {
hebastaf95226b2019-09-19 11:37:00 +0200295 element: doe.querySelector(".view.relations"),
hebasta87f1b1f2019-07-30 13:03:23 +0200296 intro: loc.TOUR_tree,
hebastaf95226b2019-09-19 11:37:00 +0200297 position: "bottom",
hebasta87f1b1f2019-07-30 13:03:23 +0200298 },
299 //Step 10, intro_item 9
300 {
301 intro: loc.TOUR_tourdone,
302 }
hebasta5df796f2019-05-21 15:27:12 +0200303 ]
hebasta5df796f2019-05-21 15:27:12 +0200304
hebasta87f1b1f2019-07-30 13:03:23 +0200305 tourR.setOptions({steps:StepsSR});
306 tourR.setOptions(labelOptions);
hebastaf95226b2019-09-19 11:37:00 +0200307
308 tourR.onbeforeexit(function(){
309 KorAP.session.set("tour", false);
hebasta87f1b1f2019-07-30 13:03:23 +0200310 });
hebasta87f1b1f2019-07-30 13:03:23 +0200311 //See also: https://introjs.com/docs/intro/options/
312 tourR.setOption('scrollToElement', true);
313 tourR.setOption('scrollTo','tooltip');
314 this.testPrerequ(StepsSR, tourR);
315
316 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
317 tourR.onbeforechange(function(targetedElement){
318
319 if(this._currentStep == 1){
320 KorAP.session.set("tour", false);
321 }
322
323 if(this._currentStep == 2){
324 doe.querySelector("#search > ol > li").click();
325 tourR._introItems[3].element = doe.querySelector('.action > .metatable');
326 tourR._introItems[3].position = "bottom";
327 }
328
329 if(this._currentStep == 4){
330 doe.querySelector(".metatable").click();
331 tourR._introItems[4].element = doe.querySelector('.view.metatable');
332 tourR._introItems[5].element = doe.querySelector('.action > .info');
333 tourR._introItems[5].position = "bottom";
334 }
335
336 if(this._currentStep == 6){
337 doe.querySelector(".info").click();
338 tourR._introItems[6].element = doe.querySelector('.view.tokentable');
339 tourR._introItems[7].element = doe.querySelector('.tree');
340 tourR._introItems[7].position = "bottom";
341 }
342
343 if(this._currentStep == 8){
344 doe.querySelector(".tree").click();
345 document.querySelectorAll(".button-group-list")[0].querySelectorAll('li')[1].click();
hebastaf95226b2019-09-19 11:37:00 +0200346 tourR._introItems[8].element = doe.querySelector(".view.relations");
hebasta87f1b1f2019-07-30 13:03:23 +0200347 }
348 });
hebastaf95226b2019-09-19 11:37:00 +0200349
hebasta5df796f2019-05-21 15:27:12 +0200350 return tourR;
351 },
hebasta87f1b1f2019-07-30 13:03:23 +0200352 /*
353 * The total number of steps and the text of the tooltips are needed for jasmine testing.
354 */
355 testPrerequ: function(steps, tour){
356 //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
357 let StepsT = steps;
358 let gtour = tour;
359 gtour.stepCount = StepsT.length;
360
361 //Array of intro content needed for efficient testing
362 gtour.testIntros = [];
363
364 for(let i = 0; i< StepsT.length; i++){
365 gtour.testIntros.push(StepsT[i].intro);
366 }
367 },
hebasta5df796f2019-05-21 15:27:12 +0200368
hebasta75cfca52019-02-19 13:15:27 +0100369 }
370});