PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.5
VikBooking Hotel Booking Engine & PMS v1.6.5
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.6.5, at admin/views/dashboard/tmpl/default_widgets.php

1,308 lines 56.0 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 vbo_css_modes = {
780 auto: vbo_css_base_uri.replace('%s', 'auto'),
781 dark: vbo_css_base_uri.replace('%s', 'dark'),
782 light: null,
783 };
784 let vbo_mode_texts = {
785 auto: Joomla.JText._('VBO_APPEARANCE_PREF_AUTO'),
786 dark: Joomla.JText._('VBO_APPEARANCE_PREF_DARK'),
787 light: Joomla.JText._('VBO_APPEARANCE_PREF_LIGHT'),
788 };
789 let vbo_mode_icons = {
790 auto: '<?php VikBookingIcons::e('magic') ?>',
791 dark: '<?php VikBookingIcons::e('moon') ?>',
792 light: '<?php VikBookingIcons::e('sun') ?>',
793 };
794
795 if (!vbo_css_modes.hasOwnProperty(set_mode)) {
796 return false;
797 }
798
799 // toggle active class
800 jQuery('.vbo-sidepanel-colorscheme-option').removeClass('vbo-sidepanel-colorscheme-option-active');
801 jQuery(this).addClass('vbo-sidepanel-colorscheme-option-active');
802
803 // adjust current preference content
804 jQuery('.vbo-sidepanel-colorscheme-current')
805 .attr('data-tooltiptext', vbo_mode_texts[set_mode])
806 .html(vbo_mode_icons[set_mode]);
807
808 // set/unset CSS files from DOM
809 for (let app_mode in vbo_css_modes) {
810 if (!vbo_css_modes.hasOwnProperty(app_mode) || !vbo_css_modes[app_mode]) {
811 continue;
812 }
813 if (app_mode == set_mode) {
814 // set this CSS file
815 jQuery('head').append('<link rel="stylesheet" id="' + vbo_css_base_id + app_mode + '" href="' + vbo_css_modes[app_mode] + '" media="all">');
816 } else {
817 // unset this CSS file
818 if (jQuery('link#' + vbo_css_base_id + app_mode).length) {
819 jQuery('link#' + vbo_css_base_id + app_mode).remove();
820 } else if (jQuery('link#' + vbo_css_base_id + app_mode + '-css').length) {
821 // WP framework may add "-css" as suffix to the given ID
822 jQuery('link#' + vbo_css_base_id + app_mode + '-css').remove();
823 }
824 }
825 }
826
827 // close menu-list
828 jQuery('.vbo-sidepanel-colorscheme-list').removeClass('vbo-sidepanel-colorscheme-list-show');
829
830 // silently update configuration value
831 VBOCore.doAjax(
832 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=configuration.update'); ?>",
833 {
834 settings: {
835 appearance_pref: set_mode,
836 }
837 },
838 (success) => {
839 // do nothing
840 },
841 (error) => {
842 console.error(error);
843 }
844 );
845 });
846
847 });
848
849 /**
850 * Asks for confirmation to restore the default widgets map
851 */
852 function vboWidgetsRestoreMap() {
853 if (confirm(Joomla.JText._('VBO_WIDGETS_RESTDEFAULT'))) {
854 return true;
855 } else {
856 return false;
857 }
858 }
859
860 /**
861 * Adds a new section to the document
862 */
863 function vboWidgetsAddSection() {
864 var tot_sections = jQuery('.vbo-admin-widgets-section').length;
865 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), Joomla.JText._('VBO_WIDGETS_NEWSECT') + ' #' + (tot_sections + 1));
866 if (sect_name_new != null && sect_name_new != '') {
867 var html_section_new = '<div class="vbo-admin-widgets-section" id="vbo-admin-widgets-section-' + (tot_sections + 1) + '">';
868 html_section_new += ' <div class="vbo-admin-widgets-section-name" data-vbomanagewidgets="1">';
869 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
870 html_section_new += ' <span class="vbo-admin-widgets-section-name-val">' + sect_name_new + '</span>';
871 html_section_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-section-cmds">';
872 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditSection(this);"><?php VikBookingIcons::e('edit'); ?></span>';
873 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveSection(this);"><?php VikBookingIcons::e('trash'); ?></span>';
874 html_section_new += ' </div>';
875 html_section_new += ' </div>';
876 html_section_new += ' <div class="vbo-admin-widgets-container vbo-admin-widgets-container-addnew" data-vbomanagewidgets="1">';
877 html_section_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddContainer(this);">';
878 html_section_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
879 html_section_new += ' </div>';
880 html_section_new += ' </div>';
881 html_section_new += '</div>';
882 jQuery('.vbo-admin-widgets-section-addnew').before(html_section_new);
883
884 // update global map object
885 vbo_admin_widgets_map.sections.push({
886 name: sect_name_new,
887 containers: []
888 });
889
890 // trigger the save-map event
891 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
892 }
893 }
894
895 /**
896 * Prompts the new section name to update it
897 */
898 function vboWidgetsEditSection(elem) {
899 var cur_sect_name_elm = jQuery(elem).closest('.vbo-admin-widgets-section-name').find('.vbo-admin-widgets-section-name-val');
900 if (!cur_sect_name_elm || !cur_sect_name_elm.length) {
901 console.error('Could not find section to edit');
902 return false;
903 }
904 var cur_sect_name_val = cur_sect_name_elm.text();
905 // find current index of selected section in the map
906 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
907 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), cur_sect_name_val);
908 if (sect_name_new != null && sect_name_new != '') {
909 cur_sect_name_elm.text(sect_name_new);
910 // update global map object
911 vbo_admin_widgets_map.sections[cur_sect_index]['name'] = sect_name_new;
912 // trigger the save-map event
913 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
914 }
915 }
916
917 /**
918 * Asks for confirmation before removing the selected section
919 */
920 function vboWidgetsRemoveSection(elem) {
921 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
922 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
923 // remove section from document
924 jQuery(elem).closest('.vbo-admin-widgets-section').remove();
925 // update global map object
926 vbo_admin_widgets_map.sections.splice(cur_sect_index, 1);
927 // trigger the save-map event
928 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
929 }
930 }
931
932 /**
933 * Displays the modal window to create a new widgets container
934 */
935 function vboWidgetsAddContainer(elem) {
936 // update last section selected
937 vbo_admin_widgets_last_section = jQuery(elem).closest('.vbo-admin-widgets-section');
938 if (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length) {
939 // parent section not found
940 console.error('parent section not found for adding a container');
941 return false;
942 }
943 // turn update flag off
944 jQuery('#vbo-newcontainer-upd').val(0);
945 // display new container form
946 jQuery('.vbo-modal-widgets-newcontainer').show();
947 jQuery('.vbo-modal-footer-newcontainer').show();
948 // set new container form button
949 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('plus-circle'); ?> ' + Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
950 // set modal title
951 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
952 // display modal
953 vboOpenModalWidgets();
954 }
955
956 /**
957 * Adds or updates one widgets container in the document.
958 */
959 function vboWidgetsAddContainerToDoc() {
960 var mode = jQuery('#vbo-newcontainer-upd').val() > 0 ? 'update' : 'new';
961 if (mode == 'new' && (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length)) {
962 // parent section not found
963 console.error('parent section not found for adding a container');
964 return false;
965 }
966 if (mode == 'update' && (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length)) {
967 // current container not found
968 console.error('current container not found');
969 return false;
970 }
971
972 // get new container size and CSS class
973 var cont_size = jQuery('#vbo-newcontainer-size').val();
974 var cont_css = jQuery('#vbo-newcontainer-size').find('option:selected').attr('data-cssclass');
975 var cont_name = jQuery('#vbo-newcontainer-size').find('option:selected').text();
976 if (!cont_size || !cont_size.length || !cont_css.length) {
977 console.error('new container size missing');
978 alert(Joomla.JText._('VBO_WIDGETS_SELCONTSIZE'));
979 return false;
980 }
981
982 if (mode == 'update') {
983 // update container class, size and title
984 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);
985
986 // update global map object
987 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);
988 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'));
989 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['size'] = cont_size;
990
991 // trigger the save-map event
992 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
993 } else {
994 // update containers count for a better styling
995 var all_sect_conts = vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
996 var new_sect_conts = all_sect_conts.length + 1;
997 all_sect_conts.attr('data-totcontainers', new_sect_conts);
998
999 // build new container
1000 var html_container_new = '<div class="vbo-admin-widgets-container ' + cont_css + '" data-vbowidgetcontsize="' + cont_size + '" data-totcontainers="' + new_sect_conts + '">';
1001 html_container_new += ' <div class="vbo-admin-widgets-container-name" data-vbomanagewidgets="1">';
1002 html_container_new += ' <span class="vbo-admin-widgets-container-name-val">' + cont_name + '</span>';
1003 html_container_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-container-cmds">';
1004 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditContainer(this);"><?php VikBookingIcons::e('edit'); ?></span>';
1005 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveContainer(this);"><?php VikBookingIcons::e('trash'); ?></span>';
1006 html_container_new += ' </div>';
1007 html_container_new += ' </div>';
1008 html_container_new += ' <div class="vbo-admin-widgets-widget vbo-admin-widgets-widget-addnew" data-vbomanagewidgets="1">';
1009 html_container_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddWidget(this);">';
1010 html_container_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
1011 html_container_new += ' </div>';
1012 html_container_new += ' </div>';
1013 html_container_new += '</div>';
1014
1015 // append new container HTML
1016 vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container-addnew').before(html_container_new);
1017
1018 // update global map object
1019 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_section);
1020 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].push({
1021 size: cont_size,
1022 widgets: []
1023 });
1024
1025 // trigger the save-map event
1026 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1027 }
1028
1029 // close modal window
1030 hideVboModalWidgets();
1031
1032 // unset last section and container
1033 vbo_admin_widgets_last_section = null;
1034 vbo_admin_widgets_last_container = null;
1035 }
1036
1037 /**
1038 * Displays the modal window for editing the selected container
1039 */
1040 function vboWidgetsEditContainer(elem) {
1041 // update last container selected
1042 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
1043 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1044 // parent container not found
1045 console.error('parent container not found');
1046 return false;
1047 }
1048 // turn update flag on
1049 jQuery('#vbo-newcontainer-upd').val(1);
1050 // set current container size
1051 jQuery('#vbo-newcontainer-size').val(vbo_admin_widgets_last_container.attr('data-vbowidgetcontsize')).trigger('change');
1052 // display edit container form
1053 jQuery('.vbo-modal-widgets-newcontainer').show();
1054 jQuery('.vbo-modal-footer-newcontainer').show();
1055 // set edit container form button
1056 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('check'); ?> ' + Joomla.JText._('VBO_WIDGETS_UPDWIDGCONT'));
1057 // set modal title
1058 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_EDITWIDGCONT'));
1059 // display modal
1060 vboOpenModalWidgets();
1061 }
1062
1063 /**
1064 * Asks for confirmation before removing the selected container
1065 */
1066 function vboWidgetsRemoveContainer(elem) {
1067 var all_sect_conts = jQuery(elem).closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
1068 var new_sect_conts = (all_sect_conts.length - 1);
1069 var cur_cont_index = all_sect_conts.index(jQuery(elem).closest('.vbo-admin-widgets-container'));
1070 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
1071 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
1072 // update containers count for a better styling
1073 all_sect_conts.attr('data-totcontainers', new_sect_conts);
1074 // remove container from document
1075 jQuery(elem).closest('.vbo-admin-widgets-container').remove();
1076 // update global map object
1077 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].splice(cur_cont_index, 1);
1078 // trigger the save-map event
1079 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1080 }
1081 }
1082
1083 /**
1084 * Displays the modal window to create a new widget
1085 */
1086 function vboWidgetsAddWidget(elem) {
1087 // update last container selected
1088 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
1089 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1090 // parent container not found
1091 console.error('parent container not found for adding a widget');
1092 return false;
1093 }
1094 // display new widget form
1095 jQuery('.vbo-modal-widgets-newwidget').show();
1096 jQuery('.vbo-modal-footer-newwidget').show();
1097 // unset any previously selected widget
1098 jQuery('#vbo-newwidget-id').val('');
1099 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected vbo-modal-widget-notselected');
1100 // set modal title
1101 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDNEWWIDG'));
1102 // display modal
1103 vboOpenModalWidgets();
1104 }
1105
1106 /**
1107 * Updates the description in the modal window for the selected widget
1108 */
1109 function vboWidgetSetNewDescr(widget_id) {
1110 // always empty the description box
1111 jQuery('.vbo-newwidget-descr').html('');
1112 if (!widget_id.length) {
1113 return '';
1114 }
1115 // seek for this widget id
1116 for (var i in vbo_admin_widgets_names) {
1117 if (!vbo_admin_widgets_names.hasOwnProperty(i)) {
1118 continue;
1119 }
1120 if (vbo_admin_widgets_names[i]['id'] == widget_id) {
1121 jQuery('.vbo-newwidget-descr').html(vbo_admin_widgets_names[i]['descr']);
1122 return vbo_admin_widgets_names[i]['descr'];
1123 }
1124 }
1125 return '';
1126 }
1127
1128 /**
1129 * Makes the current widget selected, ready to be added to the document
1130 */
1131 function vboWidgetsSelectWidget(widget_id) {
1132 if (!widget_id) {
1133 return false;
1134 }
1135
1136 // remove selected class from all widgets, add un-selected class
1137 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-notselected');
1138 // add selected class to the current widget
1139 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1140 // populate hidden field value
1141 jQuery('#vbo-newwidget-id').val(widget_id);
1142
1143 return true;
1144 }
1145
1146 /**
1147 * Adds the new selected widget to the document
1148 */
1149 function vboWidgetsAddWidgetToDoc(force_widget_id) {
1150 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1151 // parent container not found
1152 console.error('parent container not found for adding a container');
1153 return false;
1154 }
1155
1156 // get new widget id, name and descr
1157 var widget_id = null,
1158 widget_name = null,
1159 widget_descr = null;
1160 if (force_widget_id) {
1161 // plus button clicked on widget
1162 jQuery('#vbo-newwidget-id').val(force_widget_id);
1163 // remove selected class from all widgets, add un-selected class
1164 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-notselected');
1165 // add selected class to the current widget
1166 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1167 widget_id = force_widget_id;
1168 } else {
1169 // selected widget was clicked to be added
1170 widget_id = jQuery('#vbo-newwidget-id').val();
1171 }
1172 widget_name = jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').find('.vbo-modal-widget-name').text();
1173 if (!widget_id || !widget_id.length || !widget_name || !widget_name.length) {
1174 console.error('new widget id missing');
1175 return false;
1176 }
1177 // get and update the description for the currently selected widget
1178 widget_descr = vboWidgetSetNewDescr(widget_id);
1179
1180 // build new widget
1181 var html_widget_new = '<div class="vbo-admin-widgets-widget" data-vbowidgetid="' + widget_id + '">';
1182 html_widget_new += ' <div class="vbo-admin-widgets-widget-info" data-vbomanagewidgets="1">';
1183 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-inner">';
1184 html_widget_new += ' <div class="vbo-admin-widgets-widget-details">';
1185 html_widget_new += ' <span class="vbo-admin-widgets-widget-info-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
1186 html_widget_new += ' <h4 class="vbo-admin-widgets-widget-info-name">';
1187 html_widget_new += ' <span>' + widget_name + '</span>';
1188 html_widget_new += ' <span class="vbo-admin-widgets-widget-remove" onclick="vboWidgetsRemoveWidget(this);"><?php VikBookingIcons::e('trash'); ?></span>';
1189 html_widget_new += ' </h4>';
1190 html_widget_new += ' </div>';
1191 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-descr">' + widget_descr + '</div>';
1192 html_widget_new += ' </div>';
1193 html_widget_new += ' </div>';
1194 html_widget_new += ' <div class="vbo-admin-widgets-widget-output" style="display: none;"></div>';
1195 html_widget_new += '</div>';
1196
1197 // wrap the new HTML into a collection object
1198 var elem_widget_new = jQuery(html_widget_new);
1199
1200 // append new widget HTML
1201 vbo_admin_widgets_last_container.find('.vbo-admin-widgets-widget-addnew').before(elem_widget_new);
1202
1203 // update global map object
1204 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'));
1205 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);
1206 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].push(widget_id);
1207
1208 // trigger the save-map event
1209 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1210
1211 // close modal window
1212 hideVboModalWidgets();
1213
1214 // unset last container
1215 vbo_admin_widgets_last_container = null;
1216
1217 // populate widget output via AJAX
1218 vboWidgetsLoadWidgetContent(elem_widget_new, widget_id);
1219 }
1220
1221 /**
1222 * Asks for confirmation before removing the selected widget
1223 */
1224 function vboWidgetsRemoveWidget(elem) {
1225 var vbo_widget_elem = jQuery(elem).closest('.vbo-admin-widgets-widget');
1226 var cur_widg_id = vbo_widget_elem.attr('data-vbowidgetid');
1227 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-section'));
1228 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'));
1229 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'));
1230 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
1231 // calculate widget instance index for its type
1232 var widget_instance_index = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + cur_widg_id + '"]').index(vbo_widget_elem);
1233
1234 // the widget method to call
1235 var call_method = 'removeInstance';
1236 // make a silent call for the widget in case it needs to perform actions when removing an instance
1237 VBOCore.doAjax(
1238 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1239 {
1240 widget_id: cur_widg_id,
1241 widget_instance: widget_instance_index,
1242 call: call_method,
1243 tmpl: "component"
1244 },
1245 (response) => {
1246 try {
1247 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1248 if (!obj_res.hasOwnProperty(call_method)) {
1249 console.error('Unexpected JSON response', obj_res);
1250 }
1251 } catch(err) {
1252 console.error('could not parse JSON response', err, response);
1253 }
1254 },
1255 (error) => {
1256 console.error(error.responseText);
1257 }
1258 );
1259
1260 // remove widget from document
1261 vbo_widget_elem.remove();
1262 // update global map object
1263 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].splice(cur_widg_index, 1);
1264 // trigger the save-map event
1265 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1266 }
1267 }
1268
1269 /**
1270 * Populates the content of the newly added widget.
1271 */
1272 function vboWidgetsLoadWidgetContent(container, widget_id) {
1273 if (!container || !container.find('.vbo-admin-widgets-widget-output').length) {
1274 console.error('Could not find new widget container');
1275 return false;
1276 }
1277
1278 // the widget method to call
1279 var call_method = 'render';
1280
1281 VBOCore.doAjax(
1282 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1283 {
1284 widget_id: widget_id,
1285 call: call_method,
1286 tmpl: "component"
1287 },
1288 (response) => {
1289 try {
1290 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1291 if (obj_res.hasOwnProperty(call_method)) {
1292 // populate new widget content
1293 container.find('.vbo-admin-widgets-widget-output').html(obj_res[call_method]);
1294 } else {
1295 console.error('Unexpected JSON response', obj_res);
1296 }
1297 } catch(err) {
1298 console.error('could not parse JSON response', err, response);
1299 }
1300 },
1301 (error) => {
1302 console.error(error.responseText);
1303 alert(Joomla.JText._('VBO_WIDGETS_ERRDISPWIDG'));
1304 }
1305 );
1306 }
1307 </script>
1308