PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.7.2
VikBooking Hotel Booking Engine & PMS v1.7.2
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / views / dashboard / tmpl / default_widgets.php

default_widgets.php in VikBooking Hotel Booking Engine & PMS 1.7.2, at admin/views/dashboard/tmpl/default_widgets.php

1,316 lines 56.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 $vbo_app = VikBooking::getVboApplication();
14
15 // get admin widgets helper
16 $widgets_helper = VikBooking::getAdminWidgetsInstance();
17 $widgets_map = $widgets_helper->getWidgetsMap();
18
19 // get all widgets by preloading their assets (if any)
20 $widgets_names = $widgets_helper->getWidgetNames($preload = true);
21
22 $widgets_welcome = $widgets_helper->showWelcome();
23
24 // global permissions are necessary to customize the admin widgets
25 $vbo_auth_global = JFactory::getUser()->authorise('core.vbo.global', 'com_vikbooking');
26
27 // check if the notification audio file exists within VCM
28 $notif_audio_path = implode(DIRECTORY_SEPARATOR, [VCM_ADMIN_PATH, 'assets', 'css', 'audio', 'new_notification.mp3']);
29 $notif_audio_url = is_file($notif_audio_path) ? (VCM_ADMIN_URI . implode('/', ['assets', 'css', 'audio', 'new_notification.mp3'])) : null;
30
31 // theme color preferences
32 $color_scheme = VikBooking::getAppearancePref();
33 $scheme_name = JText::translate('VBO_APPEARANCE_PREF_AUTO');
34 $current_mode = 'magic';
35 if ($color_scheme == 'light') {
36 $scheme_name = JText::translate('VBO_APPEARANCE_PREF_LIGHT');
37 $current_mode = 'sun';
38 } elseif ($color_scheme == 'dark') {
39 $scheme_name = JText::translate('VBO_APPEARANCE_PREF_DARK');
40 $current_mode = 'moon';
41 }
42
43 // load sortable library
44 JHtml::fetch('jquery.framework', true, true);
45 JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.sortable.min.js');
46
47 // load language vars for JavaScript
48 JText::script('VBO_WIDGETS_WELCOME');
49 JText::script('VBO_WIDGETS_ADDWIDGCONT');
50 JText::script('VBO_WIDGETS_RESTDEFAULT');
51 JText::script('VBO_WIDGETS_ADDNEWWIDG');
52 JText::script('VBO_WIDGETS_SAVINGMAP');
53 JText::script('VBO_WIDGETS_ERRSAVINGMAP');
54 JText::script('VBO_WIDGETS_LASTUPD');
55 JText::script('VBO_WIDGETS_ENTERSECTNAME');
56 JText::script('VBO_WIDGETS_NEWSECT');
57 JText::script('VBO_WIDGETS_CONFRMELEM');
58 JText::script('VBO_WIDGETS_SELCONTSIZE');
59 JText::script('VBO_WIDGETS_UPDWIDGCONT');
60 JText::script('VBO_WIDGETS_EDITWIDGCONT');
61 JText::script('VBO_WIDGETS_ERRDISPWIDG');
62 JText::script('VBO_STICKYN_TITLE');
63 JText::script('VBO_STICKYN_TEXT');
64 JText::script('VBO_STICKYN_TEXT2');
65 JText::script('VBO_STICKYN_CUSTOMURI');
66 JText::script('VBO_BROWSER_NOTIFS_ON');
67 JText::script('VBO_BROWSER_NOTIFS_OFF');
68 JText::script('VBO_BROWSER_NOTIFS_OFF_HELP');
69 JText::script('VBO_ADMIN_WIDGET');
70 JText::script('VBO_CONGRATS');
71 JText::script('VBO_APPEARANCE_PREF_AUTO');
72 JText::script('VBO_APPEARANCE_PREF_LIGHT');
73 JText::script('VBO_APPEARANCE_PREF_DARK');
74
75 /**
76 * Monitor request vars to see if a widget should be loaded within a modal.
77 * Only the dashboard at the moment allows to render an admin widget within
78 * a modal through query string values, because all other pages will render
79 * the multitask panel that can quickly render any admin widget.
80 *
81 * @since 1.16.0 (J) - 1.6.0 (WP)
82 * @since 1.16.5 (J) - 1.6.5 (WP) added payload support for clicked Push notifications.
83 */
84 $app = JFactory::getApplication();
85
86 $load_widget = $app->input->get('load_widget', '');
87 $multitask_data = $app->input->get('multitask_data', [], 'array');
88 $multitask_options = [];
89 $push_notification = $app->input->get('push_notification', '', 'base64');
90 if (!$load_widget && $push_notification) {
91 // parse the payload to detect the proper type of widget to render
92 list($load_widget, $multitask_data, $multitask_options) = VBOMultitaskParser::queryPushData($multitask_data, base64_decode($push_notification));
93 }
94
95 // process widget data, if any
96 if (!empty($load_widget) && $desired_widget = $widgets_helper->getWidget($load_widget)) {
97 $multitask_data['_modalTitle'] = $desired_widget->getName();
98 $data_payload = json_encode($multitask_data);
99 $options_payload = json_encode($multitask_options);
100
101 // append script to DOM to render the widget within a modal
102 JFactory::getDocument()->addScriptDeclaration(
103 <<<JS
104 (function($) {
105 'use strict';
106
107 $(function() {
108 setTimeout(() => {
109 VBOCore.renderModalWidget('$load_widget', $data_payload, $options_payload, false);
110 }, 500);
111 });
112 })(jQuery);
113 JS
114 );
115 }
116
117 ?>
118 <div class="vbo-admin-widgets-wrap">
119 <?php
120 if ($vbo_auth_global) {
121 ?>
122 <div class="vbo-admin-widgets-commands">
123 <div class="vbo-admin-widgets-commands-info" data-vbomanagewidgets="1" style="display: none;">
124 <div class="vbo-admin-widgets-commands-info-inner">
125 <span class="vbo-admin-widgets-commands-info-txt"><?php echo JText::translate('VBO_WIDGETS_AUTOSAVE'); ?></span>
126 <div class="vbo-admin-widgets-commands-info-restore">
127 <a href="index.php?option=com_vikbooking&task=reset_admin_widgets" class="btn btn-secondary" onclick="return vboWidgetsRestoreMap();"><?php echo JText::translate('VBO_WIDGETS_RESTDEFAULTSHORT'); ?></a>
128 </div>
129 <div class="vbo-sidepanel-colorscheme vbo-dashboard-colorscheme">
130 <span class="vbo-tooltip vbo-tooltip-top vbo-sidepanel-colorscheme-current" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', $scheme_name); ?>"><?php VikBookingIcons::e($current_mode); ?></span>
131 <div class="vbo-sidepanel-colorscheme-list">
132 <div class="vbo-sidepanel-colorscheme-option<?php echo $color_scheme == 'auto' ? ' vbo-sidepanel-colorscheme-option-active' : ''; ?>" data-scheme="auto">
133 <span><?php VikBookingIcons::e('magic'); ?> <?php echo JText::translate('VBO_APPEARANCE_PREF_AUTO'); ?></span>
134 </div>
135 <div class="vbo-sidepanel-colorscheme-option<?php echo $color_scheme == 'light' ? ' vbo-sidepanel-colorscheme-option-active' : ''; ?>" data-scheme="light">
136 <span><?php VikBookingIcons::e('sun'); ?> <?php echo JText::translate('VBO_APPEARANCE_PREF_LIGHT'); ?></span>
137 </div>
138 <div class="vbo-sidepanel-colorscheme-option<?php echo $color_scheme == 'dark' ? ' vbo-sidepanel-colorscheme-option-active' : ''; ?>" data-scheme="dark">
139 <span><?php VikBookingIcons::e('moon'); ?> <?php echo JText::translate('VBO_APPEARANCE_PREF_DARK'); ?></span>
140 </div>
141 </div>
142 </div>
143 <div class="vbo-admin-widgets-suggest-notifications-cont" style="display: none;">
144 <span class="vbo-suggest-notifications-wrap">
145 <button class="vbo-dash-suggest-notifications-btn vbo-suggest-notifications-btn" type="button"><?php VikBookingIcons::e('bell', 'can-shake') ?></button>
146 </span>
147 </div>
148 </div>
149 </div>
150 <div class="vbo-admin-widgets-commands-mng">
151 <span class="vbo-admin-widgets-commands-mng-toggle"><?php echo $vbo_app->printYesNoButtons('vbocustwidgets', JText::translate('VBYES'), JText::translate('VBNO'), 0, 1, 0, 'vboWidgetsToggleManage(false);'); ?></span>
152 <span class="vbo-admin-widgets-commands-mng-lbl" onclick="vboWidgetsToggleManage(true);"><?php VikBookingIcons::e('cogs'); ?> <?php echo JText::translate('VBO_WIDGETS_CUSTWIDGETS'); ?></span>
153 </div>
154 </div>
155 <?php
156 }
157 ?>
158 <div class="vbo-admin-widgets-list">
159 <?php
160 foreach ($widgets_map->sections as $seck => $section) {
161 ?>
162 <div class="vbo-admin-widgets-section">
163 <div class="vbo-admin-widgets-section-name" data-vbomanagewidgets="1" style="display: none;">
164 <span class="vbo-admin-widgets-elem-cmds-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>
165 <span class="vbo-admin-widgets-section-name-val"><?php echo $section->name; ?></span>
166 <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-section-cmds">
167 <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditSection(this);"><?php VikBookingIcons::e('edit'); ?></span>
168 <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveSection(this);"><?php VikBookingIcons::e('trash'); ?></span>
169 </div>
170 </div>
171 <?php
172 if (!isset($section->containers)) {
173 $section->containers = array();
174 }
175 $tot_containers = count($section->containers);
176 foreach ($section->containers as $conk => $container) {
177 $container_css = $widgets_helper->getContainerCssClass($container->size);
178 ?>
179 <div class="vbo-admin-widgets-container <?php echo $container_css; ?>" data-vbowidgetcontsize="<?php echo $container->size; ?>" data-totcontainers="<?php echo $tot_containers; ?>">
180 <div class="vbo-admin-widgets-container-name" data-vbomanagewidgets="1" style="display: none;">
181 <span class="vbo-admin-widgets-container-name-val"><?php echo $widgets_helper->getContainerName($container->size); ?></span>
182 <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-container-cmds">
183 <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditContainer(this);"><?php VikBookingIcons::e('edit'); ?></span>
184 <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveContainer(this);"><?php VikBookingIcons::e('trash'); ?></span>
185 </div>
186 </div>
187 <?php
188 if (!isset($container->widgets)) {
189 $container->widgets = array();
190 }
191 foreach ($container->widgets as $widk => $widget_id) {
192 $widget_instance = $widgets_helper->getWidget($widget_id);
193 if ($widget_instance === false) {
194 continue;
195 }
196 ?>
197 <div class="vbo-admin-widgets-widget" data-vbowidgetid="<?php echo $widget_instance->getIdentifier(); ?>">
198 <div class="vbo-admin-widgets-widget-info" data-vbomanagewidgets="1" style="display: none;">
199 <div class="vbo-admin-widgets-widget-info-inner">
200 <div class="vbo-admin-widgets-widget-details">
201 <span class="vbo-admin-widgets-widget-info-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>
202 <h4 class="vbo-admin-widgets-widget-info-name">
203 <span><?php echo $widget_instance->getName(); ?></span>
204 <span class="vbo-admin-widgets-widget-remove" onclick="vboWidgetsRemoveWidget(this);"><?php VikBookingIcons::e('trash'); ?></span>
205 </h4>
206 </div>
207 <div class="vbo-admin-widgets-widget-info-descr"><?php echo $widget_instance->getDescription(); ?></div>
208 </div>
209 </div>
210 <div class="vbo-admin-widgets-widget-output">
211 <?php $widget_instance->render(); ?>
212 </div>
213 </div>
214 <?php
215 }
216 ?>
217 <div class="vbo-admin-widgets-widget vbo-admin-widgets-widget-addnew" data-vbomanagewidgets="1" style="display: none;">
218 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddWidget(this);">
219 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
220 </div>
221 </div>
222 </div>
223 <?php
224 }
225 ?>
226 <div class="vbo-admin-widgets-container vbo-admin-widgets-container-addnew" data-vbomanagewidgets="1" style="display: none;">
227 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddContainer(this);">
228 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
229 </div>
230 </div>
231 </div>
232 <?php
233 }
234 ?>
235 <div class="vbo-admin-widgets-section vbo-admin-widgets-section-addnew" data-vbomanagewidgets="1" style="display: none;">
236 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddSection();">
237 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
238 </div>
239 </div>
240 </div>
241 </div>
242
243 <div class="vbo-modal-overlay-block vbo-modal-overlay-block-dashwidgets">
244 <a class="vbo-modal-overlay-close" href="javascript: void(0);"></a>
245 <div class="vbo-modal-overlay-content vbo-modal-overlay-content-dashwidgets">
246 <div class="vbo-modal-overlay-content-head vbo-modal-overlay-content-head-dashwidgets">
247 <h3><span id="vbo-modal-widgets-title"></span> <span class="vbo-modal-overlay-close-times" onclick="hideVboModalWidgets();">&times;</span></h3>
248 </div>
249 <div class="vbo-modal-overlay-content-body vbo-modal-overlay-content-body-scroll">
250 <div class="vbo-modal-widgets-newcontainer vbo-modal-widgets-forms" style="display: none;">
251 <div class="vbo-modal-widgets-form-data-fields">
252 <div class="vbo-modal-widgets-form-data-field">
253 <label for="vbo-newcontainer-size"><?php echo JText::translate('VBO_WIDGETS_CONTSIZE'); ?></label>
254 <select id="vbo-newcontainer-size">
255 <?php
256 foreach ($widgets_helper->getContainerClassNames() as $class_key => $class_name_data) {
257 ?>
258 <option value="<?php echo $class_key; ?>" data-cssclass="<?php echo $class_name_data['css']; ?>"><?php echo $class_name_data['name']; ?></option>
259 <?php
260 }
261 ?>
262 </select>
263 <input type="hidden" id="vbo-newcontainer-upd" value="0" />
264 </div>
265 </div>
266 </div>
267 <div class="vbo-modal-widgets-newwidget vbo-modal-widgets-forms" style="display: none;">
268 <div class="vbo-modal-widgets-form-data-fields">
269 <div class="vbo-modal-widgets-form-data-field">
270 <label><?php echo JText::translate('VBO_WIDGETS_SELWIDGADD'); ?></label>
271 </div>
272 <div class="vbo-modal-widgets-form-data-field vbo-modal-widgets-list">
273 <input type="hidden" id="vbo-newwidget-id" value="" />
274 <?php
275 foreach ($widgets_names as $widget_data) {
276 ?>
277 <div class="vbo-modal-widget-wrap vbo-admin-widget-style-<?php echo $widget_data->style; ?>" data-vbowidgetid="<?php echo $widget_data->id; ?>" onclick="vboWidgetsSelectWidget('<?php echo $widget_data->id; ?>');">
278 <div class="vbo-modal-widget-cont-top">
279 <div class="vbo-modal-widget-icon">
280 <span><?php echo $widget_data->icon; ?></span>
281 </div>
282 <div class="vbo-modal-widget-add">
283 <span onclick="vboWidgetsAddWidgetToDoc('<?php echo $widget_data->id; ?>');"><?php VikBookingIcons::e('plus-circle'); ?></span>
284 </div>
285 </div>
286 <div class="vbo-modal-widget-cont-main">
287 <div class="vbo-modal-widget-name">
288 <span><?php echo $widget_data->name; ?></span>
289 </div>
290 <div class="vbo-modal-widget-descr">
291 <span><?php echo $widget_data->descr; ?></span>
292 </div>
293 </div>
294 </div>
295 <?php
296 }
297 ?>
298 </div>
299 <div class="vbo-modal-widgets-form-data-field vbo-newwidget-descr" style="display: none;"></div>
300 </div>
301 </div>
302 <?php
303 if ($widgets_welcome) {
304 ?>
305 <div class="vbo-widgets-welcome-wrap vbo-modal-widgets-forms" style="display: none;">
306 <div class="vbo-widgets-welcome-inner">
307 <p><?php echo JText::translate('VBO_WIDGETS_WELCOME_DESC1'); ?></p>
308 <p><?php echo JText::translate('VBO_WIDGETS_WELCOME_DESC2'); ?></p>
309 <div class="vbo-widgets-welcome-demo">
310 <div class="vbo-widgets-welcome-demo-section">
311 <span class="vbo-widgets-welcome-demo-section-lbl"><?php echo JText::translate('VBO_WIDGETS_NEWSECT'); ?></span>
312 <div class="vbo-widgets-welcome-demo-container">
313 <span class="vbo-widgets-welcome-demo-container-lbl"><?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></span>
314 <div class="vbo-widgets-welcome-demo-widget">
315 <span class="vbo-widgets-welcome-demo-widget-lbl"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></span>
316 </div>
317 </div>
318 <div class="vbo-widgets-welcome-demo-container">
319 <span class="vbo-widgets-welcome-demo-container-lbl"><?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></span>
320 <div class="vbo-widgets-welcome-demo-widget">
321 <span class="vbo-widgets-welcome-demo-widget-lbl"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></span>
322 </div>
323 </div>
324 </div>
325 </div>
326 </div>
327 </div>
328 <?php
329 }
330 ?>
331 </div>
332 <div class="vbo-modal-overlay-content-footer">
333 <div class="vbo-modal-footer-newcontainer vbo-modal-widgets-forms-footer" style="display: none;">
334 <div class="vbo-modal-overlay-content-footer-right">
335 <button type="button" class="btn btn-success" id="vbo-newcontainer-btn" onclick="vboWidgetsAddContainerToDoc();"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></button>
336 </div>
337 </div>
338 <div class="vbo-modal-footer-newwidget vbo-modal-widgets-forms-footer" style="display: none;">
339 <div class="vbo-modal-overlay-content-footer-right">
340 <button type="button" class="btn btn-success" onclick="vboWidgetsAddWidgetToDoc();"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></button>
341 </div>
342 </div>
343 <div class="vbo-modal-footer-welcome vbo-modal-widgets-forms-footer" style="display: none;">
344 <div class="vbo-modal-overlay-content-footer-left">
345 <button type="button" class="btn btn-secondary" onclick="vboWidgetsCloseWelcome(1);"><?php echo JText::translate('VBOBTNDONTREMIND'); ?></button>
346 </div>
347 <div class="vbo-modal-overlay-content-footer-right">
348 <button type="button" class="btn btn-success" onclick="vboWidgetsCloseWelcome(0);"><?php echo JText::translate('VBOBTNKEEPREMIND'); ?></button>
349 </div>
350 </div>
351 </div>
352 </div>
353 </div>
354
355 <script type="text/javascript">
356 /**
357 * Declare global scope variables.
358 */
359 var vbo_admin_widgets_map = <?php echo json_encode($widgets_map); ?>;
360 var vbo_admin_widgets_names = <?php echo json_encode($widgets_names); ?>;
361
362 var vbo_admin_widgets_last_section = null,
363 vbo_admin_widgets_last_container = null,
364 vbo_admin_widgets_initpos_section = 0,
365 vbo_admin_widgets_initpos_container = 0,
366 vbo_admin_widgets_initpos_widget = 0,
367 vbo_admin_widgets_initinst_widget = -1,
368 vbo_admin_widgets_allow_drop = false,
369 vbo_admin_widgets_sugg_notifs = false;
370
371 var vbo_modal_widgets_on = false;
372
373 var vbo_admin_widgets_welcome = <?php echo $widgets_welcome ? 'true' : 'false'; ?>;
374
375 /**
376 * Shows the modal window
377 */
378 function vboOpenModalWidgets() {
379 jQuery('.vbo-modal-overlay-block-dashwidgets').show();
380 vbo_modal_widgets_on = true;
381 }
382
383 /**
384 * Hides the modal window
385 */
386 function hideVboModalWidgets() {
387 if (vbo_modal_widgets_on === true) {
388 jQuery(".vbo-modal-overlay-block-dashwidgets").fadeOut(400, function() {
389 jQuery(".vbo-modal-overlay-content-dashwidgets").show();
390 jQuery(".vbo-modal-widgets-forms").hide();
391 jQuery(".vbo-modal-widgets-forms-footer").hide();
392 });
393 // turn flag off
394 vbo_modal_widgets_on = false;
395 }
396 }
397
398 /**
399 * Toggles the widget customizer mode
400 */
401 function vboWidgetsToggleManage(trigger) {
402 if (trigger === true) {
403 jQuery('input[name="vbocustwidgets"]').trigger('click');
404 return;
405 }
406 if (!jQuery('input[name="vbocustwidgets"]').is(':checked')) {
407 jQuery('div[data-vbomanagewidgets="1"]').hide();
408 jQuery('.vbo-admin-widgets-widget-output').show();
409 jQuery('.vbo-admin-widgets-list').removeClass('vbo-admin-widgets-list-customize');
410 } else {
411 jQuery('.vbo-admin-widgets-widget-output').hide();
412 jQuery('div[data-vbomanagewidgets="1"]').show();
413 jQuery('.vbo-admin-widgets-list').addClass('vbo-admin-widgets-list-customize');
414 // show welcome (if necessary)
415 vboWidgetsShowWelcome();
416 // handle notification suggestions
417 if (!vbo_admin_widgets_sugg_notifs && VBOCore.notificationsEnabled() === false) {
418 vbo_admin_widgets_sugg_notifs = true;
419 jQuery('.vbo-admin-widgets-suggest-notifications-cont').show();
420 VBOCore.suggestNotifications('.vbo-dash-suggest-notifications-btn');
421 }
422 }
423 }
424
425 /**
426 * Opens the modal window with the welcome message for the admin widgets customizer.
427 */
428 function vboWidgetsShowWelcome() {
429 if (!vbo_admin_widgets_welcome || !jQuery('.vbo-widgets-welcome-wrap').length) {
430 return;
431 }
432 // prevent this from being displayed again in the same page flow
433 vbo_admin_widgets_welcome = false;
434 // display welcome container
435 jQuery('.vbo-widgets-welcome-wrap').show();
436 jQuery('.vbo-modal-footer-welcome').show();
437 // set modal title
438 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_WELCOME'));
439 // display modal
440 vboOpenModalWidgets();
441 // declare timeouts to add the animate class to the welcome elements
442 setTimeout(() => {
443 // animate container
444 jQuery('.vbo-widgets-welcome-demo-section').addClass('vbo-widgets-welcome-animate');
445 }, 1000);
446 setTimeout(() => {
447 // animate first section
448 jQuery('.vbo-widgets-welcome-demo-container').first().addClass('vbo-widgets-welcome-animate');
449 }, 2000);
450 setTimeout(() => {
451 // animate last section
452 jQuery('.vbo-widgets-welcome-demo-container').last().addClass('vbo-widgets-welcome-animate');
453 }, 3000);
454 setTimeout(() => {
455 // animate widgets
456 jQuery('.vbo-widgets-welcome-demo-widget').addClass('vbo-widgets-welcome-animate');
457 }, 4000);
458 }
459
460 /**
461 * Closes the modal window for the welcome text by storing an action.
462 */
463 function vboWidgetsCloseWelcome(hidenext) {
464 // dismiss modal
465 hideVboModalWidgets();
466 // AJAX request to update the welcome status
467 VBOCore.doAjax(
468 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=admin_widgets_welcome'); ?>",
469 {
470 hide_welcome: hidenext,
471 tmpl: "component"
472 },
473 (response) => {
474 try {
475 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
476 if (!obj_res.hasOwnProperty('status')) {
477 // request failed
478 console.error('Could not update welcome status', obj_res);
479 }
480 } catch(err) {
481 console.error('could not parse JSON response when updating the welcome status', err, response);
482 }
483 },
484 (error) => {
485 console.error(error);
486 }
487 );
488 }
489
490 /**
491 * This will fire during the throttle of the save-map event.
492 * Saves the updated admin widgets map onto the database.
493 */
494 function vboHandleMapSaving() {
495 // update info status to "saving..."
496 jQuery('.vbo-admin-widgets-commands-info-txt').removeClass('vbo-admin-widgets-error').html('<?php VikBookingIcons::e('refresh', 'fa-spin fa-fw'); ?> ' + Joomla.JText._('VBO_WIDGETS_SAVINGMAP'));
497
498 // prepare AJAX request data
499 var saving_request = {
500 tmpl: "component"
501 }
502 Object.assign(saving_request, vbo_admin_widgets_map);
503
504 // make the request
505 VBOCore.doAjax(
506 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=save_admin_widgets'); ?>",
507 saving_request,
508 (response) => {
509 try {
510 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
511 if (!obj_res.status) {
512 // request failed
513 console.error('Could not update the map', obj_res);
514 // update info status to "error..."
515 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
516 } else {
517 // set last updated time
518 var now = new Date;
519 var hours = now.getHours();
520 hours = hours < 10 ? '0' + hours : hours;
521 var minutes = now.getMinutes();
522 minutes = minutes < 10 ? '0' + minutes : minutes;
523 var seconds = now.getSeconds();
524 seconds = seconds < 10 ? '0' + seconds : seconds;
525 var full_time_now = hours + ':' + minutes + ':' + seconds;
526 // update info status to "last update time"
527 jQuery('.vbo-admin-widgets-commands-info-txt').removeClass('vbo-admin-widgets-error').html('<?php VikBookingIcons::e('check-circle'); ?> ' + Joomla.JText._('VBO_WIDGETS_LASTUPD') + ': ' + full_time_now);
528 }
529 } catch(err) {
530 console.error('could not parse JSON response when updating the map', err, response);
531 // update info status to "error..."
532 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
533 }
534 },
535 (error) => {
536 console.error(error.responseText);
537 // update info status to "error..."
538 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
539 }
540 );
541 }
542
543 /**
544 * Makes all sections sortable. Do not use .disableSelection() or this
545 * will break all [contenteditable] elements and their focus/selection events.
546 */
547 function vboMakeSectionsSortable() {
548 jQuery('.vbo-admin-widgets-list').sortable({
549 axix: 'x',
550 cursor: 'move',
551 handle: '.vbo-admin-widgets-section-name .vbo-admin-widgets-elem-cmds-drag',
552 items: '.vbo-admin-widgets-section:not(.vbo-admin-widgets-section-addnew)',
553 revert: false,
554 start: function(event, ui) {
555 // update global initial position for section
556 vbo_admin_widgets_initpos_section = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(ui.item));
557 },
558 update: function(event, ui) {
559 var new_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(ui.item));
560 // update global map object - move originial section to new position
561 vbo_admin_widgets_map.sections.splice(new_sect_index, 0, vbo_admin_widgets_map.sections.splice(vbo_admin_widgets_initpos_section, 1)[0]);
562
563 // trigger the save-map event
564 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
565 }
566 });
567 }
568
569 /**
570 * Makes all widgets sortable. Do not use .disableSelection() or this
571 * will break all [contenteditable] elements and their focus/selection events.
572 */
573 function vboMakeWidgetsSortable() {
574 jQuery('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').sortable({
575 connectWith: '.vbo-admin-widgets-container:not(.vbo-admin-widgets-container-addnew)',
576 cursor: 'move',
577 dropOnEmpty: true,
578 handle: '.vbo-admin-widgets-widget-details .vbo-admin-widgets-widget-info-drag',
579 helper: 'clone',
580 items: '.vbo-admin-widgets-widget:not(.vbo-admin-widgets-widget-addnew)',
581 placeholder: 'vbo-admin-widgets-container-tmpdrop',
582 revert: false,
583 start: function(event, ui) {
584 // allow drop
585 vbo_admin_widgets_allow_drop = true;
586 // calculate initial positions
587 var initial_widget = jQuery(ui.item);
588 var initial_section = initial_widget.closest('.vbo-admin-widgets-section');
589 var initial_container = initial_widget.closest('.vbo-admin-widgets-container');
590 // update global initial position for section
591 vbo_admin_widgets_initpos_section = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(initial_section);
592 // update global initial position for container
593 vbo_admin_widgets_initpos_container = initial_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(initial_container);
594 // update global initial position for widget
595 vbo_admin_widgets_initpos_widget = initial_container.find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(initial_widget);
596 // update global initial instance index for this type of widget
597 var widget_type = initial_widget.attr('data-vbowidgetid');
598 vbo_admin_widgets_initinst_widget = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + widget_type + '"]').index(initial_widget);
599 },
600 update: function(event, ui) {
601 var dropped_widget = jQuery(ui.item);
602 var dropped_section = dropped_widget.closest('.vbo-admin-widgets-section');
603 var dropped_container = dropped_widget.closest('.vbo-admin-widgets-container');
604 // calculate new element positions
605 var new_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(dropped_section);
606 var new_cont_index = dropped_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(dropped_container);
607 var new_widg_index = dropped_container.find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(dropped_widget);
608
609 if (new_sect_index != vbo_admin_widgets_initpos_section || new_cont_index != vbo_admin_widgets_initpos_container) {
610 /**
611 * Widget has been moved to a connected list, to a different section or container.
612 * Multiple "update" events will be fired, one for each target, so 2 in total.
613 */
614 if (vbo_admin_widgets_allow_drop !== true) {
615 // both events contain the same dropped target information (ui), so we skip any later event
616 return;
617 }
618
619 // disable drop for any sub-sequent event
620 vbo_admin_widgets_allow_drop = false;
621
622 // update global map object - remove original widget
623 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(vbo_admin_widgets_initpos_widget, 1);
624
625 // update global map object - push new widget
626 vbo_admin_widgets_map.sections[new_sect_index]['containers'][new_cont_index]['widgets'].splice(new_widg_index, 0, dropped_widget.attr('data-vbowidgetid'));
627 } else {
628 /**
629 * Widget has been sorted from the same section and container list.
630 * Only one "update" event will be fired.
631 */
632
633 // update global map object - move original widget to new position
634 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(
635 new_widg_index,
636 0,
637 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(vbo_admin_widgets_initpos_widget, 1)[0]
638 );
639 }
640
641 // calculate new instance index for this type of widget
642 var widget_type = dropped_widget.attr('data-vbowidgetid');
643 var new_instance_index = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + widget_type + '"]').index(dropped_widget);
644 if (vbo_admin_widgets_initinst_widget >= 0 && new_instance_index >= 0 && vbo_admin_widgets_initinst_widget != new_instance_index) {
645 // widget instance index has changed, and since we have multiple instances of this widget, we may need to update its settings
646
647 // the widget method to call
648 var call_method = 'sortInstance';
649 // make a silent call for the widget in case it needs to perform actions when removing an instance
650 VBOCore.doAjax(
651 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
652 {
653 widget_id: widget_type,
654 widget_index_old: vbo_admin_widgets_initinst_widget,
655 widget_index_new: new_instance_index,
656 call: call_method,
657 tmpl: "component"
658 },
659 (response) => {
660 try {
661 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
662 if (!obj_res.hasOwnProperty(call_method)) {
663 console.error('Unexpected JSON response', obj_res);
664 }
665 } catch(err) {
666 console.error('could not parse JSON response', err, response);
667 }
668 },
669 (error) => {
670 console.error(error.responseText);
671 }
672 );
673 }
674
675 // trigger the save-map event
676 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
677
678 }
679 });
680 }
681
682 /**
683 * Declares document ready event processes.
684 */
685 jQuery(function() {
686
687 /**
688 * Dismiss modal window with Esc.
689 */
690 jQuery(document).keydown(function(e) {
691 if (e.keyCode == 27) {
692 if (vbo_modal_widgets_on === true) {
693 hideVboModalWidgets();
694 }
695 }
696 });
697
698 /**
699 * Dismiss modal window by clicking on an external element.
700 */
701 jQuery(document).mouseup(function(e) {
702 if (!vbo_modal_widgets_on) {
703 return false;
704 }
705 if (vbo_modal_widgets_on) {
706 var vbo_overlay_cont = jQuery(".vbo-modal-overlay-content-dashwidgets");
707 if (!vbo_overlay_cont.is(e.target) && vbo_overlay_cont.has(e.target).length === 0) {
708 hideVboModalWidgets();
709 }
710 }
711 });
712
713 /**
714 * Make all current sections and widgets sortable.
715 */
716 vboMakeSectionsSortable();
717 vboMakeWidgetsSortable();
718
719 /**
720 * Add event listener to the save-map event with debounce handler.
721 */
722 document.addEventListener('vbo-admin-widgets-savemap', VBOCore.debounceEvent(vboHandleMapSaving, 2000));
723
724 /**
725 * Setup browser notifications and admin widgets core features.
726 */
727 VBOCore.setOptions({
728 is_vbo: true,
729 cms: "<?php echo VBOPlatformDetection::isWordPress() ? 'wordpress' : 'joomla'; ?>",
730 widget_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
731 assets_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=widgets_get_assets'); ?>",
732 multitask_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_multitask_widgets'); ?>",
733 watchdata_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=widgets_watch_data'); ?>",
734 current_page: "dashboard",
735 current_page_uri: "<?php echo htmlspecialchars((string) JUri::getInstance(), ENT_QUOTES); ?>",
736 root_uri: "<?php echo htmlspecialchars(JUri::root(), ENT_QUOTES); ?>",
737 panel_opts: {
738 notif_on_class: "vbo-sidepanel-notifications-on",
739 notif_off_class: "vbo-sidepanel-notifications-off",
740 },
741 notif_audio_url: "<?php echo $notif_audio_url; ?>",
742 tn_texts: {
743 notifs_enabled: Joomla.JText._('VBO_BROWSER_NOTIFS_ON'),
744 notifs_disabled: Joomla.JText._('VBO_BROWSER_NOTIFS_OFF'),
745 notifs_disabled_help: Joomla.JText._('VBO_BROWSER_NOTIFS_OFF_HELP'),
746 admin_widget: Joomla.JText._('VBO_ADMIN_WIDGET'),
747 congrats: Joomla.JText._('VBO_CONGRATS'),
748 },
749 default_loading_body: '<?php VikBookingIcons::e('circle-notch', 'fa-spin fa-fw'); ?>',
750 service_worker_path: '<?php echo VBOWebappServiceworker::getUri(); ?>',
751 service_worker_scope: '<?php echo VBOWebappServiceworker::getScope(); ?>',
752 push: <?php echo json_encode(VBOWebappPush::getConfig()); ?>,
753 }).setupNotifications();
754
755 /**
756 * Install Service Worker
757 */
758 VBOCore.installServiceWorker().then((registration) => {
759 VBOCore.handlePushSubscription(registration).then((subscription) => {
760 console.info('Push notifications are enabled');
761 }).catch((error) => {
762 console.warn(error);
763 });
764 }).catch((error) => {
765 console.warn(error);
766 });
767
768 // color scheme preferences
769 jQuery('.vbo-sidepanel-colorscheme-current').on('click', function() {
770 jQuery('.vbo-sidepanel-colorscheme-list').toggleClass('vbo-sidepanel-colorscheme-list-show');
771 });
772
773 // color scheme selection
774 jQuery('.vbo-sidepanel-colorscheme-option').on('click', function() {
775 let set_mode = jQuery(this).attr('data-scheme');
776
777 let vbo_css_base_uri = '<?php echo VBO_ADMIN_URI . (VBOPlatformDetection::isWordPress() ? 'resources/' : '') . 'vbo-appearance-%s.css'; ?>';
778 let vbo_css_base_id = 'vbo-css-appearance-';
779 let vcm_css_base_id = 'vcm-css-appearance-';
780 let vbo_css_modes = {
781 auto: vbo_css_base_uri.replace('%s', 'auto'),
782 dark: vbo_css_base_uri.replace('%s', 'dark'),
783 light: null,
784 };
785 let vbo_mode_texts = {
786 auto: Joomla.JText._('VBO_APPEARANCE_PREF_AUTO'),
787 dark: Joomla.JText._('VBO_APPEARANCE_PREF_DARK'),
788 light: Joomla.JText._('VBO_APPEARANCE_PREF_LIGHT'),
789 };
790 let vbo_mode_icons = {
791 auto: '<?php VikBookingIcons::e('magic') ?>',
792 dark: '<?php VikBookingIcons::e('moon') ?>',
793 light: '<?php VikBookingIcons::e('sun') ?>',
794 };
795
796 if (!vbo_css_modes.hasOwnProperty(set_mode)) {
797 return false;
798 }
799
800 // toggle active class
801 jQuery('.vbo-sidepanel-colorscheme-option').removeClass('vbo-sidepanel-colorscheme-option-active');
802 jQuery(this).addClass('vbo-sidepanel-colorscheme-option-active');
803
804 // adjust current preference content
805 jQuery('.vbo-sidepanel-colorscheme-current')
806 .attr('data-tooltiptext', vbo_mode_texts[set_mode])
807 .html(vbo_mode_icons[set_mode]);
808
809 // set/unset CSS files from DOM
810 for (let app_mode in vbo_css_modes) {
811 if (!vbo_css_modes.hasOwnProperty(app_mode) || !vbo_css_modes[app_mode]) {
812 continue;
813 }
814 if (app_mode == set_mode) {
815 // set this CSS file
816 jQuery('head').append('<link rel="stylesheet" id="' + vbo_css_base_id + app_mode + '" href="' + vbo_css_modes[app_mode] + '" media="all">');
817 } else {
818 // unset this CSS file
819 if (jQuery('link#' + vbo_css_base_id + app_mode).length) {
820 jQuery('link#' + vbo_css_base_id + app_mode).remove();
821 } else if (jQuery('link#' + vbo_css_base_id + app_mode + '-css').length) {
822 // WP framework may add "-css" as suffix to the given ID
823 jQuery('link#' + vbo_css_base_id + app_mode + '-css').remove();
824 }
825 // check if the VCM related CSS file should be unset too
826 if (jQuery('link#' + vcm_css_base_id + app_mode).length) {
827 jQuery('link#' + vcm_css_base_id + app_mode).remove();
828 } else if (jQuery('link#' + vcm_css_base_id + app_mode + '-css').length) {
829 // WP framework may add "-css" as suffix to the given ID
830 jQuery('link#' + vcm_css_base_id + app_mode + '-css').remove();
831 }
832 }
833 }
834
835 // close menu-list
836 jQuery('.vbo-sidepanel-colorscheme-list').removeClass('vbo-sidepanel-colorscheme-list-show');
837
838 // silently update configuration value
839 VBOCore.doAjax(
840 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=configuration.update'); ?>",
841 {
842 settings: {
843 appearance_pref: set_mode,
844 }
845 },
846 (success) => {
847 // do nothing
848 },
849 (error) => {
850 console.error(error);
851 }
852 );
853 });
854
855 });
856
857 /**
858 * Asks for confirmation to restore the default widgets map
859 */
860 function vboWidgetsRestoreMap() {
861 if (confirm(Joomla.JText._('VBO_WIDGETS_RESTDEFAULT'))) {
862 return true;
863 } else {
864 return false;
865 }
866 }
867
868 /**
869 * Adds a new section to the document
870 */
871 function vboWidgetsAddSection() {
872 var tot_sections = jQuery('.vbo-admin-widgets-section').length;
873 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), Joomla.JText._('VBO_WIDGETS_NEWSECT') + ' #' + (tot_sections + 1));
874 if (sect_name_new != null && sect_name_new != '') {
875 var html_section_new = '<div class="vbo-admin-widgets-section" id="vbo-admin-widgets-section-' + (tot_sections + 1) + '">';
876 html_section_new += ' <div class="vbo-admin-widgets-section-name" data-vbomanagewidgets="1">';
877 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
878 html_section_new += ' <span class="vbo-admin-widgets-section-name-val">' + sect_name_new + '</span>';
879 html_section_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-section-cmds">';
880 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditSection(this);"><?php VikBookingIcons::e('edit'); ?></span>';
881 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveSection(this);"><?php VikBookingIcons::e('trash'); ?></span>';
882 html_section_new += ' </div>';
883 html_section_new += ' </div>';
884 html_section_new += ' <div class="vbo-admin-widgets-container vbo-admin-widgets-container-addnew" data-vbomanagewidgets="1">';
885 html_section_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddContainer(this);">';
886 html_section_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
887 html_section_new += ' </div>';
888 html_section_new += ' </div>';
889 html_section_new += '</div>';
890 jQuery('.vbo-admin-widgets-section-addnew').before(html_section_new);
891
892 // update global map object
893 vbo_admin_widgets_map.sections.push({
894 name: sect_name_new,
895 containers: []
896 });
897
898 // trigger the save-map event
899 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
900 }
901 }
902
903 /**
904 * Prompts the new section name to update it
905 */
906 function vboWidgetsEditSection(elem) {
907 var cur_sect_name_elm = jQuery(elem).closest('.vbo-admin-widgets-section-name').find('.vbo-admin-widgets-section-name-val');
908 if (!cur_sect_name_elm || !cur_sect_name_elm.length) {
909 console.error('Could not find section to edit');
910 return false;
911 }
912 var cur_sect_name_val = cur_sect_name_elm.text();
913 // find current index of selected section in the map
914 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
915 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), cur_sect_name_val);
916 if (sect_name_new != null && sect_name_new != '') {
917 cur_sect_name_elm.text(sect_name_new);
918 // update global map object
919 vbo_admin_widgets_map.sections[cur_sect_index]['name'] = sect_name_new;
920 // trigger the save-map event
921 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
922 }
923 }
924
925 /**
926 * Asks for confirmation before removing the selected section
927 */
928 function vboWidgetsRemoveSection(elem) {
929 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
930 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
931 // remove section from document
932 jQuery(elem).closest('.vbo-admin-widgets-section').remove();
933 // update global map object
934 vbo_admin_widgets_map.sections.splice(cur_sect_index, 1);
935 // trigger the save-map event
936 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
937 }
938 }
939
940 /**
941 * Displays the modal window to create a new widgets container
942 */
943 function vboWidgetsAddContainer(elem) {
944 // update last section selected
945 vbo_admin_widgets_last_section = jQuery(elem).closest('.vbo-admin-widgets-section');
946 if (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length) {
947 // parent section not found
948 console.error('parent section not found for adding a container');
949 return false;
950 }
951 // turn update flag off
952 jQuery('#vbo-newcontainer-upd').val(0);
953 // display new container form
954 jQuery('.vbo-modal-widgets-newcontainer').show();
955 jQuery('.vbo-modal-footer-newcontainer').show();
956 // set new container form button
957 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('plus-circle'); ?> ' + Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
958 // set modal title
959 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
960 // display modal
961 vboOpenModalWidgets();
962 }
963
964 /**
965 * Adds or updates one widgets container in the document.
966 */
967 function vboWidgetsAddContainerToDoc() {
968 var mode = jQuery('#vbo-newcontainer-upd').val() > 0 ? 'update' : 'new';
969 if (mode == 'new' && (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length)) {
970 // parent section not found
971 console.error('parent section not found for adding a container');
972 return false;
973 }
974 if (mode == 'update' && (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length)) {
975 // current container not found
976 console.error('current container not found');
977 return false;
978 }
979
980 // get new container size and CSS class
981 var cont_size = jQuery('#vbo-newcontainer-size').val();
982 var cont_css = jQuery('#vbo-newcontainer-size').find('option:selected').attr('data-cssclass');
983 var cont_name = jQuery('#vbo-newcontainer-size').find('option:selected').text();
984 if (!cont_size || !cont_size.length || !cont_css.length) {
985 console.error('new container size missing');
986 alert(Joomla.JText._('VBO_WIDGETS_SELCONTSIZE'));
987 return false;
988 }
989
990 if (mode == 'update') {
991 // update container class, size and title
992 vbo_admin_widgets_last_container.removeClass().addClass('vbo-admin-widgets-container ' + cont_css).attr('data-vbowidgetcontsize', cont_size).find('.vbo-admin-widgets-container-name-val').text(cont_name);
993
994 // update global map object
995 var cur_cont_index = vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_admin_widgets_last_container);
996 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section'));
997 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['size'] = cont_size;
998
999 // trigger the save-map event
1000 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1001 } else {
1002 // update containers count for a better styling
1003 var all_sect_conts = vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
1004 var new_sect_conts = all_sect_conts.length + 1;
1005 all_sect_conts.attr('data-totcontainers', new_sect_conts);
1006
1007 // build new container
1008 var html_container_new = '<div class="vbo-admin-widgets-container ' + cont_css + '" data-vbowidgetcontsize="' + cont_size + '" data-totcontainers="' + new_sect_conts + '">';
1009 html_container_new += ' <div class="vbo-admin-widgets-container-name" data-vbomanagewidgets="1">';
1010 html_container_new += ' <span class="vbo-admin-widgets-container-name-val">' + cont_name + '</span>';
1011 html_container_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-container-cmds">';
1012 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditContainer(this);"><?php VikBookingIcons::e('edit'); ?></span>';
1013 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveContainer(this);"><?php VikBookingIcons::e('trash'); ?></span>';
1014 html_container_new += ' </div>';
1015 html_container_new += ' </div>';
1016 html_container_new += ' <div class="vbo-admin-widgets-widget vbo-admin-widgets-widget-addnew" data-vbomanagewidgets="1">';
1017 html_container_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddWidget(this);">';
1018 html_container_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
1019 html_container_new += ' </div>';
1020 html_container_new += ' </div>';
1021 html_container_new += '</div>';
1022
1023 // append new container HTML
1024 vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container-addnew').before(html_container_new);
1025
1026 // update global map object
1027 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_section);
1028 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].push({
1029 size: cont_size,
1030 widgets: []
1031 });
1032
1033 // trigger the save-map event
1034 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1035 }
1036
1037 // close modal window
1038 hideVboModalWidgets();
1039
1040 // unset last section and container
1041 vbo_admin_widgets_last_section = null;
1042 vbo_admin_widgets_last_container = null;
1043 }
1044
1045 /**
1046 * Displays the modal window for editing the selected container
1047 */
1048 function vboWidgetsEditContainer(elem) {
1049 // update last container selected
1050 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
1051 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1052 // parent container not found
1053 console.error('parent container not found');
1054 return false;
1055 }
1056 // turn update flag on
1057 jQuery('#vbo-newcontainer-upd').val(1);
1058 // set current container size
1059 jQuery('#vbo-newcontainer-size').val(vbo_admin_widgets_last_container.attr('data-vbowidgetcontsize')).trigger('change');
1060 // display edit container form
1061 jQuery('.vbo-modal-widgets-newcontainer').show();
1062 jQuery('.vbo-modal-footer-newcontainer').show();
1063 // set edit container form button
1064 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('check'); ?> ' + Joomla.JText._('VBO_WIDGETS_UPDWIDGCONT'));
1065 // set modal title
1066 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_EDITWIDGCONT'));
1067 // display modal
1068 vboOpenModalWidgets();
1069 }
1070
1071 /**
1072 * Asks for confirmation before removing the selected container
1073 */
1074 function vboWidgetsRemoveContainer(elem) {
1075 var all_sect_conts = jQuery(elem).closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
1076 var new_sect_conts = (all_sect_conts.length - 1);
1077 var cur_cont_index = all_sect_conts.index(jQuery(elem).closest('.vbo-admin-widgets-container'));
1078 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
1079 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
1080 // update containers count for a better styling
1081 all_sect_conts.attr('data-totcontainers', new_sect_conts);
1082 // remove container from document
1083 jQuery(elem).closest('.vbo-admin-widgets-container').remove();
1084 // update global map object
1085 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].splice(cur_cont_index, 1);
1086 // trigger the save-map event
1087 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1088 }
1089 }
1090
1091 /**
1092 * Displays the modal window to create a new widget
1093 */
1094 function vboWidgetsAddWidget(elem) {
1095 // update last container selected
1096 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
1097 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1098 // parent container not found
1099 console.error('parent container not found for adding a widget');
1100 return false;
1101 }
1102 // display new widget form
1103 jQuery('.vbo-modal-widgets-newwidget').show();
1104 jQuery('.vbo-modal-footer-newwidget').show();
1105 // unset any previously selected widget
1106 jQuery('#vbo-newwidget-id').val('');
1107 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected vbo-modal-widget-notselected');
1108 // set modal title
1109 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDNEWWIDG'));
1110 // display modal
1111 vboOpenModalWidgets();
1112 }
1113
1114 /**
1115 * Updates the description in the modal window for the selected widget
1116 */
1117 function vboWidgetSetNewDescr(widget_id) {
1118 // always empty the description box
1119 jQuery('.vbo-newwidget-descr').html('');
1120 if (!widget_id.length) {
1121 return '';
1122 }
1123 // seek for this widget id
1124 for (var i in vbo_admin_widgets_names) {
1125 if (!vbo_admin_widgets_names.hasOwnProperty(i)) {
1126 continue;
1127 }
1128 if (vbo_admin_widgets_names[i]['id'] == widget_id) {
1129 jQuery('.vbo-newwidget-descr').html(vbo_admin_widgets_names[i]['descr']);
1130 return vbo_admin_widgets_names[i]['descr'];
1131 }
1132 }
1133 return '';
1134 }
1135
1136 /**
1137 * Makes the current widget selected, ready to be added to the document
1138 */
1139 function vboWidgetsSelectWidget(widget_id) {
1140 if (!widget_id) {
1141 return false;
1142 }
1143
1144 // remove selected class from all widgets, add un-selected class
1145 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-notselected');
1146 // add selected class to the current widget
1147 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1148 // populate hidden field value
1149 jQuery('#vbo-newwidget-id').val(widget_id);
1150
1151 return true;
1152 }
1153
1154 /**
1155 * Adds the new selected widget to the document
1156 */
1157 function vboWidgetsAddWidgetToDoc(force_widget_id) {
1158 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1159 // parent container not found
1160 console.error('parent container not found for adding a container');
1161 return false;
1162 }
1163
1164 // get new widget id, name and descr
1165 var widget_id = null,
1166 widget_name = null,
1167 widget_descr = null;
1168 if (force_widget_id) {
1169 // plus button clicked on widget
1170 jQuery('#vbo-newwidget-id').val(force_widget_id);
1171 // remove selected class from all widgets, add un-selected class
1172 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-notselected');
1173 // add selected class to the current widget
1174 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1175 widget_id = force_widget_id;
1176 } else {
1177 // selected widget was clicked to be added
1178 widget_id = jQuery('#vbo-newwidget-id').val();
1179 }
1180 widget_name = jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').find('.vbo-modal-widget-name').text();
1181 if (!widget_id || !widget_id.length || !widget_name || !widget_name.length) {
1182 console.error('new widget id missing');
1183 return false;
1184 }
1185 // get and update the description for the currently selected widget
1186 widget_descr = vboWidgetSetNewDescr(widget_id);
1187
1188 // build new widget
1189 var html_widget_new = '<div class="vbo-admin-widgets-widget" data-vbowidgetid="' + widget_id + '">';
1190 html_widget_new += ' <div class="vbo-admin-widgets-widget-info" data-vbomanagewidgets="1">';
1191 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-inner">';
1192 html_widget_new += ' <div class="vbo-admin-widgets-widget-details">';
1193 html_widget_new += ' <span class="vbo-admin-widgets-widget-info-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
1194 html_widget_new += ' <h4 class="vbo-admin-widgets-widget-info-name">';
1195 html_widget_new += ' <span>' + widget_name + '</span>';
1196 html_widget_new += ' <span class="vbo-admin-widgets-widget-remove" onclick="vboWidgetsRemoveWidget(this);"><?php VikBookingIcons::e('trash'); ?></span>';
1197 html_widget_new += ' </h4>';
1198 html_widget_new += ' </div>';
1199 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-descr">' + widget_descr + '</div>';
1200 html_widget_new += ' </div>';
1201 html_widget_new += ' </div>';
1202 html_widget_new += ' <div class="vbo-admin-widgets-widget-output" style="display: none;"></div>';
1203 html_widget_new += '</div>';
1204
1205 // wrap the new HTML into a collection object
1206 var elem_widget_new = jQuery(html_widget_new);
1207
1208 // append new widget HTML
1209 vbo_admin_widgets_last_container.find('.vbo-admin-widgets-widget-addnew').before(elem_widget_new);
1210
1211 // update global map object
1212 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section'));
1213 var cur_cont_index = vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_admin_widgets_last_container);
1214 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].push(widget_id);
1215
1216 // trigger the save-map event
1217 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1218
1219 // close modal window
1220 hideVboModalWidgets();
1221
1222 // unset last container
1223 vbo_admin_widgets_last_container = null;
1224
1225 // populate widget output via AJAX
1226 vboWidgetsLoadWidgetContent(elem_widget_new, widget_id);
1227 }
1228
1229 /**
1230 * Asks for confirmation before removing the selected widget
1231 */
1232 function vboWidgetsRemoveWidget(elem) {
1233 var vbo_widget_elem = jQuery(elem).closest('.vbo-admin-widgets-widget');
1234 var cur_widg_id = vbo_widget_elem.attr('data-vbowidgetid');
1235 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-section'));
1236 var cur_cont_index = vbo_widget_elem.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-container'));
1237 var cur_widg_index = vbo_widget_elem.closest('.vbo-admin-widgets-container').find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-widget'));
1238 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
1239 // calculate widget instance index for its type
1240 var widget_instance_index = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + cur_widg_id + '"]').index(vbo_widget_elem);
1241
1242 // the widget method to call
1243 var call_method = 'removeInstance';
1244 // make a silent call for the widget in case it needs to perform actions when removing an instance
1245 VBOCore.doAjax(
1246 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1247 {
1248 widget_id: cur_widg_id,
1249 widget_instance: widget_instance_index,
1250 call: call_method,
1251 tmpl: "component"
1252 },
1253 (response) => {
1254 try {
1255 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1256 if (!obj_res.hasOwnProperty(call_method)) {
1257 console.error('Unexpected JSON response', obj_res);
1258 }
1259 } catch(err) {
1260 console.error('could not parse JSON response', err, response);
1261 }
1262 },
1263 (error) => {
1264 console.error(error.responseText);
1265 }
1266 );
1267
1268 // remove widget from document
1269 vbo_widget_elem.remove();
1270 // update global map object
1271 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].splice(cur_widg_index, 1);
1272 // trigger the save-map event
1273 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1274 }
1275 }
1276
1277 /**
1278 * Populates the content of the newly added widget.
1279 */
1280 function vboWidgetsLoadWidgetContent(container, widget_id) {
1281 if (!container || !container.find('.vbo-admin-widgets-widget-output').length) {
1282 console.error('Could not find new widget container');
1283 return false;
1284 }
1285
1286 // the widget method to call
1287 var call_method = 'render';
1288
1289 VBOCore.doAjax(
1290 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1291 {
1292 widget_id: widget_id,
1293 call: call_method,
1294 tmpl: "component"
1295 },
1296 (response) => {
1297 try {
1298 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1299 if (obj_res.hasOwnProperty(call_method)) {
1300 // populate new widget content
1301 container.find('.vbo-admin-widgets-widget-output').html(obj_res[call_method]);
1302 } else {
1303 console.error('Unexpected JSON response', obj_res);
1304 }
1305 } catch(err) {
1306 console.error('could not parse JSON response', err, response);
1307 }
1308 },
1309 (error) => {
1310 console.error(error.responseText);
1311 alert(Joomla.JText._('VBO_WIDGETS_ERRDISPWIDG'));
1312 }
1313 );
1314 }
1315 </script>
1316