PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 All 140 releases
learnpress / assets / src / js / frontend / course-builder / builder-quiz / builder-tab-quiz.js

builder-tab-quiz.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at assets/src/js/frontend/course-builder/builder-quiz/builder-tab-quiz.js

454 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import * as lpUtils from 'lpAssetsJsPath/utils.js';
2 import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
3 import SweetAlert from 'sweetalert2';
4 import { SWAL_ICON_DELETE, SWAL_ICON_DUPLICATE, SWAL_ICON_TRASH_DRAFT } from '../swal-icons.js';
5
6 export class BuilderTabQuiz {
7 constructor() {
8 this.init();
9 }
10
11 static selectors = {
12 elQuizItem: '.quiz-item',
13 elQuizExpandedItems: '.quiz-action-expanded__items',
14 elQuizDuplicate: '.quiz-action-expanded__duplicate',
15 elQuizTrash: '.quiz-action-expanded__trash',
16 elQuizRestore: '.quiz-action-expanded__restore',
17 elQuizPublish: '.quiz-action-expanded__publish',
18 elQuizDelete: '.quiz-action-expanded__delete',
19 elQuizActionExpanded: '.quiz-action-expanded',
20 elQuizStatus: '.quiz-status',
21 elBtnEditQuiz: '.btn-edit-quiz',
22 };
23
24 init() {
25 this.events();
26 }
27
28 events() {
29 if ( BuilderTabQuiz._loadedEvents ) {
30 return;
31 }
32 BuilderTabQuiz._loadedEvents = true;
33
34 lpUtils.eventHandlers( 'click', [
35 {
36 selector: BuilderTabQuiz.selectors.elQuizDuplicate,
37 class: this,
38 callBack: this.duplicateQuiz.name,
39 },
40 {
41 selector: BuilderTabQuiz.selectors.elQuizTrash,
42 class: this,
43 callBack: this.trashQuiz.name,
44 },
45 {
46 selector: BuilderTabQuiz.selectors.elQuizPublish,
47 class: this,
48 callBack: this.publishQuiz.name,
49 },
50 {
51 selector: BuilderTabQuiz.selectors.elQuizRestore,
52 class: this,
53 callBack: this.restoreQuiz.name,
54 },
55 {
56 selector: BuilderTabQuiz.selectors.elQuizDelete,
57 class: this,
58 callBack: this.deleteQuiz.name,
59 },
60 {
61 selector: BuilderTabQuiz.selectors.elQuizActionExpanded,
62 class: this,
63 callBack: this.toggleExpandedAction.name,
64 },
65 {
66 selector: BuilderTabQuiz.selectors.elBtnEditQuiz,
67 class: this,
68 callBack: this.editQuiz.name,
69 },
70 ] );
71
72 document.addEventListener( 'click', ( e ) => {
73 if ( ! e.target.closest( BuilderTabQuiz.selectors.elQuizActionExpanded ) ) {
74 this.closeAllExpanded();
75 }
76 } );
77 }
78
79 editQuiz( args ) {
80 const { target } = args;
81 const elBtnEditQuiz = target.closest( BuilderTabQuiz.selectors.elBtnEditQuiz );
82
83 if ( ! elBtnEditQuiz ) {
84 return;
85 }
86
87 lpUtils.lpSetLoadingEl( elBtnEditQuiz, 1 );
88 }
89
90 duplicateQuiz( args ) {
91 const { target } = args;
92 const elQuizDuplicate = target.closest( BuilderTabQuiz.selectors.elQuizDuplicate );
93 const elQuizItem = elQuizDuplicate.closest( BuilderTabQuiz.selectors.elQuizItem );
94
95 if ( ! elQuizItem ) {
96 return;
97 }
98
99 const elActionExpanded = elQuizItem.querySelector(
100 BuilderTabQuiz.selectors.elQuizActionExpanded
101 );
102 const quizId = elQuizItem.dataset.quizId || '';
103
104 SweetAlert.fire( {
105 title: elQuizDuplicate.dataset.title || 'Duplicate Quiz',
106 text: elQuizDuplicate.dataset.content || 'Are you sure you want to duplicate this quiz?',
107 iconHtml: SWAL_ICON_DUPLICATE,
108 customClass: { icon: 'lp-cb-swal-icon-html' },
109 showCloseButton: true,
110 showCancelButton: true,
111 cancelButtonText: lpData.i18n.cancel,
112 confirmButtonText: lpData.i18n.yes,
113 reverseButtons: true,
114 } ).then( ( result ) => {
115 if ( result.isConfirmed ) {
116 lpUtils.lpSetLoadingEl( elActionExpanded, 1 );
117
118 const dataSend = {
119 action: 'duplicate_quiz',
120 args: {
121 id_url: 'duplicate-quiz',
122 },
123 quiz_id: quizId,
124 };
125
126 const callBack = {
127 success: ( response ) => {
128 const { status, message, data } = response;
129 lpToastify.show( message || 'Duplicated successfully!', status );
130
131 if ( status === 'success' && data?.redirect_url ) {
132 window.location.href = data.redirect_url;
133 }
134 },
135 error: ( error ) => {
136 lpToastify.show( error.message || error, 'error' );
137 },
138 completed: () => {
139 lpUtils.lpSetLoadingEl( elActionExpanded, 0 );
140 },
141 };
142
143 window.lpAJAXG.fetchAJAX( dataSend, callBack );
144 }
145 } );
146 }
147
148 trashQuiz( args ) {
149 const { target } = args;
150 const elQuizTrash = target.closest( BuilderTabQuiz.selectors.elQuizTrash );
151 const elQuizItem = elQuizTrash.closest( BuilderTabQuiz.selectors.elQuizItem );
152
153 if ( ! elQuizItem ) {
154 return;
155 }
156
157 const elActionExpanded = elQuizItem.querySelector(
158 BuilderTabQuiz.selectors.elQuizActionExpanded
159 );
160 const quizId = elQuizItem.dataset.quizId || '';
161
162 SweetAlert.fire( {
163 title: elQuizTrash.dataset.title || 'Trash Quiz',
164 text: elQuizTrash.dataset.content || 'Are you sure you want to move this quiz to trash?',
165 iconHtml: SWAL_ICON_TRASH_DRAFT,
166 customClass: { icon: 'lp-cb-swal-icon-html' },
167 showCloseButton: true,
168 showCancelButton: true,
169 cancelButtonText: lpData.i18n.cancel,
170 confirmButtonText: lpData.i18n.yes,
171 reverseButtons: true,
172 } ).then( ( result ) => {
173 if ( result.isConfirmed ) {
174 lpUtils.lpSetLoadingEl( elActionExpanded, 1 );
175
176 const dataSend = {
177 action: 'move_trash_quiz',
178 args: {
179 id_url: 'move-trash-quiz',
180 },
181 quiz_id: quizId,
182 };
183
184 const callBack = {
185 success: ( response ) => {
186 const { status, message, data } = response;
187 lpToastify.show( message, status );
188
189 if ( data?.html ) {
190 this.replaceItemHtml( elQuizTrash.closest( '.quiz' ), data.html );
191 }
192 },
193 error: ( error ) => {
194 lpToastify.show( error.message || error, 'error' );
195 },
196 completed: () => {
197 lpUtils.lpSetLoadingEl( elActionExpanded, 0 );
198 },
199 };
200
201 window.lpAJAXG.fetchAJAX( dataSend, callBack );
202 }
203 } );
204 }
205
206 publishQuiz( args ) {
207 const { target } = args;
208 const elQuizPublish = target.closest( BuilderTabQuiz.selectors.elQuizPublish );
209 const elQuizItem = elQuizPublish.closest( BuilderTabQuiz.selectors.elQuizItem );
210
211 if ( ! elQuizItem ) {
212 return;
213 }
214
215 const elActionExpanded = elQuizItem.querySelector(
216 BuilderTabQuiz.selectors.elQuizActionExpanded
217 );
218 lpUtils.lpSetLoadingEl( elActionExpanded, 1 );
219
220 const quizId = elQuizItem.dataset.quizId || '';
221
222 const dataSend = {
223 action: 'move_trash_quiz',
224 args: {
225 id_url: 'move-trash-quiz',
226 },
227 quiz_id: quizId,
228 status: 'publish',
229 };
230
231 const callBack = {
232 success: ( response ) => {
233 const { status, message, data } = response;
234 lpToastify.show( message, status );
235 if ( data?.html ) {
236 this.replaceItemHtml( elQuizPublish.closest( '.quiz' ), data.html );
237 }
238 },
239 error: ( error ) => {
240 lpToastify.show( error.message || error, 'error' );
241 },
242 completed: () => {
243 lpUtils.lpSetLoadingEl( elActionExpanded, 0 );
244 },
245 };
246
247 window.lpAJAXG.fetchAJAX( dataSend, callBack );
248 }
249
250 restoreQuiz( args ) {
251 const { target } = args;
252 const elQuizRestore = target.closest( BuilderTabQuiz.selectors.elQuizRestore );
253 const elQuizItem = elQuizRestore.closest( BuilderTabQuiz.selectors.elQuizItem );
254
255 if ( ! elQuizItem ) {
256 return;
257 }
258
259 const elActionExpanded = elQuizItem.querySelector(
260 BuilderTabQuiz.selectors.elQuizActionExpanded
261 );
262 lpUtils.lpSetLoadingEl( elActionExpanded, 1 );
263
264 const quizId = elQuizItem.dataset.quizId || '';
265
266 const dataSend = {
267 action: 'move_trash_quiz',
268 args: {
269 id_url: 'move-trash-quiz',
270 },
271 quiz_id: quizId,
272 status: 'draft',
273 };
274
275 const callBack = {
276 success: ( response ) => {
277 const { status, message, data } = response;
278 lpToastify.show( message, status );
279 if ( data?.html ) {
280 this.replaceItemHtml( elQuizRestore.closest( '.quiz' ), data.html );
281 }
282 },
283 error: ( error ) => {
284 lpToastify.show( error.message || error, 'error' );
285 },
286 completed: () => {
287 lpUtils.lpSetLoadingEl( elActionExpanded, 0 );
288 },
289 };
290
291 window.lpAJAXG.fetchAJAX( dataSend, callBack );
292 }
293
294 deleteQuiz( args ) {
295 const { target } = args;
296 const elQuizDelete = target.closest( BuilderTabQuiz.selectors.elQuizDelete );
297 const elQuizItem = elQuizDelete.closest( BuilderTabQuiz.selectors.elQuizItem );
298
299 if ( ! elQuizItem ) {
300 return;
301 }
302
303 const elActionExpanded = elQuizItem.querySelector(
304 BuilderTabQuiz.selectors.elQuizActionExpanded
305 );
306 const quizId = elQuizItem.dataset.quizId || '';
307
308 if ( ! quizId ) {
309 return;
310 }
311
312 SweetAlert.fire( {
313 title: elQuizDelete.dataset.title || 'Delete Quiz',
314 text:
315 elQuizDelete.dataset.content || 'Are you sure you want to permanently delete this quiz?',
316 iconHtml: SWAL_ICON_DELETE,
317 customClass: { icon: 'lp-cb-swal-icon-html' },
318 showCloseButton: true,
319 showCancelButton: true,
320 cancelButtonText: lpData.i18n.cancel,
321 confirmButtonText: lpData.i18n.yes,
322 reverseButtons: true,
323 } ).then( ( result ) => {
324 if ( result.isConfirmed ) {
325 lpUtils.lpSetLoadingEl( elActionExpanded, 1 );
326
327 const dataSend = {
328 action: 'move_trash_quiz',
329 args: {
330 id_url: 'move-trash-quiz',
331 },
332 quiz_id: quizId,
333 status: 'delete',
334 };
335
336 const callBack = {
337 success: ( response ) => {
338 const { status, message } = response;
339 lpToastify.show( message, status );
340
341 if ( status === 'success' ) {
342 const elQuiz = elQuizDelete.closest( '.quiz' );
343 elQuiz.style.transition = 'opacity 0.4s ease-out, transform 0.4s ease-out';
344 elQuiz.style.opacity = '0';
345 elQuiz.style.transform = 'translateX(160px)';
346
347 setTimeout( () => {
348 elQuiz.remove();
349 }, 400 );
350 }
351 },
352 error: ( error ) => {
353 lpToastify.show( error.message || error, 'error' );
354 },
355 completed: () => {
356 lpUtils.lpSetLoadingEl( elActionExpanded, 0 );
357 },
358 };
359
360 window.lpAJAXG.fetchAJAX( dataSend, callBack );
361 }
362 } );
363 }
364
365 toggleExpandedAction( args ) {
366 const { target } = args;
367 const elQuizActionExpanded = target.closest( BuilderTabQuiz.selectors.elQuizActionExpanded );
368
369 if ( ! elQuizActionExpanded ) {
370 return;
371 }
372
373 const elQuizItem = elQuizActionExpanded.closest( BuilderTabQuiz.selectors.elQuizItem );
374
375 if ( ! elQuizItem ) {
376 return;
377 }
378
379 const elExpandedItems = elQuizItem.querySelector(
380 BuilderTabQuiz.selectors.elQuizExpandedItems
381 );
382
383 if ( ! elExpandedItems ) {
384 return;
385 }
386
387 this.closeAllExpanded( elExpandedItems );
388 const willOpen = ! elExpandedItems.classList.contains( 'active' );
389
390 if ( willOpen ) {
391 elExpandedItems.classList.add( 'active' );
392 elQuizActionExpanded.classList.add( 'active' );
393 this.setExpandedDirection( elExpandedItems );
394 } else {
395 elExpandedItems.classList.remove( 'active' );
396 elExpandedItems.classList.remove( 'is-dropup' );
397 elQuizActionExpanded.classList.remove( 'active' );
398 }
399 }
400
401 closeAllExpanded( excludeElement = null ) {
402 const allExpandedItems = document.querySelectorAll(
403 `${ BuilderTabQuiz.selectors.elQuizExpandedItems }.active`
404 );
405 allExpandedItems.forEach( ( item ) => {
406 if ( item === excludeElement ) {
407 return;
408 }
409
410 item.classList.remove( 'active' );
411 item.classList.remove( 'is-dropup' );
412
413 const quizItem = item.closest( BuilderTabQuiz.selectors.elQuizItem );
414 if ( ! quizItem ) {
415 return;
416 }
417
418 const expandedBtn = quizItem.querySelector( BuilderTabQuiz.selectors.elQuizActionExpanded );
419 if ( expandedBtn ) {
420 expandedBtn.classList.remove( 'active' );
421 }
422 } );
423 }
424
425 setExpandedDirection( elExpandedItems ) {
426 if ( ! elExpandedItems ) {
427 return;
428 }
429
430 elExpandedItems.classList.remove( 'is-dropup' );
431
432 const elQuiz = elExpandedItems.closest( '.quiz' );
433 if ( ! elQuiz ) {
434 return;
435 }
436
437 if ( elQuiz.matches( ':last-child' ) ) {
438 elExpandedItems.classList.add( 'is-dropup' );
439 }
440 }
441
442 replaceItemHtml( elQuiz, html ) {
443 if ( ! elQuiz || ! html ) {
444 return;
445 }
446 const tmp = document.createElement( 'div' );
447 tmp.innerHTML = html;
448 const newEl = tmp.firstElementChild;
449 if ( newEl ) {
450 elQuiz.replaceWith( newEl );
451 }
452 }
453 }
454