PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / admin / layouts / taskmanager / list / tasks.php

tasks.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/layouts/taskmanager/list/tasks.php

400 lines 16.6 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 core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2025 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Obtain vars from arguments received in the layout file.
16 *
17 * @var array $data The data for rendering the tasks of given areas within a list.
18 */
19 extract($displayData);
20
21 // get the task area IDs
22 $areaIds = [];
23
24 if (is_array($data['area_ids'] ?? null)) {
25 $areaIds = $data['area_ids'];
26 }
27
28 if (!$areaIds) {
29 // we need to make the query return no results with an empty area ID
30 $areaIds = [0];
31 }
32
33 // get fetching start and limit values
34 $start = abs(intval($data['start'] ?? 0));
35 $limit = abs(intval($data['limit'] ?? 10));
36
37 // get the filters for rendering the area tasks
38 $filters = (array) ($data['filters'] ?? []);
39
40 // save current filters in the user state
41 JFactory::getApplication()->setUserState('vbo.tm.filters', $filters);
42
43 // access the task manager object
44 $taskManager = VBOFactory::getTaskManager();
45
46 // get the list of tasks according to filters, by always forcing/injecting the area IDs
47 $tasks = VBOTaskModelTask::getInstance()->filterItems(array_merge($filters, ['id_areas' => $areaIds]), $start, $limit);
48
49 foreach ($tasks as $taskRecord) {
50 // wrap task record into a registry
51 $task = VBOTaskTaskregistry::getInstance((array) $taskRecord);
52
53 // load task tags
54 $tags = $task->getTags() ? $task->getTagRecords() : [];
55
56 ?>
57 <div class="vbo-tm-list-task-row" data-task-id="<?php echo $task->getID(); ?>" data-area-id="<?php echo $task->getAreaID(); ?>">
58
59 <div class="vbo-tm-list-task-cell edit-trigger" data-type="id">
60 <span><?php VikBookingIcons::e('hashtag'); ?> <?php echo $task->getID(); ?></span>
61 </div>
62
63 <div class="vbo-tm-list-task-cell" data-type="title">
64 <a href="JavaScript: void(0);" class="edit-trigger"><?php echo $task->getTitle(); ?></a>
65 <div class="secondary">
66 <small><?php echo JHtml::fetch('date.relative', $task->get('modifiedon') ?: $task->get('createdon')); ?></small>
67 </div>
68 </div>
69
70 <div class="vbo-tm-list-task-cell" data-type="assignees">
71 <?php
72 foreach ($task->getAssigneeDetails() as $operator) {
73 ?>
74 <span class="vbo-tm-list-area-task-assignee vbo-tm-task-assignee">
75 <span class="vbo-tm-list-area-task-assignee-avatar vbo-tm-task-assignee-avatar" title="<?php echo JHtml::fetch('esc_attr', $operator['name']); ?>">
76 <?php
77 if (!empty($operator['img_uri'])) {
78 ?>
79 <img src="<?php echo $operator['img_uri']; ?>" alt="<?php echo JHtml::fetch('esc_attr', $operator['initials']); ?>" decoding="async" loading="lazy" />
80 <?php
81 } else {
82 ?>
83 <span><?php echo $operator['initials']; ?></span>
84 <?php
85 }
86 ?>
87 </span>
88 </span>
89 <?php
90 }
91 ?>
92 </div>
93
94 <div class="vbo-tm-list-task-cell" data-type="due">
95 <?php if ($dueDate = $task->getDueDate()): ?>
96 <div><?php echo JHtml::fetch('date', $dueDate, 'd F Y'); ?></div>
97 <div class="secondary"><small><?php echo JHtml::fetch('date', $dueDate, 'H:i'); ?></small></div>
98 <?php endif; ?>
99 </div>
100
101 <div class="vbo-tm-list-task-cell" data-type="status">
102 <?php
103 if ($taskManager->statusTypeExists($task->getStatus())) {
104 $status = $taskManager->getStatusTypeInstance($task->getStatus());
105 echo JHtml::fetch('vbohtml.taskmanager.status', $status);
106 }
107
108 if ($task->get('hasUnreadMessages', false)): ?>
109 <a href="javascript:void(0)" class="unread-message-dot mini edit-trigger">
110 <?php VikBookingIcons::e('comment'); ?>
111 </a>
112 <?php endif; ?>
113 </div>
114
115 <div class="vbo-tm-list-task-cell" data-type="id_order">
116
117 <div class="order-summary-flex">
118
119 <?php
120 if ($task->getBookingId() && $bookingElement = $task->buildBookingElement()) {
121 if (!empty($bookingElement['img'])) {
122 $img = '<img src="' . $bookingElement['img'] . '" class="vbo-booking-badge-avatar" decoding="async" loading="lazy" />';
123 } else {
124 $img = '<span class="vbo-booking-badge-avatar"><i class="' . VikBookingIcons::i($bookingElement['icon_class'] ?? 'hotel') . '"></i></span>';
125 }
126
127 $img = '<div class="see-booking-details" data-bid="' . $task->getBookingId() . '">'
128 . $img
129 . '<i class="' . VikBookingIcons::i('eye') . ' effect"></i>'
130 . '</div>';
131
132 $bookingText = $bookingElement['text'] . ' #' . $bookingElement['id'];
133 } else {
134 $img = '<span class="vbo-booking-badge-avatar edit-trigger"><i class="' . VikBookingIcons::i('plus') . '"></i></span>';
135 $bookingText = '<em>' . JText::translate('VBO_UNASSIGNED') . '</em>';
136 }
137 ?>
138
139 <?php echo $img; ?>
140
141 <div class="order-room-booking-details">
142 <?php if ($task->getListingId()): ?>
143 <div class="order-room"><?php echo $task->getListingName($task->getListingId()); ?></div>
144 <?php endif; ?>
145
146 <div class="order-booking"><?php echo $bookingText; ?></div>
147 </div>
148
149 </div>
150
151 </div>
152
153 <div class="vbo-tm-list-task-cell" data-type="id_area">
154 <span><?php echo $task->getAreaName($task->getAreaID()); ?></span>
155 </div>
156
157 <div class="vbo-tm-list-task-cell" data-type="tags">
158 <?php
159 if ($tags) {
160 ?>
161 <div class="vbo-tm-list-task-tags">
162 <?php
163 foreach ($tags as $tag) {
164 $tag = (array) $tag;
165 ?>
166 <span class="vbo-tm-task-tag vbo-tm-color <?php echo $tag['color']; ?>"><?php echo $tag['name']; ?></span>
167 <?php
168 }
169 ?>
170 </div>
171 <?php
172 }
173 ?>
174 </div>
175
176 </div>
177 <?php
178 }
179
180 if (!$tasks) {
181 ?>
182 <p class="info" data-no-results="1"><?php echo !$start ? JText::translate('VBO_NO_RECORDS_FOUND') : JText::translate('VBO_NO_MORE_RECORDS'); ?></p>
183 <?php
184 }
185 ?>
186
187 <script type="text/javascript">
188
189 jQuery(function($) {
190
191 /**
192 * Register listeners for editing an existing task.
193 */
194 document
195 .querySelectorAll('.vbo-tm-list-task-row')
196 .forEach((taskElement) => {
197 if (taskElement.clickListener) {
198 // listener added already
199 return;
200 }
201
202 // get the clicked task and area IDs
203 const taskId = taskElement.getAttribute('data-task-id');
204 const areaId = taskElement.getAttribute('data-area-id');
205
206 // build the click-able elements
207 let clickableElements = taskElement.querySelectorAll('.edit-trigger');
208
209 clickableElements.forEach((element) => {
210 element.addEventListener('click', () => {
211 // define the modal delete button
212 let delete_btn = jQuery('<button></button>')
213 .attr('type', 'button')
214 .addClass('btn btn-danger')
215 .text(<?php echo json_encode(JText::translate('VBELIMINA')); ?>)
216 .on('click', function() {
217 if (!confirm(<?php echo json_encode(JText::translate('VBDELCONFIRM')); ?>)) {
218 return false;
219 }
220
221 // disable button to prevent double submissions
222 let submit_btn = jQuery(this);
223 submit_btn.prop('disabled', true);
224
225 // start loading animation
226 VBOCore.emitEvent('vbo-tm-edittask-loading');
227
228 // make the request
229 VBOCore.doAjax(
230 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=taskmanager.deleteTask'); ?>",
231 {
232 data: {
233 id: taskId,
234 },
235 },
236 (resp) => {
237 // trigger filters-changed event on success
238 VBOCore.emitEvent('vbo-tm-filters-changed', {
239 filters: vboTmFilters,
240 });
241
242 // dismiss the modal
243 VBOCore.emitEvent('vbo-tm-edittask-dismiss');
244 },
245 (error) => {
246 // display error message
247 alert(error.responseText);
248
249 // re-enable submit button
250 submit_btn.prop('disabled', false);
251
252 // stop loading
253 VBOCore.emitEvent('vbo-tm-edittask-loading');
254 }
255 );
256 });
257
258 // define the modal save button
259 let save_btn = jQuery('<button></button>')
260 .attr('type', 'button')
261 .addClass('btn btn-success')
262 .text(<?php echo json_encode(JText::translate('VBSAVE')); ?>)
263 .on('click', function() {
264 // disable button to prevent double submissions
265 let submit_btn = jQuery(this);
266 submit_btn.prop('disabled', true);
267
268 // start loading animation
269 VBOCore.emitEvent('vbo-tm-edittask-loading');
270
271 // get form data
272 const taskForm = new FormData(document.querySelector('#vbo-tm-task-manage-form'));
273
274 // build query parameters for the request
275 let qpRequest = new URLSearchParams(taskForm);
276
277 // make sure the request always includes the assignees query parameter, even if the list is empty
278 if (!qpRequest.has('data[assignees][]')) {
279 qpRequest.append('data[assignees][]', []);
280 }
281
282 // make sure the request always includes the tags query parameter, even if the list is empty
283 if (!qpRequest.has('data[tags][]')) {
284 qpRequest.append('data[tags][]', []);
285 }
286
287 // make the request
288 VBOCore.doAjax(
289 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=taskmanager.updateTask'); ?>",
290 qpRequest.toString(),
291 (resp) => {
292 // trigger filters-changed event on success
293 VBOCore.emitEvent('vbo-tm-filters-changed', {
294 filters: vboTmFilters,
295 });
296
297 // dismiss the modal
298 VBOCore.emitEvent('vbo-tm-edittask-dismiss');
299 },
300 (error) => {
301 // display error message
302 alert(error.responseText);
303
304 // re-enable submit button
305 submit_btn.prop('disabled', false);
306
307 // stop loading
308 VBOCore.emitEvent('vbo-tm-edittask-loading');
309 }
310 );
311 });
312
313 // display modal
314 let modalBody = VBOCore.displayModal({
315 suffix: 'tm_edittask_modal',
316 title: <?php echo json_encode(JText::translate('VBO_TASK')); ?> + ' #' + taskId,
317 extra_class: 'vbo-modal-rounded vbo-modal-taller vbo-modal-large',
318 body_prepend: true,
319 lock_scroll: true,
320 escape_dismiss: false,
321 footer_left: delete_btn,
322 footer_right: save_btn,
323 loading_event: 'vbo-tm-edittask-loading',
324 dismiss_event: 'vbo-tm-edittask-dismiss',
325 });
326
327 // start loading animation
328 VBOCore.emitEvent('vbo-tm-edittask-loading');
329
330 // make the request
331 VBOCore.doAjax(
332 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=taskmanager.renderLayout'); ?>",
333 {
334 type: 'tasks.managetask',
335 data: {
336 task_id: taskId,
337 area_id: areaId,
338 form_id: 'vbo-tm-task-manage-form',
339 },
340 },
341 (resp) => {
342 // stop loading
343 VBOCore.emitEvent('vbo-tm-edittask-loading');
344
345 try {
346 // decode the response (if needed), and append the content to the modal body
347 let obj_res = typeof resp === 'string' ? JSON.parse(resp) : resp;
348 modalBody.append(obj_res['html']);
349 } catch (err) {
350 console.error('Error decoding the response', err, resp);
351 }
352 },
353 (error) => {
354 // display error message
355 alert(error.responseText);
356
357 // stop loading
358 VBOCore.emitEvent('vbo-tm-edittask-loading');
359 }
360 );
361 });
362 });
363
364 // turn flag on for listener set
365 taskElement.clickListener = true;
366 });
367
368 /**
369 * Register listeners for display the reservation details.
370 */
371 document
372 .querySelectorAll('.see-booking-details[data-bid]')
373 .forEach((bookingEl) => {
374 if (bookingEl.clickListener) {
375 // listener added already
376 return;
377 }
378
379 // get the clicked booking ID
380 const bookingId = bookingEl.getAttribute('data-bid');
381
382 bookingEl.addEventListener('click', () => {
383 VBOCore.handleDisplayWidgetNotification({
384 widget_id: 'booking_details',
385 }, {
386 booking_id: bookingId,
387 modal_options: {
388 body_prepend: false,
389 enlargeable: false,
390 minimizeable: false,
391 },
392 });
393 });
394
395 // turn flag on for listener set
396 bookingEl.clickListener = true;
397 });
398 });
399
400 </script>