1var selectedUserId = null; 2var selectedDate = null; 3var WAcalendar = null; 4 5$(document).ready(function () { 6 var $menu = $("#dynamic-menu"); 7 if ($menu.length === 0) { 8 return; // Exit if menu not found 9 } 10 $menu.addClass("d-none"); 11 var $menuItems = $menu.children("li"); 12 // Load usage counts and pinned states from localStorage 13 var usageCounts = JSON.parse(localStorage.getItem("menuUsageCounts")) || {}; 14 var pinnedItems = JSON.parse(localStorage.getItem("menuPinnedItems")) || {}; 15 // Function to get a unique key for each menu item 16 function getMenuItemKey($item) { 17 if (!$item || !$item.length) { 18 return null; 19 } 20 var text = $item.find("a div").text().trim(); 21 if (text) return text; 22 var classes = $item.attr("class"); 23 if (classes) { 24 var classList = classes.split(/\s+/); 25 for (var i = 0; i < classList.length; i++) { 26 if (classList[i] !== "menu-item" && classList[i] !== "active") { 27 return classList[i]; 28 } 29 } 30 } 31 var href = $item.find("a").attr("href"); 32 if (href) return href; 33 return null; 34 } 35 // Initialize counts and pinned states if not present 36 $menuItems.each(function () { 37 var key = getMenuItemKey($(this)); 38 if (key) { 39 if (!(key in usageCounts)) { 40 usageCounts[key] = 0; 41 } 42 if (!(key in pinnedItems)) { 43 pinnedItems[key] = false; 44 } 45 } 46 }); 47 // Function to reorder menu items 48 function reorderMenu() { 49 $menu.css("visibility", "hidden"); 50 var pinnedMenuItems = $menuItems 51 .filter(function () { 52 var key = getMenuItemKey($(this)); 53 return key && pinnedItems[key]; 54 }) 55 .detach(); 56 var unpinnedMenuItems = $menuItems 57 .filter(function () { 58 var key = getMenuItemKey($(this)); 59 return key && !pinnedItems[key]; 60 }) 61 .detach() 62 .sort(function (a, b) { 63 var keyA = getMenuItemKey($(a)); 64 var keyB = getMenuItemKey($(b)); 65 return keyA && keyB 66 ? (usageCounts[keyB] || 0) - (usageCounts[keyA] || 0) 67 : 0; 68 }); 69 $menu 70 .append(pinnedMenuItems) 71 .append(unpinnedMenuItems) 72 .css("visibility", "visible"); 73 } 74 // Initial ordering 75 reorderMenu(); 76 // Add click event listeners to menu items 77 $menuItems.find("> a").on("click", function (e) { 78 var key = getMenuItemKey($(this).parent()); 79 if (key) { 80 usageCounts[key] = (usageCounts[key] || 0) + 1; 81 localStorage.setItem( 82 "menuUsageCounts", 83 JSON.stringify(usageCounts) 84 ); 85 } 86 }); 87 // Add pin/unpin functionality 88 $menuItems.each(function () { 89 var $item = $(this); 90 var key = getMenuItemKey($item); 91 var $menuLink = $item.find("> a.menu-link"); 92 var $pinIcon = $('<i class="bx bx-pin pin-icon"></i>').appendTo( 93 $menuLink 94 ); 95 $pinIcon.on("click", function (e) { 96 e.preventDefault(); 97 e.stopPropagation(); 98 pinnedItems[key] = !pinnedItems[key]; 99 localStorage.setItem( 100 "menuPinnedItems", 101 JSON.stringify(pinnedItems) 102 ); 103 $item.toggleClass("pinned"); 104 $(this).toggleClass("bx-pin").toggleClass("bxs-pin text-warning"); 105 reorderMenu(); 106 }); 107 if (pinnedItems[key]) { 108 $item.addClass("pinned"); 109 $pinIcon.removeClass("bx-pin").addClass("bxs-pin text-warning"); 110 } 111 }); 112 // Implement a decay mechanism 113 function decayUsageCounts() { 114 var changed = false; 115 $.each(usageCounts, function (key, value) { 116 if (value > 0 && !pinnedItems[key]) { 117 usageCounts[key] = Math.max(0, value - 1); 118 changed = true; 119 } 120 }); 121 if (changed) { 122 localStorage.setItem( 123 "menuUsageCounts", 124 JSON.stringify(usageCounts) 125 );
126 reorderMenu(); 127 } 128 } 129 // Call decay function daily 130 var DECAY_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours in milliseconds 131 var lastDecayTime = localStorage.getItem("lastDecayTime") || 0; 132 var currentTime = Date.now(); 133 if (currentTime - lastDecayTime > DECAY_INTERVAL) { 134 decayUsageCounts(); 135 localStorage.setItem("lastDecayTime", currentTime.toString()); 136 } 137 $menu.css("opacity", 0).removeClass("d-none").animate({ opacity: 1 }, 500); 138}); 139("use strict"); 140toastr.options = { 141 positionClass: toastPosition, 142 timeOut: parseFloat(toastTimeOut) * 1000, 143 showDuration: "300", 144 hideDuration: "1000", 145 extendedTimeOut: "1000", 146 progressBar: true, 147 closeButton: true, 148}; 149var urlPrefix = window.location.pathname.split("/")[1]; 150$(document).ready(function () { 151 if ($(".js-example-basic-multiple").length) { 152 $(".js-example-basic-multiple").select2(); 153 } 154 155 if ($("#plan_id").length) { 156 $("#plan_id").select2(); 157 } 158 159 if ($("#filter_plans").length) { 160 $("#filter_plans").select2(); 161 } 162 163 if ($("#filter_by_users").length) { 164 $("#filter_by_users").select2(); 165 } 166 167 if ($("#user_id").length) { 168 $("#user_id").select2(); 169 } 170 171 if ($("#staff_ids").length) { 172 $("#staff_ids").select2(); 173 } 174 175 if ($("#staff_ids_edit").length) { 176 $("#staff_ids_edit").select2(); 177 } 178}); 179 180 181$(document).on("click", ".delete-invoice", function (e) { 182 e.preventDefault(); 183 var id = $(this).data("id"); 184 var type = $(this).data("type"); 185 var reload = $(this).data("reload") === true; // Simplified the reload condition 186 var tableID = $(this).data("table") || "table"; 187 // Map types to their respective actions and API routes 188 var actions = { 189 default: "delete", 190 }; 191 var typeMappings = { 192 default: type, 193 }; 194 var destroy = actions[type] || actions["default"]; 195 type = typeMappings[type] || typeMappings["default"]; 196 var urlPrefix = window.location.pathname.split("/")[1]; 197 198 // Show confirmation modal 199 $("#deleteModal").modal("show"); 200 $("#deleteModal").off("click", "#confirmDelete"); 201 // On confirmation click 202 $("#deleteModal").on("click", "#confirmDelete", function () { 203 $("#confirmDelete").html(label_please_wait).attr("disabled", true); 204 // Perform the AJAX request 205 $.ajax({ 206 url: `/${urlPrefix}/${type}/${destroy}/${id}`, 207 type: "DELETE", 208 headers: { 209 "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval 210 }, 211 success: function (response) { 212 $("#confirmDelete").html(label_yes).attr("disabled", false); 213 $("#deleteModal").modal("hide"); 214 if (!response.error) { 215 toastr.success(response.message); 216 if (reload) { 217 location.reload(); 218 } else if (tableID) { 219 $("#" + tableID).bootstrapTable("refresh"); 220 } else { 221 location.reload(); 222 } 223 } else { 224 toastr.error(response.message); 225 } 226 }, 227 error: function () { 228 $("#confirmDelete").html(label_yes).attr("disabled", false); 229 $("#deleteModal").modal("hide"); 230 toastr.error(label_something_went_wrong); 231 }, 232 }); 233 }); 234}); 235$(document).on("click", ".delete", function (e) { 236 e.preventDefault(); 237 var id = $(this).data("id"); 238 var type = $(this).data("type"); 239 240 //alert(type); 241 242 var reload = $(this).data("reload") === true; // Simplified the reload condition 243 var tableID = $(this).data("table") || "table"; 244 // Map types to their respective actions and API routes 245 var actions = { 246 users: "delete_user", 247 "contract-type": "delete-contract-type", 248 "project-media": "delete-media", 249 "task-media": "delete-media", 250 "expense-type": "delete-expense-type", 251 milestone: "delete-milestone", 252 default: "destroy", 253 }; 254 var typeMappings = { 255 "contract-type": "contracts", 256 "project-media": "projects", 257 "task-media": "tasks", 258 "expense-type": "expenses", 259 milestone: "projects", 260 default: type, 261 }; 262 var destroy = actions[type] || actions["default"]; 263 type = typeMappings[type] || typeMappings["default"]; 264 var urlPrefix = window.location.pathname.split("/")[1]; 265 266 // Show confirmation modal 267 $("#deleteModal").modal("show"); 268 $("#deleteModal").off("click", "#confirmDelete"); 269 // On confirmation click 270 $("#deleteModal").on("click", "#confirmDelete", function () { 271 $("#confirmDelete").html(label_please_wait).attr("disabled", true); 272 // Perform the AJAX request 273 $.ajax({ 274 url: `/${urlPrefix}/${type}/${destroy}/${id}`, 275 type: "DELETE", 276 headers: { 277 "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval 278 }, 279 success: function (response) { 280 $("#confirmDelete").html(label_yes).attr("disabled", false); 281 $("#deleteModal").modal("hide"); 282 if (!response.error) { 283 toastr.success(response.message);
284 if (reload) { 285 location.reload(); 286 } else if (tableID) { 287 $("#" + tableID).bootstrapTable("refresh"); 288 } else { 289 location.reload(); 290 } 291 } else { 292 toastr.error(response.message); 293 } 294 }, 295 error: function () { 296 $("#confirmDelete").html(label_yes).attr("disabled", false); 297 $("#deleteModal").modal("hide"); 298 toastr.error(label_something_went_wrong); 299 }, 300 }); 301 }); 302}); 303 304 305$(document).on("click", ".delete-shift", function (e) { 306 e.preventDefault(); 307 var id = $(this).data("id"); 308 var type = $(this).data("type"); 309 310 //alert(type); 311 312 var reload = $(this).data("reload") === true; // Simplified the reload condition 313 var tableID = $(this).data("table") || "table"; 314 // Map types to their respective actions and API routes 315 var actions = { 316 users: "delete_user", 317 "contract-type": "delete-contract-type", 318 "project-media": "delete-media", 319 "task-media": "delete-media", 320 "expense-type": "delete-expense-type", 321 milestone: "delete-milestone", 322 default: "destroy", 323 }; 324 var typeMappings = { 325 "contract-type": "contracts", 326 "project-media": "projects", 327 "task-media": "tasks", 328 "expense-type": "expenses", 329 milestone: "projects", 330 default: type, 331 }; 332 var destroy = actions[type] || actions["default"]; 333 type = typeMappings[type] || typeMappings["default"]; 334 var urlPrefix = window.location.pathname.split("/")[1]; 335 336 // Show confirmation modal 337 $("#deleteModal").modal("show"); 338 $("#deleteModal").off("click", "#confirmDelete"); 339 // On confirmation click 340 $("#deleteModal").on("click", "#confirmDelete", function () { 341 $("#confirmDelete").html(label_please_wait).attr("disabled", true); 342 // Perform the AJAX request 343 $.ajax({ 344 url: `/${urlPrefix}/${type}/${destroy}/${id}`, 345 type: "DELETE", 346 headers: { 347 "X-CSRF-TOKEN": $('input[name="_token"]').val(), // Simplified CSRF token retrieval 348 }, 349 success: function (response) { 350 $("#confirmDelete").html(label_yes).attr("disabled", false); 351 $("#deleteModal").modal("hide"); 352 if (!response.error) { 353 toastr.success(response.message); 354 if (reload) { 355 location.reload(); 356 } else if (tableID) { 357 $("#" + tableID).bootstrapTable("refresh"); 358 } else { 359 location.reload(); 360 } 361 } else { 362 toastr.error(response.message); 363 } 364 }, 365 error: function () { 366 $("#confirmDelete").html(label_yes).attr("disabled", false); 367 $("#deleteModal").modal("hide"); 368 toastr.error(label_something_went_wrong); 369 }, 370 }); 371 }); 372}); 373 374 375$(document).on("click", ".delete-selected", function (e) { 376 e.preventDefault(); 377 const $this = $(this); 378 const table = $this.data("table"); 379 const type = $this.data("type"); 380 const destroyActionMap = { 381 users: "delete_multiple_user", 382 "contract-type": "delete-multiple-contract-type", 383 "project-media": "delete-multiple-media", 384 "task-media": "delete-multiple-media", 385 "expense-type": "delete-multiple-expense-type", 386 milestone: "delete-multiple-milestone", 387 default: "destroy_multiple", 388 }; 389 const typeMap = { 390 "contract-type": "contracts", 391 "project-media": "projects", 392 "task-media": "tasks", 393 "expense-type": "expenses", 394 milestone: "projects", 395 }; 396 const destroy = destroyActionMap[type] || destroyActionMap.default; 397 const mappedType = typeMap[type] || type; 398 const urlPrefix = window.location.pathname.split("/")[1]; 399 const selections = $(`#${table}`).bootstrapTable("getSelections"); 400 const selectedIds = selections.map((row) => row.id); 401 if (selectedIds.length === 0) { 402 return toastr.error(label_please_select_records_to_delete); 403 } 404 $("#confirmDeleteSelectedModal") 405 .modal("show") 406 .off("click", "#confirmDeleteSelections") 407 .on("click", "#confirmDeleteSelections", function () { 408 const $confirmBtn = $("#confirmDeleteSelections"); 409 $confirmBtn.html(label_please_wait).prop("disabled", true); 410 $.ajax({ 411 url: `/${urlPrefix}/${mappedType}/${destroy}/`, 412 type: "DELETE", 413 data: { ids: selectedIds }, 414 headers: { 415 "X-CSRF-TOKEN": $('input[name="_token"]').val(), 416 }, 417 complete: () => { 418 $confirmBtn.html(label_yes).prop("disabled", false); 419 $("#confirmDeleteSelectedModal").modal("hide"); 420 }, 421 success: function (response) { 422 $(`#${table}`).bootstrapTable("refresh"); 423 toastr[response.error ? "error" : "success"]( 424 response.message 425 ); 426 }, 427 error: () => toastr.error(label_something_went_wrong), 428 }); 429 }); 430}); 431function update_status(e) { 432 var id = e["id"]; 433 var name = e["name"]; 434 var reload = e.getAttribute("reload") ? true : false;
435 var status; 436 var is_checked = $("input[name=" + name + "]:checked"); 437 if (is_checked.length >= 1) { 438 status = 1; 439 } else { 440 status = 0; 441 } 442 $.ajax({ 443 url: "/master-panel/todos/update_status", 444 type: "POST", // Use POST method 445 headers: { 446 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 447 }, 448 data: { 449 _method: "PUT", // Specify the desired method 450 id: id, 451 status: status, 452 }, 453 success: function (response) { 454 if (response.error == false) { 455 if (reload) { 456 location.reload(); 457 } 458 toastr.success(response.message); // show a success message 459 $("#" + id + "_title").toggleClass("striked"); 460 } else { 461 toastr.error(response.message); 462 } 463 }, 464 }); 465} 466$(document).on("click", ".edit-todo", function () { 467 var id = $(this).data("id"); 468 var url = $(this).data("url"); 469 $("#edit_todo_modal").modal("show"); 470 $.ajax({ 471 url: "/master-panel/todos/get/" + id, 472 type: "get", 473 headers: { 474 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 475 }, 476 dataType: "json", 477 success: function (response) { 478 $("#todo_id").val(response.todo.id); 479 $("#todo_title").val(response.todo.title); 480 $("#todo_priority").val(response.todo.priority); 481 $("#todo_description").val(response.todo.description); 482 }, 483 }); 484}); 485$(document).on("click", ".edit-note", function () { 486 var id = $(this).data("id"); 487 $("#edit_note_modal").modal("show"); 488 var url = $(this).data("url"); 489 var classes = $("#note_color").attr("class").split(" "); 490 var currentColorClass = classes.filter(function (className) { 491 return className.startsWith("select-"); 492 })[0]; 493 $.ajax({ 494 url: url, 495 type: "get", 496 headers: { 497 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 498 }, 499 dataType: "json", 500 success: function (response) { 501 $("#note_id").val(response.note.id); 502 $("#note_title").val(response.note.title); 503 $("#note_color") 504 .val(response.note.color) 505 .removeClass(currentColorClass) 506 .addClass("select-bg-label-" + response.note.color); 507 var description = 508 response.note.description !== null 509 ? response.note.description 510 : ""; 511 $("#edit_note_modal").find("#note_description").val(description); 512 }, 513 }); 514}); 515$(document).on("click", ".edit-status", function () { 516 var id = $(this).data("id"); 517 var routePrefix = $("#table").data("routePrefix"); 518 $("#edit_status_modal").modal("show"); 519 var classes = $("#status_color").attr("class").split(" "); 520 var currentColorClass = classes.filter(function (className) { 521 return className.startsWith("select-"); 522 })[0]; 523 $.ajax({ 524 url: routePrefix + "/status/get/" + id, 525 type: "get", 526 headers: { 527 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 528 }, 529 dataType: "json", 530 success: function (response) { 531 $("#status_id").val(response.status.id); 532 $("#status_title").val(response.status.title); 533 $("#status_color") 534 .val(response.status.color) 535 .removeClass(currentColorClass) 536 .addClass("select-bg-label-" + response.status.color); 537 var modalForm = $("#edit_status_modal").find("form"); 538 var usersSelect = modalForm.find( 539 '.js-example-basic-multiple[name="role_ids[]"]' 540 ); 541 usersSelect.val(response.roles); 542 usersSelect.trigger("change"); // Trigger change event to update select2 543 }, 544 }); 545}); 546$(document).on("click", ".edit-scheduler-status", function () { 547 var id = $(this).data("id"); 548 var routePrefix = $("#table").data("routePrefix"); 549 $("#edit_scheduler_statuses_modal").modal("show"); 550 $.ajax({ 551 url: routePrefix + "/scheduler-statuses/get/" + id, 552 type: "get", 553 headers: { 554 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 555 }, 556 dataType: "json", 557 success: function (response) { 558 $("#scheduler_statuses_id").val(response.status.id); 559 $("#scheduler_status_title").val(response.status.name); 560 $("#scheduler_lable").val(response.status.label); 561 $("#color_code").val(response.status.color_code); 562 var modalForm = $("#edit_scheduler_statuses_modal").find("form"); 563 }, 564 }); 565}); 566$(document).on("click", ".edit-document-categories", function () { 567 var id = $(this).data("id"); 568 var routePrefix = $("#table").data("routePrefix"); 569 $("#edit_dc_document_modal").modal("show"); 570 $.ajax({ 571 url: routePrefix + "/document-categories/get/" + id, 572 type: "get", 573 headers: { 574 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 575 }, 576 dataType: "json", 577 success: function (response) { 578 console.log(response); 579 $("#dc_id").val(response.status.id); 580 $("#dc_update_title").val(response.status.title); 581 //$("#status_title").val(response.status.title); 582 }, 583 }); 584}); 585$(document).on("click", ".edit-shift-type", function () { 586 var id = $(this).data("id"); 587 var routePrefix = $("#table").data("routePrefix"); 588 $("#edit_shift_type_modal").modal("show"); 589 $.ajax({
590 url: routePrefix + "/shift-type/get/" + id, 591 type: "get", 592 headers: { 593 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 594 }, 595 dataType: "json", 596 success: function (response) { 597 console.log(response); 598 $("#st_id").val(response.status.id); 599 $("#st_update_title").val(response.status.title); 600 //$("#status_title").val(response.status.title); 601 }, 602 }); 603}); 604$(document).on("click", ".edit-tag", function () { 605 var id = $(this).data("id"); 606 var routePrefix = $("#table").data("routePrefix"); 607 var classes = $("#tag_color").attr("class").split(" "); 608 var currentColorClass = classes.filter(function (className) { 609 return className.startsWith("select-"); 610 })[0]; 611 $("#edit_tag_modal").modal("show"); 612 $.ajax({ 613 url: routePrefix + "/tags/get/" + id, 614 type: "get", 615 headers: { 616 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 617 }, 618 dataType: "json", 619 success: function (response) { 620 $("#tag_id").val(response.tag.id);
621 $("#tag_title").val(response.tag.title); 622 $("#tag_color") 623 .val(response.tag.color) 624 .removeClass(currentColorClass) 625 .addClass("select-bg-label-" + response.tag.color); 626 }, 627 }); 628}); 629$(document).on("click", ".edit-leave-request", function () { 630 var id = $(this).data("id"); 631 $("#edit_leave_request_modal").modal("show"); 632 $.ajax({ 633 url: "/master-panel/leave-requests/get/" + id, 634 type: "get", 635 headers: { 636 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 637 }, 638 dataType: "json", 639 success: function (response) { 640 var formattedFromDate = moment(response.lr.from_date).format( 641 js_date_format 642 ); 643 var formattedToDate = moment(response.lr.to_date).format( 644 js_date_format 645 ); 646 var fromDateSelect = $("#edit_leave_request_modal").find( 647 "#update_start_date" 648 ); 649 var toDateSelect = $("#edit_leave_request_modal").find( 650 "#update_end_date" 651 ); 652 var reasonSelect = $("#edit_leave_request_modal").find( 653 '[name="reason"]' 654 ); 655 var totalDaysSelect = $("#edit_leave_request_modal").find( 656 "#update_total_days" 657 ); 658 $("#lr_id").val(response.lr.id); 659 $("#leaveUser").val( 660 response.lr.user.first_name + " " + response.lr.user.last_name 661 ); 662 fromDateSelect.val(formattedFromDate); 663 toDateSelect.val(formattedToDate); 664 initializeDateRangePicker("#update_start_date,#update_end_date"); 665 var start_date = moment(fromDateSelect.val(), js_date_format); 666 var end_date = moment(toDateSelect.val(), js_date_format); 667 var total_days = end_date.diff(start_date, "days") + 1; 668 totalDaysSelect.val(total_days); 669 if (response.lr.from_time && response.lr.to_time) { 670 $("#updatePartialLeave") 671 .prop("checked", true) 672 .trigger("change"); 673 var fromTimeSelect = $("#edit_leave_request_modal").find( 674 '[name="from_time"]' 675 ); 676 var toTimeSelect = $("#edit_leave_request_modal").find( 677 '[name="to_time"]' 678 ); 679 fromTimeSelect.val(response.lr.from_time); 680 toTimeSelect.val(response.lr.to_time); 681 } else { 682 $("#updatePartialLeave") 683 .prop("checked", false) 684 .trigger("change"); 685 } 686 if (response.lr.visible_to_all) { 687 $("#edit_leave_request_modal") 688 .find(".leaveVisibleToAll") 689 .prop("checked", true) 690 .trigger("change"); 691 } else { 692 $("#edit_leave_request_modal") 693 .find(".leaveVisibleToAll") 694 .prop("checked", false) 695 .trigger("change"); 696 var visibleToSelect = $("#edit_leave_request_modal").find( 697 '.js-example-basic-multiple[name="visible_to_ids[]"]' 698 ); 699 var visibleToUsers = response.visibleTo.map((user) => user.id); 700 visibleToSelect.val(visibleToUsers); 701 visibleToSelect.trigger("change"); 702 } 703 reasonSelect.val(response.lr.reason); 704 $("input[name=status][value=" + response.lr.status + "]").prop( 705 "checked", 706 true 707 ); 708 }, 709 }); 710}); 711$(document).on("click", ".edit-contract-type", function () { 712 var routePrefix = $("#table").data("routePrefix"); 713 var id = $(this).data("id"); 714 $("#edit_contract_type_modal").modal("show"); 715 $.ajax({ 716 url: "" + routePrefix + "/contracts/get-contract-type/" + id, 717 type: "get", 718 headers: { 719 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 720 }, 721 dataType: "json", 722 success: function (response) { 723 $("#update_contract_type_id").val(response.ct.id); 724 $("#contract_type").val(response.ct.type); 725 }, 726 }); 727}); 728$(document).on("click", ".edit-contract", function () { 729 var id = $(this).data("id"); 730 var routePrefix = $("#contracts_table").data("routePrefix"); 731 $("#edit_contract_modal").modal("show"); 732 $.ajax({ 733 url: "/master-panel/contracts/get/" + id, 734 type: "get", 735 headers: { 736 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 737 }, 738 dataType: "json", 739 success: function (response) { 740 if (response.error == false) { 741 var formattedStartDate = moment( 742 response.contract.start_date 743 ).format(js_date_format); 744 var formattedEndDate = moment( 745 response.contract.end_date 746 ).format(js_date_format); 747 $("#contract_id").val(response.contract.id);
748 $("#title").val(response.contract.title); 749 $("#value").val(response.contract.value); 750 $("#client_id").val(response.contract.client_id); 751 $("#project_id").val(response.contract.project_id); 752 $("#contract_type_id").val(response.contract.contract_type_id); 753 $("#update_contract_description").val( 754 response.contract.description 755 ); 756 $("#update_start_date").val(formattedStartDate); 757 $("#update_end_date").val(formattedEndDate); 758 initializeDateRangePicker( 759 "#update_start_date, #update_end_date" 760 ); 761 } else { 762 location.reload(); 763 } 764 }, 765 }); 766}); 767function initializeDateRangePicker(inputSelector) { 768 // Find the modal that contains the input field 769 var modalId = $(inputSelector).closest(".modal").attr("id"); 770 // Initialize daterangepicker and bind it to the modal using the modal ID 771 $(inputSelector).daterangepicker({ 772 alwaysShowCalendars: true, 773 showCustomRangeLabel: true, 774 minDate: moment($(inputSelector).val(), js_date_format), 775 singleDatePicker: true, 776 showDropdowns: true, 777 autoUpdateInput: true, 778 parentEl: "#" + modalId, // Attach the daterangepicker to the modal 779 locale: { 780 cancelLabel: "Clear", 781 format: js_date_format, 782 }, 783 }); 784 // Optional: Reposition on modal scroll 785 $("#" + modalId).on("scroll", function () { 786 if ($(inputSelector).data("daterangepicker")) { 787 $(inputSelector).data("daterangepicker").hide(); 788 $(inputSelector).data("daterangepicker").show(); 789 } 790 }); 791} 792$(document).on("click", "#set-as-default", function (e) { 793 e.preventDefault(); 794 var lang = $(this).data("lang"); 795 var url = $(this).data("url"); 796 $("#default_language_modal").modal("show"); // show the confirmation modal 797 $("#default_language_modal").on("click", "#confirm", function () { 798 $.ajax({ 799 url: url, 800 type: "PUT", 801 headers: { 802 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 803 }, 804 data: { 805 lang: lang, 806 }, 807 success: function (response) { 808 if (response.error == false) { 809 location.reload(); 810 } else { 811 toastr.error(response.message); 812 } 813 }, 814 }); 815 }); 816}); 817$(document).on("click", "#remove-participant", function (e) { 818 e.preventDefault(); 819 var routePrefix = $(this).data("routePrefix"); 820 $("#leaveWorkspaceModal").modal("show"); // show the confirmation modal 821 $("#leaveWorkspaceModal").on("click", "#confirm", function () { 822 $.ajax({ 823 url: routePrefix + "/workspaces/remove_participant", 824 type: "GET", 825 headers: { 826 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 827 }, 828 success: function (response) { 829 location.reload(); 830 }, 831 error: function (data) { 832 location.reload(); 833 }, 834 }); 835 }); 836}); 837$(document).ready(function () { 838 // Define the IDs you want to process 839 var idsToProcess = [ 840 "#start_date", 841 "#end_date", 842 "#update_start_date", 843 "#update_end_date", 844 "#lr_end_date", 845 "#meeting_end_date", 846 "#expense_date", 847 "#update_expense_date", 848 "#payment_date", 849 "#update_payment_date", 850 "#update_milestone_start_date", 851 "#update_milestone_end_date", 852 "#task_start_date", 853 "#task_end_date", 854 "#edit_announcement_start_date", 855 "#edit_announcement_end_date", 856 ]; 857 // Loop through the IDs 858 for (var i = 0; i < idsToProcess.length; i++) { 859 var id = idsToProcess[i]; 860 if ($(id).length) { 861 if ( 862 id === "#payment_date" && 863 !$(id).closest("#create_payment_modal").length 864 ) { 865 continue; 866 } 867 if ($(id).val() == "") { 868 $(id).val(moment(new Date()).format(js_date_format)); 869 } 870 var modalId = $(id).closest(".modal").attr("id"); 871 $(id).daterangepicker({ 872 alwaysShowCalendars: true, 873 showCustomRangeLabel: true, 874 // minDate: moment($(id).val(), js_date_format), 875 parentEl: "#" + modalId, // Attach the daterangepicker to the modal 876 singleDatePicker: true, 877 showDropdowns: true, 878 autoUpdateInput: true, 879 locale: { 880 cancelLabel: "Clear", 881 format: js_date_format, 882 }, 883 function(start, end, label) { 884 // Replace Font Awesome/Glyphicon icons with Boxicons 885 $(".daterangepicker .prev").html( 886 '<i class="bx bx-chevron-left"></i>' 887 ); 888 $(".daterangepicker .next").html( 889 '<i class="bx bx-chevron-right"></i>' 890 ); 891 }, 892 }); 893 } 894 } 895 // Define the IDs you want to process 896 var idsToProcess = ["#payment_date", "#dob", "#doj"]; 897 var minDateStr = "01/01/1950"; 898 var minDate = moment(minDateStr, "DD/MM/YYYY"); 899 // Loop through the IDs 900 for (var i = 0; i < idsToProcess.length; i++) { 901 var id = idsToProcess[i]; 902 if ($(id).length) { 903 var modalId = $(id).closest(".modal").attr("id"); 904 $(id).daterangepicker({ 905 alwaysShowCalendars: true, 906 showCustomRangeLabel: true, 907 singleDatePicker: true, 908 showDropdowns: true, 909 autoUpdateInput: false, 910 minDate: minDate, 911 parentEl: "#" + modalId, 912 locale: { 913 cancelLabel: "Clear", 914 format: js_date_format, 915 }, 916 }); 917 $(id).on("apply.daterangepicker", function (ev, picker) { 918 // Update the input with the selected date 919 920 921 922 if ($(this).attr('id') === 'dob') { 923 $('#start').val(picker.startDate.format("YYYY-MM-DD")).trigger('change'); 924 console.log('Start date set:', $('#start').val()); 925 } else if ($(this).attr('id') === 'doj') { 926 $('#end').val(picker.startDate.format("YYYY-MM-DD")).trigger('change'); 927 console.log('End date set:', $('#end').val()); 928 } 929 930 931 932 $(this).val(picker.startDate.format(js_date_format)); 933 }); 934 } 935 } 936}); 937if ($("#total_days").length) { 938 $("#end_date").on("apply.daterangepicker", function (ev, picker) { 939 // Calculate the inclusive difference in days between start_date and end_date 940 var start_date = moment($("#start_date").val(), js_date_format); 941 var end_date = picker.startDate; 942 var total_days = end_date.diff(start_date, "days") + 1; 943 // Display the total_days in the total_days input field 944 $("#total_days").val(total_days); 945 }); 946} 947$(document).ready(function () { 948 $( 949 "#report_start_date_between,#report_end_date_between,#filter_date_range,#project_start_date_between,#project_end_date_between,#task_start_date_between,#task_end_date_between,#lr_start_date_between,#lr_end_date_between,#contract_start_date_between,#contract_end_date_between,#timesheet_start_date_between,#timesheet_end_date_between,#meeting_start_date_between,#meeting_end_date_between,#activity_log_between_date,#start_date_between,#end_date_between,#expense_from_date_between"
950 ).daterangepicker({ 951 alwaysShowCalendars: true, 952 showCustomRangeLabel: true, 953 singleDatePicker: false, 954 showDropdowns: true, 955 autoUpdateInput: false, 956 locale: { 957 cancelLabel: "Clear", 958 format: js_date_format, 959 }, 960 }); 961 $( 962 "#report_start_date_between,#report_end_date_between,#filter_date_range,#project_start_date_between,#project_end_date_between,#task_start_date_between,#task_end_date_between,#lr_start_date_between,#lr_end_date_between,#contract_start_date_between,#contract_end_date_between,#timesheet_start_date_between,#timesheet_end_date_between,#meeting_start_date_between,#meeting_end_date_between,#activity_log_between_date,#start_date_between,#end_date_between,#expense_from_date_between" 963 ).on("apply.daterangepicker", function (ev, picker) { 964 $(this).val( 965 picker.startDate.format(js_date_format) + 966 " To " + 967 picker.endDate.format(js_date_format) 968 ); 969 }); 970}); 971if ($("#project_start_date_between").length) { 972 $("#project_start_date_between").on( 973 "apply.daterangepicker", 974 function (ev, picker) { 975 var startDate = picker.startDate.format("YYYY-MM-DD"); 976 var endDate = picker.endDate.format("YYYY-MM-DD"); 977 $("#project_start_date_from").val(startDate); 978 $("#project_start_date_to").val(endDate); 979 $("#projects_table").bootstrapTable("refresh"); 980 } 981 ); 982 $("#project_start_date_between").on( 983 "cancel.daterangepicker", 984 function (ev, picker) { 985 $("#project_start_date_from").val(""); 986 $("#project_start_date_to").val(""); 987 $("#projects_table").bootstrapTable("refresh"); 988 $("#project_start_date_between").val(""); 989 } 990 ); 991 $("#project_end_date_between").on( 992 "apply.daterangepicker", 993 function (ev, picker) { 994 var startDate = picker.startDate.format("YYYY-MM-DD"); 995 var endDate = picker.endDate.format("YYYY-MM-DD"); 996 $("#project_end_date_from").val(startDate); 997 $("#project_end_date_to").val(endDate); 998 $("#projects_table").bootstrapTable("refresh"); 999 } 1000 ); 1001 $("#project_end_date_between").on( 1002 "cancel.daterangepicker", 1003 function (ev, picker) { 1004 $("#project_end_date_from").val(""); 1005 $("#project_end_date_to").val(""); 1006 $("#projects_table").bootstrapTable("refresh"); 1007 $("#project_end_date_between").val(""); 1008 } 1009 ); 1010} 1011if ($("#task_start_date_between").length) { 1012 $("#task_start_date_between").on( 1013 "apply.daterangepicker", 1014 function (ev, picker) { 1015 var startDate = picker.startDate.format("YYYY-MM-DD"); 1016 var endDate = picker.endDate.format("YYYY-MM-DD"); 1017 $("#task_start_date_from").val(startDate); 1018 $("#task_start_date_to").val(endDate); 1019 $("#task_table").bootstrapTable("refresh"); 1020 } 1021 ); 1022 $("#task_start_date_between").on( 1023 "cancel.daterangepicker", 1024 function (ev, picker) { 1025 $("#task_start_date_from").val(""); 1026 $("#task_start_date_to").val(""); 1027 $("#task_table").bootstrapTable("refresh"); 1028 $("#task_start_date_between").val(""); 1029 } 1030 ); 1031 $("#task_end_date_between").on( 1032 "apply.daterangepicker", 1033 function (ev, picker) { 1034 var startDate = picker.startDate.format("YYYY-MM-DD"); 1035 var endDate = picker.endDate.format("YYYY-MM-DD"); 1036 $("#task_end_date_from").val(startDate); 1037 $("#task_end_date_to").val(endDate); 1038 $("#task_table").bootstrapTable("refresh"); 1039 } 1040 ); 1041 $("#task_end_date_between").on( 1042 "cancel.daterangepicker", 1043 function (ev, picker) { 1044 $("#task_end_date_from").val(""); 1045 $("#task_end_date_to").val(""); 1046 $("#task_table").bootstrapTable("refresh"); 1047 $("#task_end_date_between").val(""); 1048 } 1049 ); 1050} 1051if ($("#timesheet_start_date_between").length) { 1052 $("#timesheet_start_date_between").on( 1053 "apply.daterangepicker", 1054 function (ev, picker) { 1055 var startDate = picker.startDate.format("YYYY-MM-DD"); 1056 var endDate = picker.endDate.format("YYYY-MM-DD"); 1057 $("#timesheet_start_date_from").val(startDate); 1058 $("#timesheet_start_date_to").val(endDate); 1059 $("#timesheet_table").bootstrapTable("refresh"); 1060 } 1061 ); 1062 $("#timesheet_start_date_between").on( 1063 "cancel.daterangepicker", 1064 function (ev, picker) { 1065 $("#timesheet_start_date_from").val(""); 1066 $("#timesheet_start_date_to").val(""); 1067 $("#timesheet_table").bootstrapTable("refresh"); 1068 $("#timesheet_start_date_between").val(""); 1069 } 1070 ); 1071 $("#timesheet_end_date_between").on( 1072 "apply.daterangepicker", 1073 function (ev, picker) { 1074 var startDate = picker.startDate.format("YYYY-MM-DD"); 1075 var endDate = picker.endDate.format("YYYY-MM-DD"); 1076 $("#timesheet_end_date_from").val(startDate); 1077 $("#timesheet_end_date_to").val(endDate); 1078 $("#timesheet_table").bootstrapTable("refresh"); 1079 } 1080 ); 1081 $("#timesheet_end_date_between").on( 1082 "cancel.daterangepicker", 1083 function (ev, picker) { 1084 $("#timesheet_end_date_from").val(""); 1085 $("#timesheet_end_date_to").val(""); 1086 $("#timesheet_table").bootstrapTable("refresh"); 1087 $("#timesheet_end_date_between").val(""); 1088 } 1089 ); 1090} 1091if ($("#meeting_start_date_between").length) { 1092 $("#meeting_start_date_between").on( 1093 "apply.daterangepicker", 1094 function (ev, picker) { 1095 var startDate = picker.startDate.format("YYYY-MM-DD"); 1096 var endDate = picker.endDate.format("YYYY-MM-DD"); 1097 $("#meeting_start_date_from").val(startDate); 1098 $("#meeting_start_date_to").val(endDate); 1099 $("#meetings_table").bootstrapTable("refresh"); 1100 } 1101 ); 1102 $("#meeting_start_date_between").on( 1103 "cancel.daterangepicker", 1104 function (ev, picker) { 1105 $("#meeting_start_date_from").val(""); 1106 $("#meeting_start_date_to").val(""); 1107 $("#meetings_table").bootstrapTable("refresh"); 1108 $("#meeting_start_date_between").val(""); 1109 } 1110 ); 1111 $("#meeting_end_date_between").on( 1112 "apply.daterangepicker", 1113 function (ev, picker) { 1114 var startDate = picker.startDate.format("YYYY-MM-DD"); 1115 var endDate = picker.endDate.format("YYYY-MM-DD"); 1116 $("#meeting_end_date_from").val(startDate); 1117 $("#meeting_end_date_to").val(endDate); 1118 $("#meetings_table").bootstrapTable("refresh"); 1119 } 1120 ); 1121 $("#meeting_end_date_between").on( 1122 "cancel.daterangepicker", 1123 function (ev, picker) { 1124 $("#meeting_end_date_from").val(""); 1125 $("#meeting_end_date_to").val(""); 1126 $("#meetings_table").bootstrapTable("refresh"); 1127 $("#meeting_end_date_between").val(""); 1128 } 1129 ); 1130} 1131$( 1132 "textarea#footer_text,textarea#contract_description,textarea#update_contract_description , #privacy_policy , #terms_and_conditions , #refund_policy , #company_address,.description" 1133).tinymce({ 1134 height: 250, 1135 menubar: false, 1136 plugins: [ 1137 "link", 1138 "a11ychecker", 1139 "advlist", 1140 "advcode", 1141 "advtable", 1142 "autolink", 1143 "checklist", 1144 "export", 1145 "lists", 1146 "link", 1147 "image", 1148 "charmap", 1149 "preview", 1150 "anchor", 1151 "searchreplace", 1152 "visualblocks", 1153 "powerpaste", 1154 "fullscreen", 1155 "formatpainter", 1156 "insertdatetime", 1157 "media", 1158 "table", 1159 "help", 1160 "wordcount", 1161 ], 1162 toolbar: 1163 "link | undo redo | a11ycheck casechange blocks | bold italic backcolor | alignleft aligncenter alignright al
1163ignjustify | bullist numlist checklist outdent indent | removeformat | code table help", 1164}); 1165$(document).on("submit", ".form-submit-event", function (e) { 1166 e.preventDefault(); 1167 if ($("#net_payable").length > 0) { 1168 var net_payable = $("#net_payable").text(); 1169 $("#net_pay").val(net_payable); 1170 } 1171 var formData = new FormData(this); 1172 var currentForm = $(this); 1173 var parentModal = $(this).closest(".modal"); 1174 var submit_btn = $(this).find("#submit_btn"); 1175 if (submit_btn.length == 0) { 1176 submit_btn = parentModal.find('button[type="submit"]'); 1177 } 1178 // If still no submit button found, check within the form 1179 if (submit_btn.length === 0) { 1180 submit_btn = currentForm.find('button[type="submit"]'); 1181 } 1182 var btn_html = submit_btn.html(); 1183 var btn_val = submit_btn.val(); 1184 var redirect_url = currentForm.find('input[name="redirect_url"]').val(); 1185 redirect_url = 1186 typeof redirect_url !== "undefined" && redirect_url ? redirect_url : ""; 1187 var button_text = 1188 btn_html != "" || btn_html != "undefined" ? btn_html : btn_val; 1189 var tableInput = currentForm.find('input[name="table"]'); 1190 var tableID = tableInput.length ? tableInput.val() : "table"; 1191 $.ajax({ 1192 type: "POST", 1193 url: $(this).attr("action"), 1194 data: formData, 1195 headers: { 1196 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 1197 }, 1198 beforeSend: function () { 1199 submit_btn.html(label_please_wait); 1200 submit_btn.attr("disabled", true); 1201 }, 1202 cache: false, 1203 contentType: false, 1204 processData: false, 1205 dataType: "json", 1206 success: function (result) { 1207 submit_btn.html(button_text); 1208 submit_btn.attr("disabled", false); 1209 if (result["error"] == true) { 1210 toastr.error(result["message"]); 1211 } else { 1212 if ($(".empty-state").length > 0) { 1213 if (result.hasOwnProperty("message")) { 1214 toastr.success(result["message"]); 1215 // Show toastr for 3 seconds before reloading or redirecting 1216 setTimeout(handleRedirection, 3000); 1217 } else { 1218 handleRedirection(); 1219 } 1220 } else { 1221 if (currentForm.find('input[name="dnr"]').length > 0) { 1222 var modalWithClass = $(".modal.fade.show"); 1223 if (modalWithClass.length > 0) { 1224 var idOfModal = modalWithClass.attr("id"); 1225 $("#" + idOfModal).modal("hide"); 1226 $("#" + tableID).bootstrapTable("refresh"); 1227 currentForm[0].reset(); 1228 var partialLeaveCheckbox = $("#partialLeave"); 1229 if (partialLeaveCheckbox.length) { 1230 partialLeaveCheckbox.trigger("change"); 1231 } 1232 resetDateFields(currentForm); 1233 if (idOfModal == "create_status_modal") { 1234 var dropdownSelector = modalWithClass.find( 1235 'select[name="status_id"]' 1236 ); 1237 if (dropdownSelector.length) { 1238 var newItem = result.status; 1239 var newOption = $("<option></option>") 1240 .attr("value", newItem.id) 1241 .attr("data-color", newItem.color) 1242 .attr("selected", true) 1243 .text( 1244 newItem.title + 1245 " (" + 1246 newItem.color + 1247 ")" 1248 ); 1249 $(dropdownSelector).append(newOption); 1250 var openModalId = dropdownSelector 1251 .closest(".modal.fade.show") 1252 .attr("id"); 1253 // List of all possible modal IDs 1254 var modalIds = [ 1255 "#create_project_modal", 1256 "#edit_project_modal", 1257 "#create_task_modal", 1258 "#edit_task_modal", 1259 ]; 1260 // Iterate through each modal ID 1261 modalIds.forEach(function (modalId) { 1262 // If the modal ID is not the open one 1263 if (modalId !== "#" + openModalId) { 1264 // Find the select element within the modal 1265 var otherModalSelector = $( 1266 modalId 1267 ).find('select[name="status_id"]'); 1268 // Create a new option without 'selected' attribute 1269 var otherOption = $( 1270 "<option></option>" 1271 ) 1272 .attr("value", newItem.id) 1273 .attr( 1274 "data-color", 1275 newItem.color 1276 ) 1277 .text( 1278 newItem.title + 1279 " (" + 1280 newItem.color + 1281 ")" 1282 ); 1283 // Append the option to the select element in the modal 1284 otherModalSelector.append( 1285 otherOption 1286 ); 1287 } 1288 }); 1289 } 1290 } 1291 if (idOfModal == "create_priority_modal") { 1292 var dropdownSelector = modalWithClass.find( 1293 'select[name="priority_id"]' 1294 ); 1295 if (dropdownSelector.length) { 1296 var newItem = result.priority; 1297 var newOption = $("<option></option>") 1298 .attr("value", newItem.id) 1299 .attr( 1300 "class", 1301 "badge bg-label-" + newItem.color 1302 ) 1303 .attr("selected", true) 1304 .text( 1305 newItem.title + 1306 " (" + 1307 newItem.color + 1308 ")" 1309 ); 1310 $(dropdownSelector).append(newOption); 1311 var openModalId = dropdownSelector 1312 .closest(".modal.fade.show") 1313 .attr("id"); 1314 // List of all possible modal IDs 1315 var modalIds = [ 1316 "#create_project_modal", 1317 "#edit_project_modal", 1318 "#create_task_modal", 1319 "#edit_task_modal", 1320 ]; 1321 // Iterate through each modal ID 1322 modalIds.forEach(function (modalId) { 1323 // If the modal ID is not the open one 1324 if (modalId !== "#" + openModalId) { 1325 // Find the select element within the modal 1326 var otherModalSelector = $( 1327 modalId 1328 ).find( 1329 'select[name="priority_id"]' 1330 ); 1331 // Create a new option without 'selected' attribute 1332 var otherOption = $( 1333 "<option></option>" 1334 ) 1335 .attr("value", newItem.id) 1336 .attr( 1337 "class", 1338 "badge bg-label-" + 1339 newItem.color 1340 ) 1341 .text( 1342 newItem.title + 1343 " (" + 1344 newItem.color + 1345 ")" 1346 ); 1347 // Append the option to the select element in the modal 1348 otherModalSelector.append( 1349 otherOption 1350 ); 1351 } 1352 }); 1353 } 1354 } 1355 if (idOfModal == "create_tag_modal") { 1356 var dropdownSelector = modalWithClass.find( 1357 'select[name="tag_ids[]"]' 1358 ); 1359 if (dropdownSelector.length) { 1360 var newItem = result.tag; 1361 var newOption = $("<option></option>") 1362 .attr("value", newItem.id) 1363 .attr("data-color", newItem.color) 1364 .attr("selected", true) 1365 .text(newItem.title); 1366 $(dropdownSelector).append(newOption); 1367 $(dropdownSelector).trigger("change"); 1368 var openModalId = dropdownSelector 1369 .closest(".modal.fade.show") 1370 .attr("id"); 1371 // List of all possible modal IDs 1372 var modalIds = [ 1373 "#create_project_modal", 1374 "#edit_project_modal", 1375 ]; 1376 // Iterate through each modal ID 1377 modalIds.forEach(function (modalId) { 1378 // If the modal ID is not the open one 1379 if (modalId !== "#" + openModalId) { 1380 // Find the select element within the modal 1381 var otherModalSelector = $( 1382 modalId 1383 ).find('select[name="tag_ids[]"]'); 1384 // Create a new option without 'selected' attribute 1385 var otherOption = $( 1386 "<option></option>" 1387 ) 1388 .attr("value", newItem.id) 1389 .attr( 1390 "data-color", 1391 newItem.color 1392 ) 1393 .text(newItem.title); 1394 // Append the option to the select element in the modal 1395 otherModalSelector.append( 1396 otherOption 1397 ); 1398 } 1399 }); 1400 } 1401 } 1402 if (idOfModal == "create_item_modal") { 1403 var dropdownSelector = $("#item_id"); 1404 if (dropdownSelector.length) { 1405 var newItem = result.item; 1406 var newOption = $("<option></option>") 1407 .attr("value", newItem.id) 1408 .attr("selected", true) 1409 .text(newItem.title); 1410 $(dropdownSelector).append(newOption); 1411 $(dropdownSelector).trigger("change"); 1412 } 1413 } 1414 if (idOfModal === "create_contract_type_modal") { 1415 var dropdownSelector = modalWithClass.find( 1416 'select[name="contract_type_id"]' 1417 ); 1418 if (dropdownSelector.length) { 1419 var newItem = result.ct; 1420 var newOption = $("<option></option>") 1421 .attr("value", newItem.id) 1422 .attr("selected", true) 1423 .text(newItem.type); 1424 // Append and select the new option in the current modal 1425 dropdownSelector.append(newOption); 1426 var openModalId = dropdownSelector 1427 .closest(".modal.fade.show") 1428 .attr("id"); 1429 var otherModalId = 1430 openModalId === "create_contract_modal" 1431 ? "#edit_contract_modal" 1432 : "#create_contract_modal"; 1433 var otherModalSelector = $( 1434 otherModalId 1435 ).find('select[name="contract_type_id"]'); 1436 // Create a new option for the other modal without 'selected' attribute 1437 var otherOption = $("<option></option>") 1438 .attr("value", newItem.id) 1439 .text(newItem.type); 1440 // Append the option to the other modal 1441 otherModalSelector.append(otherOption); 1442 } 1443
1443 } 1444 if (idOfModal == "create_pm_modal") { 1445 var dropdownSelector = $( 1446 'select[name="payment_method_id"]' 1447 ); 1448 if (dropdownSelector.length) { 1449 var newItem = result.pm; 1450 var newOption = $("<option></option>") 1451 .attr("value", newItem.id) 1452 .attr("selected", true) 1453 .text(newItem.title); 1454 $(dropdownSelector).append(newOption); 1455 $(dropdownSelector).trigger("change"); 1456 } 1457 } 1458 if (idOfModal == "create_allowance_modal") { 1459 var dropdownSelector = $( 1460 'select[name="allowance_id"]' 1461 ); 1462 if (dropdownSelector.length) { 1463 var newItem = result.allowance; 1464 var newOption = $("<option></option>") 1465 .attr("value", newItem.id) 1466 .attr("selected", true) 1467 .text(newItem.title); 1468 $(dropdownSelector).append(newOption); 1469 $(dropdownSelector).trigger("change"); 1470 } 1471 } 1472 if (idOfModal == "create_deduction_modal") { 1473 var dropdownSelector = $( 1474 'select[name="deduction_id"]' 1475 ); 1476 if (dropdownSelector.length) { 1477 var newItem = result.deduction; 1478 var newOption = $("<option></option>") 1479 .attr("value", newItem.id) 1480 .attr("selected", true) 1481 .text(newItem.title); 1482 $(dropdownSelector).append(newOption); 1483 $(dropdownSelector).trigger("change"); 1484 } 1485 } 1486 } 1487 toastr.success(result["message"]); 1488 } else { 1489 if (result.hasOwnProperty("message")) { 1490 toastr.success(result["message"]); 1491 // Show toastr for 3 seconds before reloading or redirecting 1492 setTimeout(handleRedirection, 3000); 1493 } else { 1494 handleRedirection(); 1495 } 1496 } 1497 } 1498 } 1499 }, 1500 error: function (xhr, status, error) { 1501 submit_btn.html(button_text); 1502 submit_btn.attr("disabled", false); 1503 1504 if (!navigator.onLine) { 1505 // Browser reports offline 1506 toastr.error("No internet connection. Please check your network."); 1507 return; 1508 } 1509 1510 if (xhr.status === 422) { 1511 // Handle validation errors here 1512 var response = xhr.responseJSON; // Assuming you're returning JSON 1513 if (response.error) { 1514 // Handle the general error message 1515 var generalErrorMessage = response.message; 1516 toastr.error(generalErrorMessage); 1517 } 1518 // You can access validation errors from the response object 1519 var errors = response.errors; 1520 for (var key in errors) { 1521 if ( 1522 errors.hasOwnProperty(key) && 1523 Array.isArray(errors[key]) 1524 ) {
1525 errors[key].forEach(function (error) { 1526 toastr.error(error); 1527 }); 1528 } 1529 } 1530 // Example: Display the first validation error message 1531 toastr.error(label_please_correct_errors); 1532 // Assuming you have a list of all input fields with error messages 1533 var inputFields = currentForm.find( 1534 "input[name], select[name], textarea[name]" 1535 ); 1536 inputFields = $(inputFields.toArray().reverse()); 1537 // Iterate through all input fields 1538 inputFields.each(function () { 1539 var inputField = $(this); 1540 var fieldName = inputField.attr("name"); 1541 var errorMessageElement; 1542 if (errors && errors[fieldName]) { 1543 if (inputField.closest(".input-group").length) { 1544 errorMessageElement = inputField 1545 .closest(".input-group") 1546 .next(".error-message"); 1547 if (errorMessageElement.length === 0) { 1548 errorMessageElement = $( 1549 '<span class="text-danger error-message"></span>' 1550 ); 1551 inputField 1552 .closest(".input-group") 1553 .after(errorMessageElement); 1554 } 1555 } else { 1556 errorMessageElement = inputField.next( 1557 ".text-danger.error-message" 1558 ); 1559 if (errorMessageElement.length === 0) { 1560 errorMessageElement = $( 1561 '<span class="text-danger error-message"></span>' 1562 ); 1563 inputField.after(errorMessageElement); 1564 } 1565 } 1566 errorMessageElement.text(errors[fieldName][0]); 1567 inputField[0].scrollIntoView({ 1568 behavior: "smooth", 1569 block: "start", 1570 }); 1571 inputField.focus(); 1572 } else { 1573 // If there is no validation error message, clear the existing message 1574 errorMessageElement = inputField.next(".error-message"); 1575 if (errorMessageElement.length === 0) { 1576 errorMessageElement = inputField 1577 .parent() 1578 .nextAll(".error-message") 1579 .first(); 1580 } 1581 if ( 1582 errorMessageElement && 1583 errorMessageElement.length > 0 1584 ) { 1585 errorMessageElement.remove(); 1586 } 1587 } 1588 }); 1589 } else { 1590 // Handle other errors (non-validation errors) here 1591 toastr.error(error); 1592 } 1593 }, 1594 }); 1595 function handleRedirection() { 1596 if (redirect_url === "") { 1597 window.location.reload(); // Reload the current page 1598 } else { 1599 window.location.href = redirect_url; // Redirect to specified URL 1600 } 1601 } 1602}); 1603// Click event handler for the favorite icon 1604$(document).on("click", ".favorite-icon", function () { 1605 var icon = $(this); 1606 var routePrefix = $(this).data("routePrefix"); 1607 var projectId = $(this).data("id"); 1608 var isFavorite = icon.attr("data-favorite"); 1609 isFavorite = isFavorite == 1 ? 0 : 1; 1610 var reload = $(this).data("require_reload") !== undefined ? 1 : 0; 1611 var dataTitle = icon.data("bs-original-title"); 1612 var temp = dataTitle !== undefined ? "data-bs-original-title" : "title"; 1613 // Send an AJAX request to update the favorite status 1614 $.ajax({ 1615 url: "/master-panel/projects/update-favorite/" + projectId, 1616 type: "POST", 1617 headers: { 1618 "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), 1619 }, 1620 data: { 1621 is_favorite: isFavorite, 1622 }, 1623 success: function (response) {
1624 if (reload) { 1625 location.reload(); 1626 } else { 1627 icon.attr("data-favorite", isFavorite); 1628 // Update the tooltip text 1629 if (isFavorite == 0) { 1630 icon.removeClass("bxs-star"); 1631 icon.addClass("bx-star"); 1632 icon.attr(temp, add_favorite); // Update the tooltip text 1633 toastr.success( 1634 label_project_removed_from_favorite_successfully 1635 ); 1636 } else { 1637 icon.removeClass("bx-star"); 1638 icon.addClass("bxs-star"); 1639 icon.attr(temp, remove_favorite); // Update the tooltip text 1640 toastr.success( 1641 label_project_marked_as_favorite_successfully 1642 ); 1643 } 1644 } 1645 }, 1646 error: function (data) { 1647 // Handle errors if necessary 1648 toastr.error(error); 1649 }, 1650 }); 1651}); 1652$(document).on("click", ".duplicate", function (e) { 1653 e.preventDefault(); 1654 var id = $(this).data("id"); 1655 var type = $(this).data("type"); 1656 var reload = $(this).data("reload"); // Get the value of data-reload attribute 1657 if (typeof reload !== "undefined" && reload === true) { 1658 reload = true; 1659 } else { 1660 reload = false; 1661 } 1662 var tableID = $(this).data("table") || "table"; 1663 $("#duplicateModal").modal("show"); // show the confirmation modal 1664 $("#duplicateModal").off("click", "#confirmDuplicate"); 1665 if (type != "estimates-invoices" && type != "payslips") { 1666 $("#duplicateModal").find("#titleDiv").removeClass("d-none"); 1667 var title = $(this).data("title"); 1668 $("#duplicateModal").find("#updateTitle").val(title); 1669 } else { 1670 $("#duplicateModal").find("#titleDiv").addClass("d-none"); 1671 } 1672 $("#duplicateModal").on("click", "#confirmDuplicate", function (e) { 1673 e.preventDefault(); 1674 var title = $("#duplicateModal").find("#updateTitle").val(); 1675 $("#confirmDuplicate").html(label_please_wait).attr("disabled", true); 1676 $.ajax({ 1677 url: 1678 "/master-panel/" + 1679 type + 1680 "/duplicate/" + 1681 id + 1682 "?reload=" + 1683 reload + 1684 "&title=" + 1685 title, 1686 type: "GET", 1687 headers: { 1688 "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), 1689 }, 1690 success: function (response) { 1691 $("#confirmDuplicate").html(label_yes).attr("disabled", false); 1692 $("#duplicateModal").modal("hide"); 1693 if (response.error == false) { 1694 if (reload) { 1695 location.reload(); 1696 } else { 1697 toastr.success(response.message); 1698 if (tableID) { 1699 $("#" + tableID).bootstrapTable("refresh"); 1700 } 1701 } 1702 } else { 1703 toastr.error(response.message); 1704 } 1705 }, 1706 error: function (data) { 1707 $("#confirmDuplicate").html(label_yes).attr("disabled", false); 1708 $("#duplicateModal").modal("hide"); 1709 var response = data.responseJSON; 1710 if (response.error) { 1711 toastr.error(response.message); 1712 } else { 1713 toastr.error(label_something_went_wrong); 1714 } 1715 }, 1716 }); 1717 }); 1718}); 1719$("#deduction_type").on("change", function (e) { 1720 if ($("#deduction_type").val() == "amount") { 1721 $("#amount_div").removeClass("d-none"); 1722 $("#percentage_div").addClass("d-none"); 1723 } else if ($("#deduction_type").val() == "percentage") { 1724 $("#amount_div").addClass("d-none"); 1725 $("#percentage_div").removeClass("d-none"); 1726 } else { 1727 $("#amount_div").addClass("d-none"); 1728 $("#percentage_div").addClass("d-none"); 1729 } 1730}); 1731$("#update_deduction_type").on("change", function (e) { 1732 if ($("#update_deduction_type").val() == "amount") { 1733 $("#update_amount_div").removeClass("d-none"); 1734 $("#update_percentage_div").addClass("d-none"); 1735 } else if ($("#update_deduction_type").val() == "percentage") { 1736 $("#update_amount_div").addClass("d-none"); 1737 $("#update_percentage_div").removeClass("d-none"); 1738 } else { 1739 $("#update_amount_div").addClass("d-none"); 1740 $("#update_percentage_div").addClass("d-none"); 1741 } 1742}); 1743if (document.getElementById("system-update-dropzone")) { 1744 var is_error = false;
1745 if (!$("#system-update").hasClass("dropzone")) { 1746 var systemDropzone = new Dropzone("#system-update-dropzone", { 1747 url: $("#system-update").attr("action"), 1748 paramName: "update_file", 1749 autoProcessQueue: false, 1750 parallelUploads: 1, 1751 maxFiles: 1, 1752 acceptedFiles: ".zip", 1753 timeout: 360000, 1754 autoDiscover: false, 1755 headers: { 1756 "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), // Pass the CSRF token as a header 1757 }, 1758 addRemoveLinks: true, 1759 dictRemoveFile: "x", 1760 dictMaxFilesExceeded: "Only 1 file can be uploaded at a time", 1761 dictResponseError: "Error", 1762 uploadMultiple: true, 1763 dictDefaultMessage: 1764 '<p><input type="button" value="Select Files" class="btn btn-primary" /><br> or <br> Drag & Drop System Update / Installable / Plugin\'s .zip file Here</p>', 1765 }); 1766 systemDropzone.on("addedfile", function (file) { 1767 var i = 0; 1768 if (this.files.length) { 1769 var _i, _len; 1770 for (_i = 0, _len = this.files.length; _i < _len - 1; _i++) { 1771 if ( 1772 this.files[_i].name === file.name && 1773 this.files[_i].size === file.size && 1774 this.files[_i].lastModifiedDate.toString() === 1775 file.lastModifiedDate.toString() 1776 ) { 1777 this.removeFile(file); 1778 i++; 1779 } 1780 } 1781 } 1782 }); 1783 systemDropzone.on("error", function (file, response) { }); 1784 systemDropzone.on("sending", function (file, xhr, formData) { 1785 formData.append("flash_message", 1); 1786 xhr.onreadystatechange = function (response) { 1787 // return; 1788 setTimeout(function () { 1789 location.reload(); 1790 }, 2000); 1791 }; 1792 }); 1793 $("#system_update_btn").on("click", function (e) { 1794 e.preventDefault(); 1795 if (is_error == false) { 1796 if (systemDropzone.files.length === 0) { 1797 // Show toast message if no file is selected 1798 toastr.error("Please select a file to upload."); 1799 setTimeout(function () { 1800 location.reload(); 1801 }, 2000); 1802 } 1803 $("#system_update_btn") 1804 .attr("disabled", true) 1805 .text(label_please_wait); 1806 systemDropzone.processQueue(); 1807 } 1808 }); 1809 } 1810} 1811if (document.getElementById("media-upload-dropzone")) { 1812 var is_error = false; 1813 var mediaDropzone = new Dropzone("#media-upload-dropzone", { 1814 url: $("#media-upload").attr("action"), 1815 paramName: "media_files", 1816 autoProcessQueue: false, 1817 timeout: 360000, 1818 autoDiscover: false, 1819 headers: { 1820 "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), // Pass the CSRF token as a header 1821 }, 1822 addRemoveLinks: true, 1823 dictRemoveFile: "x", 1824 dictResponseError: "Error", 1825 uploadMultiple: true, 1826 dictDefaultMessage: 1827 '<p><input type="button" value="Select" class="btn btn-primary" /><br> or <br> Drag & Drop Files Here</p>', 1828 }); 1829 mediaDropzone.on("addedfile", function (file) { 1830 var i = 0; 1831 if (this.files.length) { 1832 var _i, _len; 1833 for (_i = 0, _len = this.files.length; _i < _len - 1; _i++) { 1834 if ( 1835 this.files[_i].name === file.name && 1836 this.files[_i].size === file.size && 1837 this.files[_i].lastModifiedDate.toString() === 1838 file.lastModifiedDate.toString() 1839 ) { 1840 this.removeFile(file); 1841 i++; 1842 } 1843 } 1844 } 1845 }); 1846 mediaDropzone.on("error", function (file, response) { 1847 return; 1848 }); 1849 mediaDropzone.on("sending", function (file, xhr, formData) { 1850 var id = $("#media_type_id").val(); 1851 formData.append("flash_message", 1); 1852 formData.append("id", id); 1853 xhr.onreadystatechange = function (response) { 1854 setTimeout(function () { 1855 location.reload(); 1856 }, 2000); 1857 }; 1858 }); 1859 $("#upload_media_btn").on("click", function (e) { 1860 e.preventDefault(); 1861 if (mediaDropzone.getQueuedFiles().length > 0) { 1862 if (is_error == false) { 1863 $("#upload_media_btn") 1864 .attr("disabled", true) 1865 .text(label_please_wait); 1866 mediaDropzone.processQueue(); 1867 return; 1868 } 1869 } else { 1870 toastr.error("No file(s) chosen."); 1871 } 1872 }); 1873} 1874// Row-wise Select/Deselect All 1875$(".row-permission-checkbox").change(function () { 1876 var module = $(this).data("module"); 1877 var isChecked = $(this).prop("checked"); 1878 $(`.permission-checkbox[data-module="${module}"]`).prop( 1879 "checked", 1880 isChecked 1881 ); 1882}); 1883$("#selectAllColumnPermissions").change(function () { 1884 var isChecked = $(this).prop("checked"); 1885 $(".permission-checkbox").prop("checked", isChecked); 1886 if (isChecked) { 1887 $(".row-permission-checkbox").prop("checked", true).trigger("change"); // Check all row permissions when select all is checked 1888 } else { 1889 $(".row-permission-checkbox").prop("checked", false).trigger("change"); // Uncheck all row permissions when select all is unchecked 1890 } 1891 checkAllPermissions(); // Check all permissions 1892}); 1893// Select/Deselect All for Rows 1894$("#selectAllPermissions").change(function () { 1895 var isChecked = $(this).prop("checked"); 1896 $(".row-permission-checkbox").prop("checked", isChecked).trigger("change"); 1897}); 1898// Function to check/uncheck all permissions for a module 1899function checkModulePermissions(module) { 1900 var allChecked = true; 1901 $('.permission-checkbox[data-module="' + module + '"]').each(function () { 1902 if (!$(this).prop("checked")) { 1903 allChecked = false;
1904 } 1905 }); 1906 $("#selectRow" + module).prop("checked", allChecked); 1907} 1908// Function to check if all permissions are checked and select/deselect "Select all" checkbox 1909function checkAllPermissions() { 1910 var allPermissionsChecked = true; 1911 $(".permission-checkbox").each(function () { 1912 if (!$(this).prop("checked")) { 1913 allPermissionsChecked = false; 1914 } 1915 }); 1916 $("#selectAllColumnPermissions").prop("checked", allPermissionsChecked); 1917} 1918// Event handler for individual permission checkboxes 1919$(".permission-checkbox").on("change", function () { 1920 var module = $(this).data("module"); 1921 checkModulePermissions(module); 1922 checkAllPermissions(); 1923}); 1924// Event handler for "Select all" checkbox 1925$("#selectAllColumnPermissions").on("change", function () { 1926 var isChecked = $(this).prop("checked"); 1927 $(".permission-checkbox").prop("checked", isChecked); 1928}); 1929// Initial check for permissions on page load 1930$(".row-permission-checkbox").each(function () { 1931 var module = $(this).data("module"); 1932 checkModulePermissions(module); 1933}); 1934checkAllPermissions(); 1935$(document).ready(function () { 1936 $(".fixed-table-toolbar").each(function () { 1937 var $toolbar = $(this); 1938 var $data_type = $toolbar 1939 .closest(".table-responsive") 1940 .find("#data_type"); 1941 var $data_table = $toolbar 1942 .closest(".table-responsive") 1943 .find("#data_table"); 1944 var $save_column_visibility = $toolbar 1945 .closest(".table-responsive") 1946 .find("#save_column_visibility"); 1947 if ($data_type.length > 0) { 1948 var data_type = $data_type.val(); 1949 var data_table = $data_table.val() || "table"; 1950 // Create the "Delete selected" button 1951 if (window.location.href.includes("scheduler-statuses")) { 1952 var $deleteButton = ''; 1953 } else { 1954 var $deleteButton = $( 1955 '<div class="columns columns-left btn-group float-left action_delete_' + 1956 data_type.replace("-", "_") + 1957 '">' + 1958 '<button type="button" class="btn btn-outline-danger float-left delete-selected" data-type="' + 1959 data_type + 1960 '" data-table="' + 1961 data_table + 1962 '">' + 1963 '<i class="bx bx-trash"></i> ' + 1964 label_delete_selected + 1965 "</button>" + 1966 "</div>" 1967 ); 1968 } 1969 // Add the "Delete selected" button before the first element in the toolbar 1970 $toolbar.prepend($deleteButton); 1971 if (data_type == "tasks") { 1972 // Create the "Clear Filters" button 1973 var $clearFiltersButton = $( 1974 '<div class="columns columns-left btn-group float-left">' + 1975 '<button type="button" class="btn btn-outline-secondary clear-filters">' + 1976 '<i class="bx bx-x-circle"></i> ' + 1977 label_clear_filters + 1978 "</button>" + 1979 "</div>" 1980 ); 1981 $deleteButton.after($clearFiltersButton); 1982 } 1983 if ($save_column_visibility.length > 0) { 1984 var $savePreferencesButton = $( 1985 '<div class="columns columns-left btn-group float-left">' + 1986 '<button type="button" class="btn btn-outline-primary save-column-visibility" data-type="' + 1987 data_type + 1988 '" data-table="' + 1989 data_table + 1990 '">' + 1991 '<i class="bx bx-save"></i> ' + 1992 label_save_column_visibility + 1993 "</button>" + 1994 "</div>" 1995 ); 1996 $deleteButton.after($savePreferencesButton); 1997 } 1998 } 1999 }); 2000}); 2001$("#media_storage_type").on("change", function (e) { 2002 if ($("#media_storage_type").val() == "s3") { 2003 $(".aws-s3-fields").removeClass("d-none"); 2004 } else { 2005 $(".aws-s3-fields").addClass("d-none"); 2006 } 2007}); 2008$(document).on("click", ".edit-milestone", function () { 2009 var id = $(this).data("id"); 2010 var urlPrefix = window.location.pathname.split("/")[1]; 2011 $.ajax({ 2012 url: "/" + urlPrefix + "/projects/get-milestone/" + id, 2013 type: "get", 2014 headers: { 2015 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2016 }, 2017 dataType: "json", 2018 success: function (response) { 2019 var formattedStartDate = moment(response.ms.start_date).format( 2020 js_date_format 2021 ); 2022 var formattedEndDate = moment(response.ms.end_date).format( 2023 js_date_format 2024 ); 2025 $("#milestone_id").val(response.ms.id); 2026 $("#milestone_title").val(response.ms.title); 2027 $("#update_milestone_start_date").val(formattedStartDate); 2028 $("#update_milestone_end_date").val(formattedEndDate); 2029 $("#milestone_status").val(response.ms.status); 2030 $("#milestone_cost").val(response.ms.cost); 2031 $("#milestone_description").val(response.ms.description); 2032 $("#milestone_progress").val(response.ms.progress); 2033 $(".milestone-progress").text(response.ms.progress + "%"); 2034 }, 2035 }); 2036}); 2037// subscriptions start and end date 2038$(document).ready(function () { 2039 if ( 2040 window.location.href.includes("transactions") || 2041 window.location.href.includes("plans") || 2042 window.location.href.includes("customers") 2043 ) { 2044 var deleteBtn = $(".delete-selected"); 2045 // Hide the delete button 2046 deleteBtn.addClass("d-none"); 2047 } 2048}); 2049$(document).on("click", ".edit-expense-type", function () { 2050 var id = $(this).data("id"); 2051 $("#edit_expense_type_modal").modal("show"); 2052 var urlPrefix = window.location.pathname.split("/")[1]; 2053 $.ajax({
2054 url: "/" + urlPrefix + "/expenses/get-expense-type/" + id, 2055 type: "get", 2056 headers: { 2057 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2058 }, 2059 dataType: "json", 2060 success: function (response) { 2061 $("#update_expense_type_id").val(response.et.id); 2062 $("#expense_type_title").val(response.et.title); 2063 $("#expense_type_description").val(response.et.description); 2064 }, 2065 }); 2066}); 2067$(document).on("click", ".edit-expense", function () { 2068 var id = $(this).data("id"); 2069 $("#edit_expense_modal").modal("show"); 2070 var urlPrefix = window.location.pathname.split("/")[1]; 2071 $.ajax({ 2072 url: "/" + urlPrefix + "/expenses/get/" + id, 2073 type: "get", 2074 headers: { 2075 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2076 }, 2077 dataType: "json", 2078 success: function (response) { 2079 var formattedExpDate = moment(response.exp.expense_date).format( 2080 js_date_format 2081 ); 2082 var amount = parseFloat(response.exp.amount); 2083 $("#update_expense_id").val(response.exp.id); 2084 $("#expense_title").val(response.exp.title); 2085 $("#expense_type_id").val(response.exp.expense_type_id); 2086 $("#expense_user_id").val(response.exp.user_id); 2087 $("#expense_amount").val(amount.toFixed(decimal_points)); 2088 $("#update_expense_date").val(formattedExpDate); 2089 $("#expense_note").val(response.exp.note); 2090 }, 2091 }); 2092}); 2093$(document).on("click", ".edit-payment", function () { 2094 var id = $(this).data("id"); 2095 $("#edit_payment_modal").modal("show"); 2096 var urlPrefix = window.location.pathname.split("/")[1]; 2097 $.ajax({ 2098 url: "/" + urlPrefix + "/payments/get/" + id, 2099 type: "get", 2100 headers: { 2101 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2102 }, 2103 dataType: "json", 2104 success: function (response) { 2105 var formattedExpDate = moment(response.payment.payment_date).format( 2106 js_date_format 2107 ); 2108 var amount = parseFloat(response.payment.amount); 2109 $("#update_payment_id").val(response.payment.id); 2110 $("#payment_invoice_id").val(response.payment.invoice_id); 2111 $("#payment_amount").val(amount.toFixed(decimal_points)); 2112 $("#update_payment_date").val(formattedExpDate); 2113 $("#payment_note").val(response.payment.note); 2114 var userId = response.payment.user.id; 2115 var userName = 2116 response.payment.user.first_name + 2117 " " + 2118 response.payment.user.last_name; 2119 if ( 2120 $("#payment_user_id").find("option[value='" + userId + "']") 2121 .length 2122 ) { 2123 $("#payment_user_id").val(userId).trigger("change"); 2124 } else { 2125 var newOption = new Option(userName, userId, true, true); 2126 $("#payment_user_id").append(newOption).trigger("change"); 2127 } 2128 var pm_id = response.payment.payment_method.id; 2129 var pm_title = response.payment.payment_method.title; 2130 if ( 2131 $("#payment_pm_id").find("option[value='" + pm_id + "']").length 2132 ) { 2133 $("#payment_pm_id").val(pm_id).trigger("change"); 2134 } else { 2135 var newOption = new Option(pm_title, pm_id, true, true); 2136 $("#payment_pm_id").append(newOption).trigger("change"); 2137 } 2138 }, 2139 }); 2140}); 2141function initializeDateRangePicker(inputSelector) { 2142 var modalId = $(inputSelector).closest(".modal").attr("id"); 2143 $(inputSelector).daterangepicker({ 2144 alwaysShowCalendars: true, 2145 showCustomRangeLabel: true, 2146 minDate: moment($(inputSelector).val(), js_date_format), 2147 singleDatePicker: true, 2148 showDropdowns: true, 2149 autoUpdateInput: true, 2150 parentEl: "#" + modalId, 2151 locale: { 2152 cancelLabel: "Clear", 2153 format: js_date_format, 2154 }, 2155 }); 2156} 2157$(document).ready(function () { 2158 $("#togglePassword").on("click", function () { 2159 var passwordInput = $("#password"); 2160 var toggleButton = $(this); 2161 // Toggle password visibility 2162 if (passwordInput.attr("type") === "password") { 2163 passwordInput.attr("type", "text"); 2164 toggleButton.html('<i class="far fa-eye"></i>'); 2165 } else { 2166 passwordInput.attr("type", "password"); 2167 toggleButton.html('<i class="far fa-eye-slash"></i>'); 2168 } 2169 }); 2170}); 2171$(document).on("click", ".superadmin-login", function (e) { 2172 e.preventDefault(); 2173 $("#email").val("[email protected]"); 2174 $("#password").val("12345678"); 2175}); 2176$(document).on("click", ".admin-login", function (e) { 2177 e.preventDefault(); 2178 $("#email").val("[email protected]"); 2179 $("#password").val("12345678"); 2180}); 2181$(document).on("click", ".member-login", function (e) { 2182 e.preventDefault(); 2183 $("#email").val("[email protected]"); 2184 $("#password").val("12345678"); 2185}); 2186$(document).on("click", ".client-login", function (e) { 2187 e.preventDefault(); 2188 $("#email").val("[email protected]"); 2189 $("#password").val("12345678"); 2190}); 2191$("#show_password").on("click", function () { 2192 var eyeicon = $(this).find("i"); 2193 let password = document.getElementById("password"); 2194 if (password.type == "password") { 2195 password.type = "text"; 2196 eyeicon.removeClass("bx-hide"); 2197 eyeicon.addClass("bx-show"); 2198 } else { 2199 password.type = "password"; 2200 eyeicon.removeClass("bx-show"); 2201 eyeicon.addClass("bx-hide"); 2202 } 2203}); 2204$("#show_confirm_password").on("click", function () { 2205 var eyeicon = $(this).find("i");
2206 let confirm_password = document.getElementById("password_confirmation"); 2207 if (confirm_password.type == "password") { 2208 confirm_password.type = "text"; 2209 eyeicon.removeClass("bx-hide"); 2210 eyeicon.addClass("bx-show"); 2211 } else { 2212 confirm_password.type = "password"; 2213 eyeicon.removeClass("bx-show"); 2214 eyeicon.addClass("bx-hide"); 2215 } 2216}); 2217$(".min_0").on("change", function () { 2218 var amount = $(this).val(); 2219 if (amount < 0) { 2220 $(this).val(""); 2221 toastr.error(label_min_0); 2222 } else { 2223 // Clear error message if the value is valid 2224 } 2225}); 2226$(".max_100").on("change", function () { 2227 var percentage = $(this).val(); 2228 if (percentage > 100) { 2229 toastr.error(lable_max_100); 2230 } else { 2231 // Clear error message if the value is valid 2232 } 2233}); 2234function clearModalContents($modal) { 2235 // Clear all input fields 2236 $modal.find('input:not([type="hidden"])').each(function () { 2237 if ( 2238 $(this).attr("type") === "checkbox" || 2239 $(this).attr("type") === "radio" 2240 ) { 2241 $(this).prop("checked", false); 2242 } else { 2243 $(this).val(""); 2244 } 2245 }); 2246 // Clear all textarea fields 2247 $modal.find("textarea").val(""); 2248 // Reset all select elements 2249 $modal.find("select").prop("selectedIndex", 0); 2250 // Clear any error messages or validation states 2251 $modal 2252 .find(".error-message") 2253 .removeClass("text-danger") 2254 .closest("p") 2255 .text(""); 2256 // Reset Select2 elements 2257 $modal.find("select").each(function () { 2258 if ($(this).data("select2")) { 2259 $(this).val(null).trigger("change"); 2260 } 2261 }); 2262 // Reset the form inside the modal 2263 $modal.find("form").trigger("reset"); 2264} 2265// Usage for all modals 2266$(document).on("hidden.bs.modal", ".modal", function () { 2267 // var $modal = $(this); 2268 // if ($modal.attr('id') !== 'timerModal') { 2269 // clearModalContents($modal); 2270 // } 2271 var modalId = $(this).attr("id"); 2272 var $form = $(this).find("form"); // Find the form inside the modal 2273 $form.trigger("reset"); // Reset the form 2274 $form.find(".error-message").html(""); 2275 var partialLeaveCheckbox = $("#partialLeave"); 2276 if (partialLeaveCheckbox.length) { 2277 partialLeaveCheckbox.trigger("change"); 2278 } 2279 var leaveVisibleToAllCheckbox = $form.find(".leaveVisibleToAll"); 2280 if (leaveVisibleToAllCheckbox.length) { 2281 leaveVisibleToAllCheckbox.trigger("change"); 2282 } 2283 var defaultColor = 2284 modalId == "create_note_modal" || modalId == "edit_note_modal" 2285 ? "success" 2286 : "primary"; 2287 var colorSelect = $form.find('select[name="color"]'); 2288 if (colorSelect.length) { 2289 var classes = colorSelect.attr("class").split(" "); 2290 var currentColorClass = classes.filter(function (className) { 2291 return className.startsWith("select-"); 2292 })[0]; 2293 } 2294 colorSelect 2295 .removeClass(currentColorClass) 2296 .addClass("select-bg-label-" + defaultColor); 2297 $form.find(".js-example-basic-multiple").trigger("change"); 2298 if ($('.selectTaskProject[name="project"]').length) { 2299 $form.find($('.selectTaskProject[name="project"]')).trigger("change"); 2300 } 2301 if ($('.selectLruser[name="user_id"]').length) { 2302 $form.find($('.selectLruser[name="user_id"]')).trigger("change"); 2303 } 2304 if ($("#users_associated_with_project").length) { 2305 $("#users_associated_with_project").text(""); 2306 } 2307 if ($("#task_update_users_associated_with_project").length) { 2308 $("#task_update_users_associated_with_project").text(""); 2309 } 2310 $form.find("#reminder-settings").addClass("d-none"); 2311 $form.find("#edit-reminder-settings").addClass("d-none"); 2312 $form.find("#reminder-settings").find("input").prop("checked", false); 2313 $form.find("#edit-reminder-settings").find("input").prop("checked", false); 2314 $form.find("#recurring-task-settings").addClass("d-none"); 2315 $form.find("#edit-recurring-task-settings").addClass("d-none"); 2316 $form.find("#recurring-task-settings").find("input").prop("checked", false); 2317 $form.find("#edit-recurring-task-settings").find("input").prop("checked", false); 2318 resetDateFields($form); 2319}); 2320$(document).on("click", "#mark-all-notifications-as-read", function (e) { 2321 e.preventDefault(); 2322 $("#mark_all_notifications_as_read_modal").modal("show"); // show the confirmation modal 2323 $("#mark_all_notifications_as_read_modal").on( 2324 "click", 2325 "#confirmMarkAllAsRead", 2326 function () { 2327 $("#confirmMarkAllAsRead") 2328 .html(label_please_wait) 2329 .attr("disabled", true); 2330 $.ajax({ 2331 url: "/master-panel/notifications/mark-all-as-read", 2332 type: "PUT", 2333 headers: { 2334 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2335 }, 2336 success: function (response) { 2337 location.reload(); 2338 // $('#confirmMarkAllAsRead').html(label_yes).attr('disabled', false); 2339 }, 2340 }); 2341 } 2342 ); 2343}); 2344 2345$(document).on("click", ".notification-open-popup", function (e) { 2346 e.preventDefault(); 2347 var $this = $(this); 2348 var title = $this.data('title'); 2349 var message = $this.data('message'); 2350 var date = $this.data('date'); 2351 var url = $this.data('url'); 2352 2353 $('#notificationModalTitle').html(title); 2354 $('#notificationModalMessage').text(message); 2355 $('#notificationModalDate').text(date); 2356 $('#notificationModalLink').attr('href', url); 2357 2358 $('#notificationDetailModal').modal('show'); 2359 2360 // if ($('#table').length) { 2361 // $('#table').bootstrapTable('refresh'); 2362 // } 2363 2364 var notificationId = $this.data("id"); 2365 var needConfirm = $this.data("needconfirm") || false; 2366 performUpdate(notificationId, needConfirm, $this); 2367}); 2368 2369$(document).on("click", ".update-notification-status", function (e) { 2370 var $this = $(this); 2371 2372 if ($this.hasClass('dropdown-item')) { 2373 e.preventDefault(); 2374 var title = $this.data('title'); 2375 var message = $this.data('message'); 2376 var date = $this.data('date'); 2377 var url = $this.data('url'); 2378 2379 $('#notificationModalTitle').text(title); 2380 $('#notificationModalMessage').text(message); 2381 $('#notificationModalDate').text(date); 2382 $('#notificationModalLink').attr('href', url); 2383 2384 $('#notificationDetailModal').modal('show'); 2385 // if ($('#table').length) { 2386 // $('#table').bootstrapTable('refresh'); 2387 // } 2388 } 2389 2390 var notificationId = $this.data("id"); 2391 var needConfirm = true; 2392 2393 /*if (needConfirm) { 2394 // Show the confirmation modal 2395 $("#update_notification_status_modal").modal("show"); 2396 // Attach click event handler to the confirmation button 2397 $("#update_notification_status_modal").off( 2398 "click", 2399 "#confirmNotificationStatus" 2400 ); 2401 $("#update_notification_status_modal").on( 2402 "click", 2403 "#confirmNotificationStatus", 2404 function () { 2405 $("#confirmNotificationStatus") 2406 .html(label_please_wait) 2407 .attr("disabled", true); 2408 performUpdate(notificationId, needConfirm, $this); 2409 } 2410 ); 2411 } else {*/ 2412 // If confirmation is not needed, directly perform the update and handle response 2413 performUpdate(notificationId, needConfirm, $this); 2414 //} 2415}); 2416function performUpdate(notificationId, needConfirm = "", $element = null) { 2417 $.ajax({ 2418 url: "/master-panel/notifications/update-status", 2419 type: "PUT", 2420 data: { id: notificationId, needConfirm: needConfirm }, 2421 headers: { 2422 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2423 }, 2424 success: function (response) { 2425 if (response.error == false && response.unread_count !== undefined) { 2426 let countElem = $('#unreadNotificationsCount'); 2427 countElem.text(response.unread_count); 2428 if (response.unread_count > 0) { 2429 countElem.removeClass('d-none'); 2430 } else { 2431 countElem.addClass('d-none'); 2432 } 2433 } 2434 2435 if (needConfirm) { 2436 $("#confirmNotificationStatus") 2437 .html(label_yes) 2438 .attr("disabled", false); 2439 if (response.error == false) { 2440 toastr.success(response.message); 2441 $("#table").bootstrapTable("refresh"); 2442 } else { 2443 toastr.error(response.message); 2444 } 2445 $("#update_notification_status_modal").modal("hide"); 2446 } else { 2447 if (response.error == false) { 2448 if ($element && $element.hasClass('dropdown-item')) { 2449 $element.removeClass('update-notification-status'); 2450 } 2451 if ($('#table').length) { 2452 $('#table').bootstrapTable('refresh'); 2453 } 2454 } 2455 } 2456 }, 2457 }); 2458} 2459 2460$( 2461 "textarea#email_verify_email,textarea#email_account_creation,textarea#email_forgot_password,textarea#email_project_assignment,textarea#email_task_assignment,textarea#email_workspace_assignment,textarea#email_meeting_assignment,textarea#email_leave_request_creation,textarea#email_leave_request_status_updation,textarea#email_project_status_updation,textarea#email_task_status_updation,textarea#email_team_member_on_leave_alert,textarea#email_project_issue_assignment,textarea#email_announcement,textarea#email_task_reminder,textarea#email_recurring_task" 2462).tinymce({ 2463 height: 821, 2464 menubar: true, 2465 plugins: [ 2466 "link", 2467 "a11ychecker", 2468 "advlist", 2469 "advcode", 2470 "advtable", 2471 "autolink", 2472 "checklist", 2473 "export", 2474 "lists", 2475 "link", 2476 "image", 2477 "charmap", 2478 "preview", 2479 "anchor", 2480 "searchreplace", 2481 "visualblocks", 2482 "powerpaste", 2483 "fullscreen", 2484 "formatpainter", 2485 "insertdatetime", 2486 "media", 2487 "table", 2488 "help", 2489 "wordcount", 2490 "emoticons", 2491 "code", 2492 ], 2493 toolbar: false, 2494 // toolbar: 'link | undo redo | a11ycheck casechange blocks | bold italic backcolor | alignleft aligncenter alignright al
2494ignjustify | bullist numlist checklist outdent indent | removeformat | code blockquote emoticons table help' 2495}); 2496// Handle click event on toolbar items 2497$(".tox-tbtn").click(function () { 2498 // Get the current editor instance 2499 var editor = tinyMCE.activeEditor; 2500 // Close any open toolbar dropdowns 2501 tinymce.ui.Factory.each(function (ctrl) { 2502 if (ctrl.type === "toolbarbutton" && ctrl.settings.toolbar) { 2503 if (ctrl !== this && ctrl.settings.toolbar === "toolbox") { 2504 ctrl.panel.hide(); 2505 } 2506 } 2507 }, editor); 2508 // Execute the action associated with the clicked toolbar item 2509 editor.execCommand("mceInsertContent", false, "Clicked!"); 2510}); 2511$(document).on("click", ".restore-default", function (e) { 2512 e.preventDefault(); 2513 var form = $(this).closest("form"); 2514 var type = form.find('input[name="type"]').val(); 2515 var name = form.find('input[name="name"]').val(); 2516 var textarea = type + "_" + name; 2517 $("#restore_default_modal").modal("show"); // show the confirmation modal 2518 $("#restore_default_modal").off("click", "#confirmRestoreDefault"); 2519 $("#restore_default_modal").on( 2520 "click", 2521 "#confirmRestoreDefault", 2522 function () { 2523 $("#confirmRestoreDefault") 2524 .html(label_please_wait) 2525 .attr("disabled", true); 2526 $.ajax({ 2527 url: "/superadmin/settings/get-default-template", 2528 type: "POST", 2529 data: { type: type, name: name }, 2530 headers: { 2531 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2532 }, 2533 dataType: "json", 2534 success: function (response) { 2535 $("#confirmRestoreDefault") 2536 .html(label_yes) 2537 .attr("disabled", false); 2538 $("#restore_default_modal").modal("hide"); 2539 if (response.error == false) { 2540 tinymce.get(textarea).setContent(response.content); 2541 toastr.success(response.message); 2542 } else { 2543 toastr.error(response.message); 2544 } 2545 }, 2546 }); 2547 } 2548 ); 2549}); 2550$(document).on("click", ".sms-restore-default", function (e) { 2551 e.preventDefault(); 2552 var form = $(this).closest("form"); 2553 var type = form.find('input[name="type"]').val(); 2554 var name = form.find('input[name="name"]').val(); 2555 var textarea = type + "_" + name; 2556 $("#restore_default_modal").modal("show"); // show the confirmation modal 2557 $("#restore_default_modal").off("click", "#confirmRestoreDefault"); 2558 $("#restore_default_modal").on( 2559 "click", 2560 "#confirmRestoreDefault", 2561 function () { 2562 $("#confirmRestoreDefault") 2563 .html(label_please_wait) 2564 .attr("disabled", true); 2565 $.ajax({ 2566 url: "/superadmin/settings/get-default-template", 2567 type: "POST", 2568 data: { type: type, name: name }, 2569 headers: { 2570 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2571 }, 2572 dataType: "json", 2573 success: function (response) { 2574 $("#confirmRestoreDefault") 2575 .html(label_yes) 2576 .attr("disabled", false); 2577 $("#restore_default_modal").modal("hide"); 2578 if (response.error == false) { 2579 $("#" + textarea).val(response.content); 2580 toastr.success(response.message); 2581 } else { 2582 toastr.error(response.message); 2583 } 2584 }, 2585 }); 2586 } 2587 ); 2588}); 2589$(document).on("click", ".edit-language", function () { 2590 var id = $(this).data("id"); 2591 $("#edit_language_modal").modal("show"); 2592 $.ajax({ 2593 url: "/superadmin/settings/languages/get/" + id, 2594 type: "get", 2595 headers: { 2596 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2597 }, 2598 dataType: "json", 2599 success: function (response) { 2600 $("#language_id").val(response.language.id); 2601 $("#language_title").val(response.language.name); 2602 }, 2603 }); 2604}); 2605$(document).on("click", ".edit-priority", function () { 2606 var id = $(this).data("id"); 2607 $("#edit_priority_modal").modal("show"); 2608 var classes = $("#priority_color").attr("class").split(" "); 2609 var currentColorClass = classes.filter(function (className) { 2610 return className.startsWith("select-"); 2611 })[0]; 2612 $.ajax({ 2613 url: "/master-panel/priority/get/" + id, 2614 type: "get", 2615 headers: { 2616 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 2617 }, 2618 dataType: "json", 2619 success: function (response) { 2620 $("#priority_id").val(response.priority.id); 2621 $("#priority_title").val(response.priority.title); 2622 $("#priority_color") 2623 .val(response.priority.color) 2624 .removeClass(currentColorClass) 2625 .addClass("select-bg-label-" + response.priority.color); 2626 }, 2627 }); 2628}); 2629$(document).on("click", ".openCreateStatusModal", function (e) { 2630 e.preventDefault(); 2631 $("#create_status_modal").modal("show"); 2632}); 2633$(document).on("click", ".openCreatePriorityModal", function (e) { 2634 e.preventDefault(); 2635 $("#create_priority_modal").modal("show"); 2636}); 2637$(document).on("click", ".openCreateTagModal", function (e) { 2638 e.preventDefault(); 2639 $("#create_tag_modal").modal("show"); 2640}); 2641$(document).ready(function () { 2642 function formatTag(tag) { 2643 if (!tag.id) { 2644 return tag.text; 2645 }
2646 var color = $(tag.element).data("color"); 2647 var $tag = $( 2648 '<span class="badge bg-label-' + color + '">' + tag.text + "</span>" 2649 ); 2650 return $tag; 2651 } 2652 function formatStatus(status) { 2653 if (!status.id) { 2654 return status.text; 2655 } 2656 var color = $(status.element).data("color"); 2657 var $status = $( 2658 '<span class="badge bg-label-' + 2659 color + 2660 '">' + 2661 status.text + 2662 "</span>" 2663 ); 2664 return $status; 2665 } 2666 function formatPriority(priority) { 2667 if (!priority.id) { 2668 return priority.text; 2669 } 2670 var color = $(priority.element).data("color"); 2671 var $priority = $( 2672 '<span class="badge bg-label-' + 2673 color + 2674 '">' + 2675 priority.text + 2676 "</span>" 2677 ); 2678 return $priority; 2679 } 2680 if ($(".tagsDropdown").length) { 2681 $(".tagsDropdown").select2({ 2682 templateResult: formatTag, 2683 templateSelection: formatTag, 2684 escapeMarkup: function (markup) { 2685 return markup; 2686 }, 2687 }); 2688 } 2689 $(".statusDropdown").each(function () { 2690 var $this = $(this); 2691 $this.select2({ 2692 dropdownParent: $this.closest(".modal"), 2693 templateResult: formatStatus, 2694 templateSelection: formatStatus, 2695 escapeMarkup: function (markup) { 2696 return markup; 2697 }, 2698 }); 2699 }); 2700 $(".priorityDropdown").each(function () { 2701 var $this = $(this); 2702 $this.select2({ 2703 dropdownParent: $this.closest(".modal"), 2704 templateResult: formatPriority, 2705 templateSelection: formatPriority, 2706 allowClear: true, 2707 escapeMarkup: function (markup) { 2708 return markup; 2709 }, 2710 language: { 2711 noResults: function () { 2712 return label_no_results_found; 2713 }, 2714 searching: function () { 2715 return label_searching; 2716 }, 2717 }, 2718 }); 2719 // Prevent dropdown from opening when clear button is clicked 2720 $this 2721 .on("select2:unselecting", function (e) { 2722 $(this).data("state", "unselecting"); 2723 }) 2724 .on("select2:open", function (e) { 2725 if ($(this).data("state") === "unselecting") { 2726 $(this).removeData("state"); 2727 $this.select2("close"); // Close the dropdown immediately 2728 } 2729 }); 2730 }); 2731 $(".selectTaskProject").each(function () { 2732 var $this = $(this); 2733 $this.select2({ 2734 dropdownParent: $this.closest(".modal"), 2735 }); 2736 }); 2737}); 2738$(document).on("click", ".edit-project", function () { 2739 var id = $(this).data("id"); 2740 $("#edit_project_modal").modal("show"); 2741 $.ajax({ 2742 url: "/master-panel/projects/get/" + id, 2743 type: "get", 2744 headers: { 2745 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2746 }, 2747 dataType: "json", 2748 success: function (response) { 2749 var formattedStartDate = moment(response.project.start_date).format( 2750 js_date_format 2751 ); 2752 var formattedEndDate = moment(response.project.end_date).format( 2753 js_date_format 2754 ); 2755 var $modal = $("#edit_project_modal"); // Cache the modal element for better performance 2756 $("#project_id").val(response.project.id); 2757 $("#project_title").val(response.project.title); 2758 $modal 2759 .find("#project_status_id") 2760 .val(response.project.status_id) 2761 .trigger("change"); 2762 $modal 2763 .find("#project_priority_id") 2764 .val(response.project.priority_id) 2765 .trigger("change"); 2766 $("#project_budget").val(response.project.budget); 2767 $("#update_start_date").val(formattedStartDate); 2768 $("#update_end_date").val(formattedEndDate); 2769 initializeDateRangePicker("#update_start_date, #update_end_date"); 2770 $("#task_accessiblity").val(response.project.task_accessiblity); 2771 $("#edit_tasks_time_entries").prop( 2772 "checked", 2773 Boolean(response.project.enable_tasks_time_entries) 2774 ); 2775 $("#project_description").val(response.project.description); 2776 $("#projectNote").val(response.project.note); 2777 // Populate project users in the multi-select dropdown 2778 var usersSelect = $("#edit_project_modal").find( 2779 '.js-example-basic-multiple[name="user_id[]"]' 2780 ); 2781 // Preselect project users if they exist 2782 var projectUsers = response.users.map((user) => user.id); 2783 usersSelect.val(projectUsers); 2784 usersSelect.trigger("change"); // Trigger change event to update select2 2785 var clientsSelect = $("#edit_project_modal").find( 2786 '.js-example-basic-multiple[name="client_id[]"]' 2787 ); 2788 var projectClients = response.clients.map((client) => client.id); 2789 clientsSelect.val(projectClients); 2790 clientsSelect.trigger("change"); // Trigger change event to update select2 2791 var tagsSelect = $("#edit_project_modal").find( 2792 '[name="tag_ids[]"]' 2793 ); 2794 var projectTags = response.tags.map((tag) => tag.id); 2795 // Select old tags 2796 tagsSelect.val(projectTags); 2797 // Trigger change event to update Select2 2798 tagsSelect.trigger("change.select2"); 2799 }, 2800 error: function (xhr, status, error) { 2801 console.error(error); 2802 }, 2803 }); 2804}); 2805$(document).on("click", "#set-default-view", function (e) { 2806 e.preventDefault(); 2807 var type = $(this).data("type"); 2808 var view = $(this).data("view"); 2809 var url = "/master-panel/save-" + type + "-view-preference"; 2810 $("#set_default_view_modal").modal("show"); 2811 $("#set_default_view_modal").off("click", "#confirm"); 2812 $("#set_default_view_modal").on("click", "#confirm", function () { 2813 $("#set_default_view_modal") 2814 .find("#confirm") 2815 .html(label_please_wait) 2816 .attr("disabled", true); 2817 $.ajax({ 2818 url: url, 2819 type: "PUT", 2820 headers: { 2821 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2822 }, 2823 data: { 2824 type: type, 2825 view: view, 2826 }, 2827 success: function (response) { 2828 $("#set_default_view_modal") 2829 .find("#confirm") 2830 .html(label_yes) 2831 .attr("disabled", false); 2832 if (response.error == false) { 2833 $("#set-default-view") 2834 .text(label_default_view) 2835 .removeClass("bg-secondary") 2836 .addClass("bg-primary"); 2837 $("#set_default_view_modal").modal("hide"); 2838 toastr.success(response.message); 2839 } else { 2840 toastr.error(response.message); 2841 } 2842 }, 2843 }); 2844 }); 2845}); 2846//task project select 2847$(document).ready(function () { 2848 $('.selectTaskProject[name="project"]').on("change", function (e) { 2849 var projectId = $(this).val(); 2850 if (projectId) { 2851 $.ajax({ 2852 url: "/master-panel/projects/get/" + projectId, 2853 type: "GET", 2854 success: function (response) { 2855 $("#users_associated_with_project").html( 2856 "(" + 2857 label_users_associated_with_project + 2858 " <strong>" + 2859 response.project.title + 2860 "</strong>)" 2861 ); 2862 var usersSelect = $( 2863 '.js-example-basic-multiple[name="users_id[]"]' 2864 ); 2865 usersSelect.empty(); // Clear existing options 2866 // Check if task_accessibility is 'project_users' 2867 $.each(response.users, function (index, user) { 2868 var option = $("<option>", { 2869 value: user.id, 2870 text: user.first_name + " " + user.last_name, 2871 }); 2872 usersSelect.append(option); 2873 }); 2874 if ( 2875 response.project.task_accessibility == "project_users" 2876 ) { 2877 var taskUsers = response.users.map((user) => user.id); 2878 usersSelect.val(taskUsers); 2879 } else { 2880 usersSelect.val(authUserId); 2881 } 2882 usersSelect.trigger("change"); 2883 2884 var taskLists = $('#task_list'); 2885 taskLists.empty(); // Clear existing options 2886 // Check if task_accessibility is 'project_users' 2887 $.each(response.task_lists, function (index, taskList) { 2888 var option = $("<option>", { 2889 value: taskList.id, 2890 text: taskList.name, 2891 }); 2892 taskLists.append(option); 2893 }); 2894 if (response.task_lists.length == 0) { 2895 var option = $("<option>", { 2896 value: '', 2897 text: label_no_task_list, 2898 }); 2899 taskLists.append(option); 2900 } 2901 2902 2903 }, 2904 error: function (xhr, status, error) { 2905 console.error(error); 2906 }, 2907 }); 2908 } 2909 }); 2910}); 2911$(document).on("click", ".quick-view", function (e) { 2912 e.preventDefault(); 2913 var id = $(this).data("id"); 2914 var type = $(this).data("type") || "task"; 2915 $("#type").val(type); 2916 $("#typeId").val(id); 2917 $.ajax({ 2918 url: "/master-panel/" + type + "s/get/" + id, 2919 type: "GET", 2920 success: function (response) { 2921 if (response.error == false) { 2922 $("#quickViewModal").modal("show"); 2923 if (type == "task" && response.task) { 2924 $("#quickViewTitlePlaceholder").text(response.task.title); 2925 $("#quickViewDescPlaceholder").html( 2926 response.task.description 2927 ); 2928 } else if (type == "project" && response.project) { 2929 $("#quickViewTitlePlaceholder").text( 2930 response.project.title 2931 ); 2932 $("#quickViewDescPlaceholder").html( 2933 response.project.description 2934 ); 2935 } 2936 $("#typePlaceholder").text( 2937 type == "task" ? label_task : label_project 2938 ); 2939 $("#usersTable").bootstrapTable("refresh"); 2940 $("#clientsTable").bootstrapTable("refresh"); 2941 } else { 2942 toastr.error(response.message); 2943 } 2944 }, 2945 error: function (xhr, status, error) { 2946 // Handle error 2947 toastr.error("Something Went Wrong"); 2948 }, 2949 }); 2950}); 2951//edit task modal 2952$(document).on("click", ".edit-task", function () { 2953 var id = $(this).data("id"); 2954 $("#edit_task_modal").modal("show"); 2955 $.ajax({ 2956 url: "/master-panel/tasks/get/" + id, 2957 type: "get", 2958 headers: { 2959 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 2960 }, 2961 dataType: "json", 2962 success: function (response) { 2963 console.log(response); 2964 var formattedStartDate = moment(response.task.start_date).format( 2965 js_date_format 2966 ); 2967 var formattedEndDate = moment(response.task.end_date).format( 2968 js_date_format 2969 ); 2970 $("#task_update_users_associated_with_project").html( 2971 "(" + 2972 label_users_associated_with_project + 2973 " <strong>" + 2974 response.project.title + 2975 "</strong>)" 2976 ); 2977 $("#id").val(response.task.id); 2978 $("#title").val(response.task.title); 2979 $("#task_status_id").val(response.task.status_id).trigger("change"); 2980 $("#priority_id").val(response.task.priority_id).trigger("change"); 2981 $("#update_start_date").val(formattedStartDate); 2982 $("#update_end_date").val(formattedEndDate); 2983 initializeDateRangePicker("#update_start_date, #update_end_date"); 2984 $("#update_project_title").val(response.project.title); 2985 $("#task_description").val(response.task.description); 2986 $("#taskNote").val(response.task.note); 2987 $("#edit_billing_type") 2988 .val(response.task.billing_type) 2989 .trigger("change"); 2990 $("#edit_completion_percentage") 2991 .val(response.task.completion_percentage) 2992 .trigger("change"); 2993 // Populate project users in the multi-select dropdown 2994 var usersSelect = $("#edit_task_modal").find( 2995 '.js-example-basic-multiple[name="user_id[]"]' 2996 ); 2997 usersSelect.empty(); // Clear existing options 2998 $.each(response.project.users, function (index, user) { 2999 var option = $("<option>", { 3000 value: user.id, 3001 text: user.first_name + " " + user.last_name, 3002 }); 3003 usersSelect.append(option); 3004 }); 3005 // Preselect task users if they exist 3006 var taskUsers = response.task.users.map((user) => user.id); 3007 usersSelect.val(taskUsers); 3008 usersSelect.trigger("change"); // Trigger change event to update select2 3009 3010 // Populate reminders 3011 if (response.task.reminders && response.task.reminders.length > 0) { 3012 const reminder = response.task.reminders[0]; 3013 console.log(reminder); 3014 3015 // Set reminder switch 3016 $('#edit-reminder-switch').prop('checked', reminder.is_active === 1); 3017 3018 // Show reminder settings if active 3019 if (reminder.is_active === 1) { 3020 $('#edit-reminder-settings').removeClass('d-none'); 3021 } else { 3022 $('#edit-reminder-settings').addClass('d-none'); 3023 } 3024 3025 // Set frequency type 3026 $('#edit-frequency-type').val(reminder.frequency_type).trigger('change'); 3027 3028 // Handle visibility and values for day selectors based on frequency type 3029 switch (reminder.frequency_type) { 3030 case 'weekly': 3031 $('#edit-day-of-week-group').removeClass('d-none'); 3032 $('#edit-day-of-month-group').addClass('d-none'); 3033 $('#edit-day-of-week').val(reminder.day_of_week || ''); 3034 break; 3035 case 'monthly': 3036 $('#edit-day-of-month-group').removeClass('d-none'); 3037 $('#edit-day-of-week-group').addClass('d-none'); 3038 $('#edit-day-of-month').val(reminder.day_of_month || ''); 3039 break; 3040 default: // daily 3041 $('#edit-day-of-week-group').addClass('d-none'); 3042 $('#edit-day-of-month-group').addClass('d-none'); 3043 } 3044 3045 // Set time of day 3046 // Convert the time string to correct format for input type="time" 3047 const timeOfDay = reminder.time_of_day.slice(0, 5); // Get HH:mm from HH:mm:ss 3048 $('#edit-time-of-day').val(timeOfDay); 3049 } 3050 3051 // Populate recurring task settings 3052 if (response.task.recurring_task) { 3053 const recurring_task = response.task.recurring_task; 3054 3055 3056
3056 // Set recurring task switch 3057 $('#edit-recurring-task-switch').prop('checked', recurring_task.is_active === 1); 3058 3059 // Show recurring task settings if active 3060 if (recurring_task.is_active === 1) { 3061 $('#edit-recurring-task-settings').removeClass('d-none'); 3062 } else { 3063 $('#edit-recurring-task-settings').addClass('d-none'); 3064 } 3065 3066 // Set frequency type 3067 $('#edit-recurrence-frequency').val(recurring_task.frequency).trigger('change'); 3068 3069 // Handle visibility and values for day selectors based on frequency type 3070 switch (recurring_task.frequency) { 3071 case 'weekly': 3072 $('#edit-recurrence-day-of-week-group').removeClass('d-none'); 3073 $('#edit-recurrence-day-of-month-group').addClass('d-none'); 3074 $('#edit-recurrence-day-of-week').val(recurring_task.day_of_week || ''); 3075 break; 3076 case 'monthly': 3077 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 3078 $('#edit-recurrence-day-of-week-group').addClass('d-none'); 3079 $('#edit-recurrence-day-of-month').val(recurring_task.day_of_month || ''); 3080 break; 3081 case 'yearly': 3082 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 3083 $('#edit-recurrence-day-of-week-group').addClass('d-none'); 3084 $('#edit-recurrence-day-of-month').val(recurring_task.day_of_month || ''); 3085 $('#edit-recurrence-month-of-year-group').removeClass('d-none'); 3086 $('#edit-recurrence-month-of-year').val(recurring_task.month_of_year || ''); 3087 break; 3088 default: // daily 3089 $('#edit-recurrence-day-of-week-group').addClass('d-none'); 3090 $('#edit-recurrence-day-of-month-group').addClass('d-none'); 3091 $('#edit-recurrence-month-of-year-group').addClass('d-none'); 3092 } 3093 3094 // Starts From and Number of Occuerences 3095 $('#edit-recurrence-starts-from').val(recurring_task.starts_from); 3096 $('#edit-recurrence-occurrences').val(recurring_task.number_of_occurrences); 3097 } 3098 }, 3099 error: function (xhr, status, error) { 3100 console.error(error); 3101 }, 3102 }); 3103}); 3104// Column Visibility 3105$(document).on("click", ".save-column-visibility", function (e) { 3106 e.preventDefault(); 3107 var tableName = $(this).data("table"); 3108 var type = $(this).data("type"); 3109 type = type.replace(/-/g, "_"); // This replaces all hyphens with underscores 3110 $("#confirmSaveColumnVisibility").modal("show"); 3111 $("#confirmSaveColumnVisibility").off("click", "#confirm"); 3112 $("#confirmSaveColumnVisibility").on("click", "#confirm", function () { 3113 $("#confirmSaveColumnVisibility") 3114 .find("#confirm") 3115 .html(label_please_wait) 3116 .attr("disabled", true); 3117 var visibleColumns = []; 3118 $("#" + tableName) 3119 .bootstrapTable("getVisibleColumns") 3120 .forEach((column) => { 3121 if (!column.checkbox) { 3122 visibleColumns.push(column.field); 3123 } 3124 }); 3125 // Send preferences to the server 3126 $.ajax({ 3127 url: "/master-panel/save-column-visibility", 3128 type: "POST", 3129 data: { 3130 type: type, 3131 visible_columns: JSON.stringify(visibleColumns), 3132 }, 3133 headers: { 3134 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 3135 }, 3136 success: function (response) { 3137 $("#confirmSaveColumnVisibility") 3138 .find("#confirm") 3139 .html(label_yes) 3140 .attr("disabled", false); 3141 if (response.error == false) { 3142 $("#confirmSaveColumnVisibility").modal("hide"); 3143 toastr.success(response.message); 3144 } else { 3145 toastr.error(response.message); 3146 } 3147 }, 3148 error: function (data) { 3149 $("#confirmSaveColumnVisibility") 3150 .find("#confirm") 3151 .html(label_yes) 3152 .attr("disabled", false); 3153 $("#confirmSaveColumnVisibility").modal("hide"); 3154 toastr.error(label_something_went_wrong); 3155 }, 3156 }); 3157 }); 3158});
3159// Edit Workspace Modal 3160$(document).on("click", ".edit-workspace", function () { 3161 var id = $(this).data("id"); 3162 $("#editWorkspaceModal").modal("show"); 3163 $.ajax({ 3164 url: "/master-panel/workspaces/get/" + id, 3165 type: "get", 3166 headers: { 3167 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 3168 }, 3169 dataType: "json", 3170 success: function (response) { 3171 $("#workspace_id").val(response.workspace.id); 3172 $("#workspace_title").val(response.workspace.title); 3173 var usersSelect = $("#editWorkspaceModal").find( 3174 '.js-example-basic-multiple[name="user_ids[]"]' 3175 ); 3176 var workspaceUsers = response.workspace.users.map( 3177 (user) => user.id 3178 ); 3179 usersSelect.val(workspaceUsers); 3180 usersSelect.trigger("change"); // Trigger change event to update select2 3181 var clientsSelect = $("#editWorkspaceModal").find( 3182 '.js-example-basic-multiple[name="client_ids[]"]' 3183 ); 3184 var workspaceClients = response.workspace.clients.map( 3185 (client) => client.id 3186 ); 3187 clientsSelect.val(workspaceClients); 3188 clientsSelect.trigger("change"); // Trigger change event to update select2 3189 if (response.workspace.is_primary == 1) { 3190 $("#editWorkspaceModal") 3191 .find("#updatePrimaryWorkspace") 3192 .prop("checked", true) 3193 .prop("disabled", true); 3194 } else { 3195 $("#editWorkspaceModal") 3196 .find("#updatePrimaryWorkspace") 3197 .prop("checked", false) 3198 .prop("disabled", false); 3199 } 3200 }, 3201 error: function (xhr, status, error) { 3202 console.error(error); 3203 }, 3204 }); 3205}); 3206// Edit Meetings 3207$(document).on("click", ".edit-meeting", function () { 3208 var id = $(this).data("id"); 3209 $("#editMeetingModal").modal("show"); 3210 $.ajax({ 3211 url: "/master-panel/meetings/get/" + id, 3212 type: "get", 3213 headers: { 3214 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 3215 }, 3216 dataType: "json", 3217 success: function (response) { 3218 var formattedStartDate = moment(response.meeting.start_date).format( 3219 js_date_format 3220 ); 3221 var formattedEndDate = moment(response.meeting.end_date).format( 3222 js_date_format 3223 ); 3224 var startDateInput = $("#editMeetingModal").find( 3225 '[name="start_date"]' 3226 ); 3227 var endDateInput = $("#editMeetingModal").find('[name="end_date"]'); 3228 $("#meeting_id").val(response.meeting.id); 3229 $("#meeting_title").val(response.meeting.title); 3230 startDateInput.val(formattedStartDate); 3231 endDateInput.val(formattedEndDate); 3232 // $("#meeting_start_time").val(response.meeting.start_time); 3233 // $("#meeting_end_time").val(response.meeting.end_time); 3234 3235 let startTime = response.meeting.start_time; 3236 let endTime = response.meeting.end_time; 3237 3238 // â Set input value 3239 $("#meeting_start_time").val(startTime); 3240 $("#meeting_end_time").val(endTime); 3241 3242 // â Sync with flatpickr (VERY IMPORTANT) 3243 let startEl = document.querySelector("#meeting_start_time"); 3244 let endEl = document.querySelector("#meeting_end_time"); 3245 3246 if (startEl && startEl._flatpickr) { 3247 startEl._flatpickr.setDate(startTime, true); 3248 } 3249 if (endEl && endEl._flatpickr) { 3250 endEl._flatpickr.setDate(endTime, true); 3251 } 3252 var usersSelect = $("#editMeetingModal").find( 3253 '.js-example-basic-multiple[name="user_ids[]"]' 3254 ); 3255 var meetingUsers = response.meeting.admin.map((admin) => admin.id); 3256 usersSelect.val(meetingUsers); 3257 usersSelect.trigger("change"); // Trigger change event to update select2 3258 var clientsSelect = $("#editMeetingModal").find( 3259 '.js-example-basic-multiple[name="client_ids[]"]' 3260 ); 3261 var meetingClients = response.meeting.clients.map( 3262 (client) => client.id 3263 ); 3264 clientsSelect.val(meetingClients); 3265 clientsSelect.trigger("change"); // Trigger change event to update select2 3266 3267 var staffsSelect = $("#editMeetingModal").find( 3268 '.js-example-basic-multiple[name="staff_ids[]"]' 3269 ); 3270 var meetingStaffs = response.meeting.staffs.map( 3271 (staff) => staff.id 3272 ); 3273 staffsSelect.val(meetingStaffs); 3274 staffsSelect.trigger("change"); 3275 3276 // ["#meeting_start_time","#meeting_end_time"].forEach(selector => { 3277 // flatpickr(selector, { 3278 // enableTime: true, 3279 // noCalendar: true, 3280 // dateFormat: "h:i K", 3281 // time_24hr: false, 3282 // defaultDate: selector.value || null, 3283 // }); 3284 // }); 3285 3286 3287 }, 3288 error: function (xhr, status, error) { 3289 console.error(error); 3290 }, 3291 }); 3292}); 3293$("#partialLeave, #updatePartialLeave").on("change", function () { 3294 var $form = $(this).closest("form"); // Get the closest form element 3295 var isChecked = $(this).prop("checked"); 3296 if (isChecked) { 3297 // If the checkbox is checked 3298 $form 3299 .find(".leave-from-date-div") 3300 .removeClass("col-5") 3301 .addClass("col-3"); 3302 $form.find(".leave-to-date-div").removeClass("col-5").addClass("col-3"); 3303 $form 3304 .find(".leave-from-time-div, .leave-to-time-div") 3305 .removeClass("d-none"); 3306 $form.find("#guide_text").removeClass("d-none"); 3307 } else { 3308 // If the checkbox is unchecked, revert the changes 3309 $form.find('input[name="from_time"]').val(""); 3310 $form.find('input[name="to_time"]').val(""); 3311 $form 3312 .find(".leave-from-date-div") 3313 .removeClass("col-3") 3314 .addClass("col-5"); 3315 $form.find(".leave-to-date-div").removeClass("col-3").addClass("col-5"); 3316 $form 3317 .find(".leave-from-time-div, .leave-to-time-div") 3318 .addClass("d-none"); 3319 $form.find("#guide_text").addClass("d-none"); 3320 } 3321}); 3322$(".leaveVisibleToAll").on("change", function () { 3323 var $form = $(this).closest("form"); // Get the closest form element 3324 var isChecked = $(this).prop("checked"); 3325 if (isChecked) { 3326 // If the checkbox is checked 3327 $form.find(".leaveVisibleToDiv").addClass("d-none"); 3328 var visibleToSelect = $form.find( 3329 '.js-example-basic-multiple[name="visible_to_ids[]"]' 3330 ); 3331 visibleToSelect.val(null).trigger("change"); 3332 } else { 3333 // If the checkbox is unchecked, revert the changes 3334 $form.find(".leaveVisibleToDiv").removeClass("d-none"); 3335 } 3336}); 3337$(document).ready(function () { 3338 var upcomingBDCalendarInitialized = false;
3339 var upcomingWACalendarInitialized = false; 3340 var membersOnLeaveCalendarInitialized = false; 3341 // Add event listener for tab shown event 3342 $(".nav-tabs .nav-item").on("shown.bs.tab", function (event) { 3343 var tabId = $(event.target).attr("data-bs-target"); 3344 if ( 3345 tabId == "#navs-top-upcoming-birthdays-calendar" && 3346 !upcomingBDCalendarInitialized 3347 ) { 3348 initializeUpcomingBDCalendar(); 3349 upcomingBDCalendarInitialized = true; 3350 } else if ( 3351 tabId == "#navs-top-upcoming-work-anniversaries-calendar" && 3352 !upcomingWACalendarInitialized 3353 ) { 3354 initializeUpcomingWACalendar(); 3355 upcomingWACalendarInitialized = true; 3356 } else if ( 3357 tabId == "#navs-top-members-on-leave-calendar" && 3358 !membersOnLeaveCalendarInitialized 3359 ) { 3360 initializeMembersOnLeaveCalendar(); 3361 membersOnLeaveCalendarInitialized = true; 3362 } 3363 }); 3364}); 3365function initializeUpcomingBDCalendar() { 3366 var upcomingBDCalendar = document.getElementById( 3367 "upcomingBirthdaysCalendar" 3368 ); 3369 // Check if the calendar element exists 3370 if (upcomingBDCalendar) { 3371 var BDcalendar = new FullCalendar.Calendar(upcomingBDCalendar, { 3372 plugins: ["interaction", "dayGrid", "list"], 3373 headerToolbar: { 3374 left: "prev,next today", 3375 center: "title", 3376 right: "dayGridMonth,listYear", 3377 }, 3378 editable: true, 3379 events: function (fetchInfo, successCallback, failureCallback) { 3380 // Make AJAX request to fetch dynamic data 3381 $.ajax({ 3382 url: "/master-panel/home/upcoming-birthdays-calendar", 3383 type: "GET", 3384 data: { 3385 startDate: fetchInfo.startStr, 3386 endDate: fetchInfo.endStr, 3387 }, 3388 success: function (response) { 3389 // Parse and format dynamic data for FullCalendar 3390 var events = response.map(function (event) { 3391 return { 3392 title: event.title, 3393 start: event.start, 3394 end: event.start, 3395 backgroundColor: event.backgroundColor, 3396 borderColor: event.borderColor, 3397 textColor: event.textColor, 3398 userId: event.userId, 3399 }; 3400 }); 3401 // Invoke success callback with dynamic data 3402 successCallback(events); 3403 }, 3404 error: function (xhr, status, error) { 3405 console.error(xhr.responseText); 3406 // Invoke failure callback if there's an error 3407 failureCallback(error); 3408 }, 3409 }); 3410 }, 3411 eventClick: function (info) { 3412 if ( 3413 info.event.extendedProps && 3414 info.event.extendedProps.userId 3415 ) { 3416 var userId = info.event.extendedProps.userId; 3417 var url = "/master-panel/users/profile/" + userId; 3418 window.open(url, "_blank"); // Open in a new tab 3419 } 3420 }, 3421 }); 3422 BDcalendar.render(); 3423 } 3424} 3425function initializeUpcomingWACalendar() { 3426 var upcomingWACalendar = document.getElementById( 3427 "upcomingWorkAnniversariesCalendar" 3428 ); 3429 // Check if the calendar element exists 3430 if (upcomingWACalendar) { 3431 var WAcalendar = new FullCalendar.Calendar(upcomingWACalendar, { 3432 plugins: ["interaction", "dayGrid", "list"], 3433 headerToolbar: { 3434 left: "prev,next today", 3435 center: "title", 3436 right: "dayGridMonth,listYear", 3437 }, 3438 editable: true, 3439 height: "auto", 3440 events: function (fetchInfo, successCallback, failureCallback) { 3441 // Make AJAX request to fetch dynamic data 3442 $.ajax({ 3443 url: "/master-panel/home/upcoming-work-anniversaries-calendar", 3444 type: "GET", 3445 data: { 3446 startDate: fetchInfo.startStr, 3447 endDate: fetchInfo.endStr, 3448 }, 3449 success: function (response) { 3450 // Parse and format dynamic data for FullCalendar 3451 var events = response.map(function (event) { 3452 return { 3453 title: event.title, 3454 start: event.start, 3455 end: event.start, 3456 backgroundColor: event.backgroundColor, 3457 borderColor: event.borderColor, 3458 textColor: event.textColor, 3459 userId: event.userId, 3460 }; 3461 }); 3462 // Invoke success callback with dynamic data 3463 successCallback(events); 3464 }, 3465 error: function (xhr, status, error) { 3466 console.error(xhr.responseText); 3467 // Invoke failure callback if there's an error 3468 failureCallback(error); 3469 }, 3470 }); 3471 }, 3472 eventClick: function (info) { 3473 if ( 3474 info.event.extendedProps && 3475 info.event.extendedProps.userId 3476 ) { 3477 var userId = info.event.extendedProps.userId; 3478 var url = "/master-panel/users/profile/" + userId; 3479 window.open(url, "_blank"); // Open in a new tab 3480 } 3481 }, 3482 }); 3483 WAcalendar.render(); 3484 } 3485}
3486function initializeMembersOnLeaveCalendar() { 3487 var membersOnLeaveCalendar = document.getElementById("membersOnLeaveCalendar"); 3488 3489 if (membersOnLeaveCalendar) { 3490 // Optional: clear and re-init if needed 3491 membersOnLeaveCalendar.innerHTML = ""; // Reset content 3492 3493 var MOLcalendar = new FullCalendar.Calendar(membersOnLeaveCalendar, { 3494 plugins: ["interaction", "dayGrid", "list"], 3495 headerToolbar: { 3496 left: "prev,next today", 3497 center: "title", 3498 right: "dayGridMonth,listYear", 3499 }, 3500 editable: true, 3501 displayEventTime: true, 3502 events: function (fetchInfo, successCallback, failureCallback) { 3503 $.ajax({ 3504 url: "/master-panel/home/members-on-leave-calendar", 3505 type: "GET", 3506 data: { 3507 startDate: fetchInfo.startStr, 3508 endDate: fetchInfo.endStr, 3509 }, 3510 success: function (response) { 3511 var events = response.map(function (event) { 3512 var eventData = { 3513 title: event.title, 3514 start: event.start, 3515 end: moment(event.end).add(1, "days").format("YYYY-MM-DD"), 3516 backgroundColor: event.backgroundColor, 3517 borderColor: event.borderColor, 3518 textColor: event.textColor, 3519 userId: event.userId, 3520 }; 3521 if (event.startTime && event.endTime) { 3522 eventData.extendedProps = { 3523 startTime: event.startTime, 3524 endTime: event.endTime, 3525 }; 3526 } 3527 return eventData; 3528 }); 3529 successCallback(events); 3530 }, 3531 error: function (xhr, status, error) { 3532 console.error(xhr.responseText); 3533 failureCallback(error); 3534 }, 3535 }); 3536 }, 3537 eventClick: function (info) { 3538 if (info.event.extendedProps && info.event.extendedProps.userId) { 3539 var userId = info.event.extendedProps.userId; 3540 window.open("/master-panel/users/profile/" + userId, "_blank"); 3541 } 3542 }, 3543 }); 3544 3545 MOLcalendar.render(); 3546 } 3547} 3548 3549// Run on page load 3550window.addEventListener("load", initializeMembersOnLeaveCalendar); 3551 3552// Also run when clicking a button (example) 3553document.addEventListener("DOMContentLoaded", function () { 3554 const btn = document.getElementById("showLeaveCalendarBtn"); 3555 if (btn) { 3556 btn.addEventListener("click", initializeMembersOnLeaveCalendar); 3557 } 3558}); 3559 3560// View Assigned Projects and Tasks 3561$(document).on("click", ".viewAssigned", function (e) { 3562 e.preventDefault(); 3563 var projectsUrl = "/master-panel/projects/listing"; 3564 var tasksUrl = "/master-panel/tasks/list"; 3565 var id = $(this).data("id"); 3566 var type = $(this).data("type"); 3567 var user = $(this).data("user"); 3568 projectsUrl = projectsUrl + (id ? "/" + id : ""); 3569 tasksUrl = tasksUrl + (id ? "/" + id : ""); 3570 $("#viewAssignedModal").modal("show"); 3571 var projectsTable = $("#viewAssignedModal").find("#projects_table"); 3572 var tasksTable = $("#viewAssignedModal").find("#task_table"); 3573 if (type === "tasks") { 3574 $('.nav-link[data-bs-target="#navs-top-view-assigned-tasks"]').tab( 3575 "show" 3576 ); 3577 $( 3578 '.nav-link[data-bs-target="#navs-top-view-assigned-projects"]' 3579 ).removeClass("active"); 3580 $("#navs-top-view-assigned-projects").removeClass("show active"); 3581 $("#navs-top-view-assigned-tasks").addClass("show active"); 3582 } else { 3583 $('.nav-link[data-bs-target="#navs-top-view-assigned-projects"]').tab( 3584 "show" 3585 ); 3586 $( 3587 '.nav-link[data-bs-target="#navs-top-view-assigned-tasks"]' 3588 ).removeClass("active"); 3589 $("#navs-top-view-assigned-tasks").removeClass("show active"); 3590 $("#navs-top-view-assigned-projects").addClass("show active"); 3591 } 3592 $("#userPlaceholder").text(user); 3593 $(projectsTable).bootstrapTable("refresh", { 3594 url: projectsUrl, 3595 }); 3596 $(tasksTable).bootstrapTable("refresh", { 3597 url: tasksUrl, 3598 }); 3599}); 3600// Internal Client 3601$("#internal_client").change(function () { 3602 var isChecked = $(this).prop("checked"); 3603 $("#password, #password_confirmation").val(""); 3604 $("#passDiv, #confirmPassDiv, #statusDiv, #requireEvDiv").toggleClass( 3605 "d-none", 3606 isChecked 3607 ); 3608 $("#client_deactive").prop("checked", true); 3609 $("#require_ev_" + (isChecked ? "no" : "yes")).prop("checked", true); 3610 $("#password").next(".error-message").remove(); 3611 $("#password_confirmation").next(".error-message").remove(); 3612}); 3613$("#update_internal_client").change(function () { 3614 var isChecked = $(this).prop("checked"); 3615 $("#password, #password_confirmation").val(""); 3616 $("#passDiv, #confirmPassDiv, #statusDiv, #requireEvDiv").toggleClass( 3617 "d-none", 3618 isChecked 3619 ); 3620 // Remove .error-message elements next to #password and #password_confirmation 3621 $("#password").next(".error-message").remove(); 3622 $("#password_confirmation").next(".error-message").remove(); 3623}); 3624//Open Create Contract Type Modal 3625$(document).on("click", ".openCreateContractTypeModal", function (e) { 3626 e.preventDefault(); 3627 $("#create_contract_type_modal").modal("show"); 3628}); 3629// reset date 3630function resetDateFields($form) { 3631 var currentDate = moment(new Date()).format(js_date_format); // Get current date 3632 $form.find("input").each(function () { 3633 var $this = $(this); 3634 if ($this.data("daterangepicker")) { 3635 // Destroy old instance 3636 $this.data("daterangepicker").remove(); 3637 // Reinitialize with new value 3638 $this.val(currentDate).daterangepicker({ 3639 alwaysShowCalendars: true, 3640 showCustomRangeLabel: true, 3641 // minDate: moment($(id).val(), js_date_format), 3642 singleDatePicker: true, 3643 showDropdowns: true, 3644 autoUpdateInput: true, 3645 locale: { 3646 cancelLabel: "Clear", 3647 format: js_date_format, 3648 }, 3649 }); 3650 } 3651 }); 3652} 3653// Change Select Color 3654$(document).on("change", 'select[name="color"]', function (e) { 3655 e.preventDefault(); 3656 var select = $(this); 3657 var classes = $(this).attr("class").split(" "); 3658 var currentColorClass = classes.filter(function (className) { 3659 return className.startsWith("select-"); 3660 })[0]; 3661 var selectedOption = $(this).find("option:selected"); 3662 var selectedOptionClasses = selectedOption.attr("class").split(" "); 3663 var newColorClass = "select-" + selectedOptionClasses[1]; 3664 select.removeClass(currentColorClass).addClass(newColorClass); 3665}); 3666// Select All Preferences 3667$(document).ready(function () { 3668 if ($("#selectAllPreferences").length) { 3669 // Check initial state of checkboxes and update selectAllPreferences checkbox 3670 updateSelectAll(); 3671 // Select/deselect all checkboxes when the selectAllPreferences checkbox is clicked 3672 $("#selectAllPreferences").click(function () { 3673 var isChecked = $(this).prop("checked"); 3674 $('input[name="enabled_notifications[]"]:not(:disabled)').prop( 3675 "checked", 3676 isChecked 3677 ); 3678 }); 3679 // Update the selectAllPreferences checkbox state based on the checkboxes' status 3680 $('input[name="enabled_notifications[]"]').change(function () { 3681 updateSelectAll(); 3682 }); 3683 // Function to update selectAllPreferences checkbox based on checkboxes' status 3684 function updateSelectAll() { 3685 var allChecked = 3686 $('input[name="enabled_notifications[]"]:not(:disabled)') 3687 .length === 3688 $( 3689 'input[name="enabled_notifications[]"]:not(:disabled):checked' 3690 ).length; 3691 $("#selectAllPreferences").prop("checked", allChecked); 3692 } 3693 } 3694}); 3695function toggleChatIframe() {
3696 var iframeContainer = document.getElementById("chatIframeContainer"); 3697 if ( 3698 iframeContainer.style.display === "none" || 3699 iframeContainer.style.display === "" 3700 ) { 3701 iframeContainer.style.display = "block"; 3702 } else { 3703 iframeContainer.style.display = "none"; 3704 } 3705} 3706$(document).on("change", "#statusSelect", function (e) { 3707 e.preventDefault(); 3708 var id = $(this).data("id"); 3709 var statusId = this.value; 3710 var type = $(this).data("type") || "project"; 3711 var reload = $(this).data("reload") || false; 3712 var select = $(this); 3713 var originalStatusId = $(this).data("original-status-id"); 3714 var originalColorClass = $(this).data("original-color-class"); 3715 var classes = $(this).attr("class").split(" "); 3716 var currentColorClass = classes.filter(function (className) { 3717 return className.startsWith("select-"); 3718 })[0]; 3719 var selectedOption = $(this).find("option:selected"); 3720 var selectedOptionClasses = selectedOption.attr("class").split(" "); 3721 var newColorClass = "select-" + selectedOptionClasses[1]; 3722 select.removeClass(currentColorClass).addClass(newColorClass); 3723 $.ajax({ 3724 url: "/master-panel/" + type + "s/get/" + id, 3725 type: "GET", 3726 success: function (response) { 3727 if (response.error == false) { 3728 $("#confirmUpdateStatusModal").modal("show"); // show the confirmation modal 3729 $("#confirmUpdateStatusModal").off( 3730 "click", 3731 "#confirmUpdateStatus" 3732 ); 3733 if (type == "task" && response.task) { 3734 $("#statusNote").val(response.task.note); 3735 originalStatusId = response.task.status_id; 3736 } else if (type == "project" && response.project) { 3737 $("#statusNote").val(response.project.note); 3738 originalStatusId = response.project.status_id; 3739 } 3740 $("#confirmUpdateStatusModal").on( 3741 "click", 3742 "#confirmUpdateStatus", 3743 function (e) { 3744 $("#confirmUpdateStatus") 3745 .html(label_please_wait) 3746 .attr("disabled", true); 3747 // Send AJAX request to update status 3748 $.ajax({ 3749 type: "POST", 3750 url: "/master-panel/update-" + type + "-status", 3751 headers: { 3752 "X-CSRF-TOKEN": $('input[name="_token"]').attr( 3753 "value" 3754 ), 3755 }, 3756 data: { 3757 id: id, 3758 statusId: statusId, 3759 note: $("#statusNote").val(), 3760 }, 3761 success: function (response) { 3762 $("#confirmUpdateStatus") 3763 .html(label_yes) 3764 .attr("disabled", false); 3765 if (response.error == false) { 3766 setTimeout(function () { 3767 if (reload) { 3768 window.location.reload(); // Reload the current page 3769 } 3770 }, 3000); 3771 $("#confirmUpdateStatusModal").modal( 3772 "hide" 3773 ); 3774 var tableSelector = 3775 type == "project" 3776 ? "projects_table" 3777 : "task_table"; 3778 var $table = $("#" + tableSelector); 3779 if ($table.length) { 3780 $table.bootstrapTable("refresh"); 3781 } 3782 toastr.success(response.message); 3783 } else { 3784 select 3785 .removeClass(newColorClass) 3786 .addClass(originalColorClass); 3787 select.val(originalStatusId); 3788 toastr.error(response.message); 3789 } 3790 }, 3791 error: function (xhr, status, error) { 3792 $("#confirmUpdateStatus") 3793 .html(label_yes) 3794 .attr("disabled", false); 3795 // Handle error 3796 select 3797 .removeClass(newColorClass) 3798 .addClass(originalColorClass); 3799 select.val(originalStatusId); 3800 toastr.error("Something Went Wrong"); 3801 }, 3802 }); 3803 } 3804 ); 3805 } else { 3806 $("#confirmUpdateStatus") 3807 .html(label_yes) 3808 .attr("disabled", false); 3809 select.val(originalStatusId); 3810 toastr.error(response.message); 3811 } 3812 }, 3813 error: function (xhr, status, error) { 3814 // Handle error 3815 toastr.error("Something Went Wrong"); 3816 }, 3817 }); 3818 // Handle modal close event 3819 $("#confirmUpdateStatusModal").off( 3820 "click", 3821 ".btn-close, #declineUpdateStatus" 3822 ); 3823 $("#confirmUpdateStatusModal").on( 3824 "click", 3825 ".btn-close, #declineUpdateStatus", 3826 function (e) { 3827 // Set original status when modal is closed without confirmation 3828 select.val(originalStatusId); 3829 select.removeClass(newColorClass).addClass(originalColorClass); 3830 } 3831 ); 3832}); 3833$(document).on("change", "#prioritySelect", function (e) { 3834 e.preventDefault(); 3835 var id = $(this).data("id"); 3836 var priorityId = this.value; 3837 var type = $(this).data("type") || "project"; 3838 var reload = $(this).data("reload") || false; 3839 var select = $(this); 3840 var originalPriorityId = $(this).data("original-priority-id") || 0; 3841 var originalColorClass = $(this).data("original-color-class"); 3842 var classes = $(this).attr("class").split(" "); 3843 var currentColorClass = classes.filter(function (className) { 3844 return className.startsWith("select-"); 3845 })[0]; 3846 var selectedOption = $(this).find("option:selected"); 3847 var selectedOptionClasses = selectedOption.attr("class").split(" "); 3848 var newColorClass = "select-" + selectedOptionClasses[1]; 3849 select.removeClass(currentColorClass).addClass(newColorClass); 3850 $("#confirmUpdatePriorityModal").modal("show"); // show the confirmation modal 3851 $("#confirmUpdatePriorityModal").off("click", "#confirmUpdatePriority"); 3852 $("#confirmUpdatePriorityModal").on( 3853 "click", 3854 "#confirmUpdatePriority", 3855 function (e) { 3856 $("#confirmUpdatePriority") 3857 .html(label_please_wait) 3858 .attr("disabled", true); 3859 $.ajax({ 3860 type: "POST", 3861 url: "/master-panel/update-" + type + "-priority", 3862 headers: { 3863 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 3864 }, 3865 data: { 3866 id: id, 3867 priorityId: priorityId, 3868 }, 3869 success: function (response) { 3870 $("#confirmUpdatePriority") 3871 .html(label_yes) 3872 .attr("disabled", false); 3873 if (response.error == false) { 3874 setTimeout(function () {
3875 if (reload) { 3876 window.location.reload(); // Reload the current page 3877 } 3878 }, 3000); 3879 $("#confirmUpdatePriorityModal").modal("hide"); 3880 toastr.success(response.message); 3881 var tableSelector = 3882 type == "project" ? "projects_table" : "task_table"; 3883 var $table = $("#" + tableSelector); 3884 if ($table.length) { 3885 $table.bootstrapTable("refresh"); 3886 } 3887 } else { 3888 select 3889 .removeClass(newColorClass) 3890 .addClass(originalColorClass); 3891 select.val(originalPriorityId); 3892 toastr.error(response.message); 3893 } 3894 }, 3895 error: function (xhr, status, error) { 3896 $("#confirmUpdatePriority") 3897 .html(label_yes) 3898 .attr("disabled", false); 3899 // Handle error 3900 select 3901 .removeClass(newColorClass) 3902 .addClass(originalColorClass); 3903 select.val(originalPriorityId); 3904 toastr.error("Something Went Wrong"); 3905 }, 3906 }); 3907 } 3908 ); 3909}); 3910$(document).ready(function () { 3911 if ($("#total_days").length) { 3912 // Function to calculate and display the total days for create modal 3913 function calculateCreateTotalDays() { 3914 var start_date = moment($("#start_date").val(), js_date_format); 3915 var end_date = moment($("#lr_end_date").val(), js_date_format); 3916 if (start_date.isValid() && end_date.isValid()) { 3917 var total_days = end_date.diff(start_date, "days") + 1; 3918 $("#total_days").val(total_days); 3919 } 3920 } 3921 // Bind the event handlers to both date pickers in the create modal 3922 $("#start_date").on("apply.daterangepicker", function (ev, picker) { 3923 calculateCreateTotalDays(); 3924 }); 3925 $("#lr_end_date").on("apply.daterangepicker", function (ev, picker) { 3926 calculateCreateTotalDays(); 3927 }); 3928 } 3929 if ($("#update_total_days").length) { 3930 // Function to calculate and display the total days for update modal 3931 function calculateUpdateTotalDays() { 3932 var start_date = moment( 3933 $("#update_start_date").val(), 3934 js_date_format 3935 ); 3936 var end_date = moment($("#update_end_date").val(), js_date_format); 3937 if (start_date.isValid() && end_date.isValid()) { 3938 var total_days = end_date.diff(start_date, "days") + 1; 3939 $("#update_total_days").val(total_days); 3940 } 3941 } 3942 // Bind the event handlers to both date pickers in the update modal 3943 $("#update_start_date").on( 3944 "apply.daterangepicker", 3945 function (ev, picker) { 3946 calculateUpdateTotalDays(); 3947 } 3948 ); 3949 $("#update_end_date").on( 3950 "apply.daterangepicker", 3951 function (ev, picker) { 3952 calculateUpdateTotalDays(); 3953 } 3954 ); 3955 } 3956}); 3957/// Search Functionality for the Menu Bar 3958$(document).ready(function () { 3959 var $searchInput = $("#menu-search"); 3960 var $clearButton = $("#clear-search"); 3961 var menuItems = $(".menu-item"); 3962 // Search input event handler 3963 $searchInput.on("input", function () { 3964 var searchQuery = $searchInput.val().toLowerCase(); 3965 $clearButton.toggle(searchQuery.length > 0); 3966 menuItems.each(function () { 3967 const $menuItem = $(this); 3968 const $parentMenu = $menuItem.closest(".menu-sub"); 3969 const $parentMenuItem = $parentMenu.closest(".menu-item"); 3970 const itemText = $menuItem.text().toLowerCase(); 3971 if (itemText.includes(searchQuery)) { 3972 $menuItem.show(); 3973 // Show and open parent menu item 3974 if ($parentMenuItem.length) { 3975 $parentMenuItem.show().addClass("open"); 3976 } 3977 // If this item has a submenu 3978 const $subMenu = $menuItem.find("> .menu-sub"); 3979 if ($subMenu.length) { 3980 $menuItem.addClass("open"); 3981 } 3982 } else { 3983 // Only hide if it doesn't have visible children 3984 if (!$menuItem.find(".menu-item:visible").length) { 3985 $menuItem.hide(); 3986 } 3987 } 3988 }); 3989 }); 3990 // Clear button click event handler 3991 $clearButton.on("click", function () { 3992 $searchInput.val(""); 3993 $clearButton.hide(); 3994 menuItems.find(".open").removeClass("open"); 3995 menuItems.show(); // Show all menu items 3996 }); 3997}); 3998function calenderView() { 3999 var calendar = document.getElementById("taskCalenderDiv"); 4000 // Check if the calendar element exists 4001 if (calendar) { 4002 var project_id = $("#project_id").val(); 4003 var WAcalendar = new FullCalendar.Calendar(calendar, { 4004 plugins: ["interaction", "dayGrid", "list"], 4005 headerToolbar: { 4006 left: "prev,next today", 4007 center: "title", 4008 right: "dayGridMonth,listYear", 4009 }, 4010 editable: false, 4011 height: "auto", 4012 selectable: true, // Enable date selection 4013 select: function (info) { 4014 // Handle date selection 4015 openCreateTaskModal({ 4016 startDate: info.start, 4017 endDate: info.end, 4018 }); 4019 }, 4020 dateClick: function (info) { 4021 // Handle single date click 4022 openCreateTaskModal({ 4023 startDate: info.date, 4024 endDate: info.date, 4025 }); 4026 }, 4027 events: function (fetchInfo, successCallback, failureCallback) { 4028 // Fetch tasks for the current month 4029 fetchTasks( 4030 fetchInfo.start, 4031 fetchInfo.end, 4032 successCallback, 4033 failureCallback, 4034 project_id 4035 ); 4036 }, 4037 datesSet: function (info) { 4038 // Fetch tasks when the month changes 4039 WAcalendar.removeAllEvents(); 4040 WAcalendar.refetchEvents(); 4041 }, 4042 eventClick: function (info) { 4043 // Redirect to the task info page 4044 window.open(info.event.extendedProps.tasks_info_url, "_blank"); 4045 }, 4046 }); 4047 WAcalendar.render(); 4048 } 4049} 4050 4051var WAcalendarStaff = null; // move to global scope 4052 4053function calenderViewshiftC() { 4054 var calendarEl = document.getElementById("shiftCalenderDivC"); 4055 if (!calendarEl) return; 4056 4057 if (WAcalendarStaff !== null) { 4058 WAcalendarStaff.destroy(); 4059 } 4060 4061 var project_id = $("#project_id").val(); 4062 4063 WAcalendarStaff = new FullCalendar.Calendar(calendarEl, { 4064 initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek', 4065 plugins: ["interaction", "dayGrid", "list"], 4066 headerToolbar: { 4067 left: viewMode === "monthly" ? "prev,next today" : "", 4068 center: "title", 4069 right: "dayGridMonth,listYear,timeGridWeek", 4070 }, 4071 displayEventTime: false, 4072 editable: false, 4073 height: "auto", 4074 selectable: true, 4075 4076 validRange: function (nowDate) { 4077 if (viewMode === 'weekly') { 4078 const start = new Date(nowDate); 4079 const end = new Date(nowDate); 4080 start.setDate(start.getDate() - start.getDay()); // Sunday 4081 end.setDate(start.getDate() + 6); // Saturday 4082 return { start: start, end: end }; 4083 } 4084 return null; 4085 }, 4086 4087 dateClick: function (info) { 4088 var clickedDate = info.dateStr; 4089 const currentPath = window.location.pathname; 4090 let ajaxUrl = currentPath.includes('/master-panel/change-request') 4091 ? "/master-panel/getChangerequestStaff" 4092 : "/master-panel/staffs/shift/getShiftData"; 4093 4094 $.ajax({ 4095 url: ajaxUrl, 4096 method: "GET", 4097 data: { 4098 start: info.date.toISOString(), 4099 end: info.date.toISOString(), 4100 user_id: selectedUserId || "", 4101 date: clickedDate 4102 }, 4103 success: function (response) { 4104 if (response && response.length > 0) { 4105 4106 4107 $("#shiftCalenderDivModal").modal("show"); 4108 $("#shiftCalenderDivModal .modal-title").text("Shift Details"); 4109 4110 let allShiftsHtml = ''; 4111 const today = new Date().toISOString().split('T')[0]; 4112 4113 response.forEach(function (shift) { 4114 // ---------------------------- 4115 // Normalize dates 4116 // ---------------------------- 4117 const normalizeDate = (dateStr) => { 4118 if (dateStr.includes('/')) { 4119 const [d, m, y] = dateStr.split('/'); 4120 return `${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`; 4121 } 4122 return dateStr; 4123 }; 4124 4125 const clickedYmd = normalizeDate(clickedDate); 4126 const shiftYmd = normalizeDate(shift.date); 4127 const date_actual = shift.date_actual; 4128 4129 // ---------------------------- 4130 // Time calculation 4131 // ---------------------------- 4132 const now = new Date(); 4133 let isPast = false;
4134 4135 if (shift.time && shift.date) { 4136 4137 const [startStr, endStr] = shift.time.split('-').map(t => t.trim()); 4138 4139 const parseTime = (timeStr) => { 4140 let [time, meridian] = timeStr.split(' '); 4141 let [h, m] = time.split(':').map(Number); 4142 4143 if (meridian === 'PM' && h !== 12) h += 12; 4144 if (meridian === 'AM' && h === 12) h = 0; 4145 4146 return { h, m }; 4147 }; 4148 4149 const [shiftYear, shiftMonth, shiftDay] = shiftYmd.split('-').map(Number); 4150 4151 const start = parseTime(startStr); 4152 const end = parseTime(endStr); 4153 4154 const startDateTime = new Date( 4155 shiftYear, 4156 shiftMonth - 1, 4157 shiftDay, 4158 start.h, 4159 start.m 4160 ); 4161 4162 let endDateTime = new Date( 4163 shiftYear, 4164 shiftMonth - 1, 4165 shiftDay, 4166 end.h, 4167 end.m 4168 ); 4169 4170 // Overnight shift 4171 if (endDateTime <= startDateTime) { 4172 endDateTime.setDate(endDateTime.getDate() + 1); 4173 } 4174 4175 isPast = now > endDateTime; 4176 } 4177 4178 // ---------------------------- 4179 // Button logic â (ONLY ONCE) 4180 // ---------------------------- 4181 let actionButton = ''; 4182 4183 if (currentPath.includes('/master-panel/change-request') || currentPath.includes('/master-panel/staffs/shift/calender')) { 4184 4185 // only on shift date 4186 if (clickedYmd === date_actual) { 4187 4188 if (isPast) { 4189 actionButton = 4190 `<button class="btn btn-sm btn-danger" disabled> 4191 Your shift ended 4192 </button>`; 4193 } else { 4194 actionButton = 4195 `<a class="btn btn-sm btn-primary" 4196 href="/master-panel/change-request/edit/${shift.id}"> 4197 Change Request 4198 </a>`; 4199 } 4200 } 4201 } 4202 4203 // ---------------------------- 4204 // Render HTML 4205 // ---------------------------- 4206 allShiftsHtml += ` 4207 <div class="border rounded p-2 mb-3"> 4208 ${isAdmin ? `<div><strong>Staff:</strong> ${shift.user_name || 'N/A'}</div>` : ''} 4209 <div><strong>Participant:</strong> ${shift.client_name || 'N/A'}</div> 4210 <div><strong>Date:</strong> ${shift.date_show}</div> 4211 <div><strong>Time:</strong> ${shift.time || 'N/A'}</div> 4212 <div><strong>Shift Type:</strong> ${shift.shift_type || 'N/A'}</div> 4213 <div class="mt-2"> 4214 <a class="btn btn-sm btn-primary me-2 d-none" 4215 href="${shift.shift_info_url}" target="_blank"> 4216 View Shift 4217 </a> 4218 ${actionButton} 4219 </div> 4220 </div> 4221 `; 4222 }); 4223 4224 4225 $("#shiftCalenderDivModal .modal-body").html(allShiftsHtml); 4226 $("#shiftActionBtn").hide(); // Hide the old single shift button 4227 } else { 4228 $('#shiftCalenderDivModal').modal('hide'); 4229 if (!currentPath.includes('/master-panel/change-request')) { 4230 window.location.href = "/master-panel/staffs/shift/create?date=" + clickedDate; 4231 } 4232 } 4233 }, 4234 error: function () { 4235 alert("Failed to fetch shift data."); 4236 } 4237 }); 4238 }, 4239 4240 events: function (fetchInfo, successCallback, failureCallback) { 4241 fetchShiftsStaff( 4242 fetchInfo.start, 4243 fetchInfo.end, 4244 successCallback, 4245 failureCallback, 4246 project_id, 4247 selectedUserId, 4248 selectedDate 4249 ); 4250 }, 4251 4252 datesSet: function () { 4253 WAcalendarStaff.removeAllEvents(); 4254 WAcalendarStaff.refetchEvents(); 4255 if (viewMode === 'weekly') { 4256 const todayBtn = document.querySelector('.fc-today-button'); 4257 if (todayBtn && todayBtn.disabled) { 4258 todayBtn.style.display = 'none'; 4259 } 4260 } 4261 }, 4262 4263 eventClick: function (info) { 4264 selectedUserId = info.event.extendedProps.user_id; 4265 selectedDate = info.event.start.toISOString().split("T")[0]; 4266 WAcalendarStaff.removeAllEvents(); 4267 WAcalendarStaff.refetchEvents(); 4268 }, 4269 }); 4270 4271 WAcalendarStaff.render(); 4272 4273 $("#resetFilterBtn").on("click", function () { 4274 selectedUserId = null; 4275 selectedDate = null; 4276 WAcalendarStaff.removeAllEvents(); 4277 WAcalendarStaff.refetchEvents(); 4278 }); 4279 4280 window.viewStaffShifts = function (userId) { 4281 selectedUserId = userId; 4282 selectedDate = null; 4283 WAcalendarStaff.removeAllEvents(); 4284 WAcalendarStaff.refetchEvents(); 4285 }; 4286 4287 $('#shiftCalenderDivModal [data-dismiss="modal"]').on('click', function () { 4288 $('#shiftCalenderDivModal').modal('hide'); 4289 WAcalendarStaff.removeAllEvents(); 4290 WAcalendarStaff.refetchEvents(); 4291 $("#resetFilterBtn").trigger('click'); 4292 }); 4293} 4294 4295 4296function calenderViewshift() { 4297 const calendarEl = document.getElementById('shiftCalenderDiv'); 4298 if (!calendarEl) return; 4299 4300 let WAcalendarAllocated = new FullCalendar.Calendar(calendarEl, { 4301 defaultView: 'dayGridMonth', 4302 plugins: ["interaction", "dayGrid", "timeGrid", "list"], 4303 header: { 4304 left: "prev,next", 4305 center: "title", 4306 right: "dayGridMonth,timeGridWeek,timeGridDay", 4307 }, 4308 buttonText: { 4309 dayGridMonth: 'Monthly View', 4310 timeGridWeek: 'Weekly View', 4311 timeGridDay: 'Today View' 4312 }, 4313 editable: false, 4314 height: "auto", 4315 selectable: true, 4316 displayEventTime: true, 4317 eventTimeFormat: { 4318 hour: 'numeric', 4319 minute: '2-digit', 4320 meridiem: 'short' 4321 }, 4322 eventRender: function (info) { 4323 // Add status-based CSS class for custom styling 4324 if (info.event.extendedProps.status_id !== undefined) { 4325 $(info.el).addClass('event-status-' + info.event.extendedProps.status_id); 4326 } 4327 4328 // Helpful tooltip for truncated titles 4329 $(info.el).attr('title', info.event.title); 4330 }, 4331 events: function (fetchInfo, successCallback, failureCallback) { 4332 $.ajax({ 4333 url: "/master-panel/allocated-shifts/get-data/approved", 4334 type: "GET", 4335 data: { 4336 start: fetchInfo.start.toISOString(), 4337 end: fetchInfo.end.toISOString(), 4338 client_id: $('#filter_client').val(), 4339 user_id: $('#filter_staff').val(), 4340 status_id: $('#filter_status').val() 4341 }, 4342 success: function (response) { 4343 successCallback(response); 4344 }, 4345 error: function (xhr, status, error) { 4346 toastr.error("Failed to load shift data"); 4347 failureCallback(error); 4348 } 4349 }); 4350 }, 4351 eventClick: function (info) { 4352 const userId = info.event.extendedProps.user_id; 4353 const shiftAcceptId = info.event.extendedProps.shift_accept_id; 4354 4355 // Format dates for the details query (range of the clicked day) 4356 const startDate = info.event.start.toISOString().split('T')[0]; 4357 const endDate = info.event.end ? info.event.end.toISOString().split('T')[0] : startDate; 4358 4359 $('#shiftDetailsContent').html('<div class="text-center p-5"><div class="spinner-border text-primary" role="status"></div></div>'); 4360 $('#shiftDetailsModal').modal('show'); 4361 4362 $.ajax({
4363 url: "/master-panel/allocated-shifts/details", 4364 type: "GET", 4365 data: { 4366 user_id: userId, 4367 shift_accept_id: shiftAcceptId, 4368 start_date: startDate, 4369 end_date: endDate, 4370 approve: 1 4371 }, 4372 success: function (html) { 4373 $('#shiftDetailsContent').html(html); 4374 }, 4375 error: function () { 4376 $('#shiftDetailsContent').html('<div class="alert alert-danger">Failed to load shift details.</div>'); 4377 } 4378 }); 4379 }, 4380 dateClick: function (info) { 4381 const clickedDate = info.dateStr; 4382 const events = WAcalendarAllocated.getEvents(); 4383 4384 // Check if there are any events on the clicked date 4385 const clickedDateStart = moment(clickedDate).startOf('day'); 4386 const clickedDateEnd = moment(clickedDate).endOf('day'); 4387 4388 const hasShifts = events.some(event => { 4389 const eventStart = moment(event.start); 4390 const eventEnd = moment(event.end || event.start); 4391 return eventStart.isBefore(clickedDateEnd) && eventEnd.isAfter(clickedDateStart); 4392 }); 4393 4394 if (hasShifts) { 4395 // If shifts exist, open the day view 4396 WAcalendarAllocated.changeView('timeGridDay', clickedDate); 4397 } else { 4398 // If no shifts exist, redirect to the create page 4399 const createUrl = calendarEl.getAttribute('data-create-url'); 4400 const isAdmin = calendarEl.getAttribute('data-is-admin') === 'true'; 4401 4402 if (isAdmin && createUrl) { 4403 window.location.href = `${createUrl}?date = ${clickedDate} `; 4404 } else { 4405 WAcalendarAllocated.changeView('timeGridDay', clickedDate); 4406 } 4407 } 4408 } 4409 }); 4410 4411 WAcalendarAllocated.render(); 4412 4413 // â Accept/Reject from Popup 4414 $(document).on('click', '#staff_accept_shift_btn, #staff_reject_shift_btn', function () { 4415 const shiftId = $(this).data('shift-accept-id'); 4416 const isAccept = $(this).attr('id') === 'staff_accept_shift_btn'; 4417 const newStatus = isAccept ? 2 : 3; // 2=Accepted, 3=Rejected 4418 const actionText = isAccept ? 'Accept' : 'Reject'; 4419 4420 if (!confirm(`Are you sure you want to ${actionText.toLowerCase()} this shift ? `)) return; 4421 4422 const $btn = $(this); 4423 const originalHtml = $btn.html(); 4424 $btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span> Processing...'); 4425 4426 $.ajax({ 4427 url: `/ master - panel / accept - shift / ${shiftId}/status`, 4428 type: "POST", 4429 data: { 4430 _token: $('meta[name="csrf-token"]').attr('content'), 4431 status: newStatus 4432 }, 4433 success: function (response) { 4434 if (response.success) { 4435 toastr.success(`Shift ${actionText.toLowerCase()}ed successfully`); 4436 $('#shiftDetailsModal').modal('hide'); 4437 WAcalendarAllocated.refetchEvents(); 4438 } else { 4439 toastr.error(response.message || `Failed to ${actionText.toLowerCase()} shift`); 4440 $btn.prop('disabled', false).html(originalHtml); 4441 } 4442 }, 4443 error: function () { 4444 toastr.error("An error occurred. Please try again."); 4445 $btn.prop('disabled', false).html(originalHtml); 4446 } 4447 }); 4448 }); 4449 4450 // Apply Filter Button 4451 $('#btn_filter_calendar').on('click', function () { 4452 WAcalendarAllocated.refetchEvents(); 4453 }); 4454 4455 // Reset Filters 4456 $('#reset_filters').on('click', function () { 4457 $('#filter_client').val(''); 4458 $('#filter_status').val(''); 4459 $('#filter_staff').empty().append('<option value="">All Staff</option>'); 4460 WAcalendarAllocated.refetchEvents(); 4461 }); 4462 4463 // Dependent Dropdown Logic 4464 $('#filter_client').on('change', function () { 4465 const clientId = $(this).val(); 4466 const $staffSelect = $('#filter_staff'); 4467 4468 if (clientId) { 4469 $.get("/master-panel/allocated-shifts/get-staff", { client_id: clientId }, function (data) { 4470 $staffSelect.empty().append('<option value="">All Staff</option>'); 4471 if (data.staff && data.staff.length > 0) { 4472 data.staff.forEach(function (s) { 4473 const name = s.first_name + ' ' + (s.middle_name ? s.middle_name + ' ' : '') + s.last_name; 4474 $staffSelect.append(`<option value="${s.id}">${name}</option>`); 4475 }); 4476 } 4477 }); 4478 } 4479 }); 4480} 4481 4482 4483 4484 4485function calenderViewshiftClient() { 4486 var calendar = document.getElementById("shiftCalenderDivClient"); 4487 4488 if (calendar) { 4489 var project_id = $("#project_id").val(); 4490 var WAcalendar = new FullCalendar.Calendar(calendar, { 4491 initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek', 4492 plugins: ["interaction", "dayGrid", "list"], 4493 headerToolbar: { 4494 left: viewMode === "monthly" ? "prev,next today" : "", 4495 center: "title", 4496 right: "dayGridMonth,listYear,timeGridWeek", 4497 }, 4498 4499 displayEventTime: false, 4500 editable: false, 4501 height: "auto", 4502 selectable: true, 4503 4504 validRange: function (nowDate) { 4505 if (viewMode === 'weekly') { 4506 const start = new Date(nowDate); 4507 start.setDate(start.getDate() - start.getDay()); // Sunday 4508 const end = new Date(start); 4509 end.setDate(end.getDate() + 6); // Saturday 4510 return { 4511 start: start.toISOString().split("T")[0], 4512 end: new Date(end.getTime() + 86400000).toISOString().split("T")[0] 4513 }; 4514 } 4515 return null; // full range allowed in monthly 4516 }, 4517 // dateClick: function (info) { 4518 // var clickedDate = info.dateStr; 4519 // var hasShift = false;
4520 // WAcalendar.getEvents().forEach(function (event) { 4521 // var eventDate = event.start.toISOString().split("T")[0]; 4522 // if (eventDate === clickedDate) { 4523 // hasShift = true; 4524 // } 4525 // }); 4526 // if (!hasShift) { 4527 // window.open("/master-panel/clients/shift/create?date=" + clickedDate, "_blank"); 4528 // } 4529 // }, 4530 4531 dateClick: function (info) { 4532 var clickedDate = info.dateStr; 4533 $.ajax({ 4534 //url:ajaxUrl, 4535 url: "/master-panel/clients/shift/getShiftData", 4536 method: "GET", 4537 data: { 4538 start: info.date.toISOString(), 4539 end: info.date.toISOString(), 4540 user_id: selectedUserId || "", 4541 date: clickedDate 4542 }, 4543 success: function (response) { 4544 if (response && response.length > 0) { 4545 const shift = response[0]; 4546 $("#shiftCalenderDivModal").modal("show"); 4547 $("#shiftCalenderDivModal .modal-title").text("Shift Details"); 4548 $("#shiftCalenderDivModal .event-user").text(shift.client_id || "N/A"); 4549 $("#shiftCalenderDivModal .event-client").text(shift.client_name || "N/A"); 4550 $("#shiftCalenderDivModal .event-date").text(shift.date || clickedDate); 4551 // $("#shiftCalenderDivModal .event-time").text(shift.start_time + " - " + shift.end_time); 4552 $("#shiftCalenderDivModal .event-time").text(shift.time); 4553 $("#shiftCalenderDivModal .event-type").text(shift.shift_type || "N/A"); 4554 $("#shiftCalenderDivModal .edit-link").attr('href', `/master-panel/clients/shifts/edit/${shift.id}`).text('Edit'); 4555 4556 $("#shiftActionBtn") 4557 .text("View Shift") 4558 .attr("href", shift.shift_info_url) 4559 .show(); 4560 } else { 4561 $('#shiftCalenderDivModal').modal('hide'); 4562 4563 // $("#shiftCalenderDivModal .modal-title").text("Create New Shift"); 4564 // $("#shiftCalenderDivModal .event-user").text("N/A"); 4565 // $("#shiftCalenderDivModal .event-date").text(clickedDate); 4566 // $("#shiftCalenderDivModal .event-time").text("N/A"); 4567 // $("#shiftCalenderDivModal .event-type").text("N/A"); 4568 4569 // $("#shiftActionBtn") 4570 // .text("Create Shift") 4571 // .attr("href", "/master-panel/staffs/shift/create?date=" + clickedDate) 4572 // .show(); 4573 4574 window.location.href = "/master-panel/clients/shift/create?date=" + clickedDate; 4575 4576 } 4577 }, 4578 error: function () { 4579 alert("Failed to fetch shift data."); 4580 } 4581 }); 4582 }, 4583 4584 events: function (fetchInfo, successCallback, failureCallback) { 4585 // â Use global selectedUserId and selectedDate 4586 fetchShifts( 4587 fetchInfo.start, 4588 fetchInfo.end, 4589 successCallback, 4590 failureCallback, 4591 project_id, 4592 selectedUserId, 4593 selectedDate 4594 ); 4595 }, 4596 4597 datesSet: function (info) { 4598 WAcalendar.removeAllEvents(); 4599 WAcalendar.refetchEvents(); 4600 4601 }, 4602 4603 eventClick: function (info) { 4604 // â Update global filters 4605 selectedUserId = info.event.extendedProps.user_id; 4606 selectedDate = info.event.start.toISOString().split("T")[0]; 4607 WAcalendar.removeAllEvents(); 4608 WAcalendar.refetchEvents(); 4609 }, 4610 }); 4611 4612 WAcalendar.render(); 4613 } 4614 $("#resetFilterBtn").on("click", function () { 4615 selectedUserId = null; 4616 selectedDate = null; 4617 4618 if (WAcalendar) { 4619 WAcalendar.removeAllEvents(); 4620 WAcalendar.refetchEvents(); 4621 } 4622 }); 4623 window.viewUserShifts = function (userId) { 4624 selectedUserId = userId; 4625 selectedDate = null; 4626 if (WAcalendar) { 4627 WAcalendar.removeAllEvents(); 4628 WAcalendar.refetchEvents(); 4629 } 4630 4631 }; 4632 4633 $('#shiftCalenderDivModal [data-dismiss="modal"]').on('click', function () { 4634 $('#shiftCalenderDivModal').modal('hide'); 4635 // Just refresh events, not reinitialize calendar 4636 WAcalendarStaff.removeAllEvents(); 4637 WAcalendarStaff.refetchEvents(); 4638 $("#resetFilterBtn").trigger('click'); 4639 }); 4640} 4641 4642 4643 4644// Helper function to open the create task modal 4645function openCreateTaskModal(dates) { 4646 // Format dates to your required format (example uses YYYY-MM-DD) 4647 const startDate = formatDate(dates.startDate); 4648 const endDate = formatDate(dates.endDate); 4649 // If you're using a bootstrap modal 4650 const modal = new bootstrap.Modal( 4651 document.getElementById("create_task_modal") 4652 ); 4653 // Set the date values in your form inputs 4654 document.getElementById("task_start_date").value = startDate; 4655 document.getElementById("task_end_date").value = endDate; 4656 // Show the modal 4657 modal.show(); 4658} 4659// Helper function to format dates according to system format 4660function formatDate(date) { 4661 if (!date) return ""; 4662 try { 4663 // Create a moment object and format according to system date format 4664 return moment(date).format(js_date_format); 4665 } catch (error) { 4666 console.error("Error formatting date:", error); 4667 // Fallback to ISO format if there's an error 4668 return date.toISOString().split("T")[0]; 4669 } 4670} 4671function fetchTasks( 4672 startDate, 4673 endDate, 4674 successCallback, 4675 failureCallback, 4676 project_id 4677) { 4678 $.ajax({ 4679 url: "/master-panel/tasks/get-calendar-data", 4680 type: "GET", 4681 data: { 4682 start: startDate.toISOString(), // Send the start date 4683 end: endDate.toISOString(), // Send the end date, 4684 project_id: project_id, 4685 }, 4686 success: function (response) { 4687 // Parse and format dynamic data for FullCalendar 4688 var events = response.map(function (event) { 4689 return {
4690 id: event.id, 4691 tasks_info_url: event.tasks_info_url, 4692 title: event.title, 4693 start: event.start, 4694 end: moment(event.end).add(1, "days").format("YYYY-MM-DD"), 4695 backgroundColor: event.backgroundColor, 4696 borderColor: event.borderColor, 4697 textColor: event.textColor, 4698 }; 4699 }); 4700 // Invoke success callback with dynamic data 4701 successCallback(events); 4702 }, 4703 error: function (xhr, status, error) { 4704 console.error(xhr.responseText); 4705 // Invoke failure callback if there's an error 4706 failureCallback(error); 4707 }, 4708 }); 4709} 4710 4711 4712function fetchShifts( 4713 startDate, 4714 endDate, 4715 successCallback, 4716 failureCallback, 4717 project_id, 4718 user_id = null, 4719 date = null 4720) { 4721 const currentPath = window.location.pathname; 4722 let ajaxUrl = ''; // Declare in outer scope 4723 if (currentPath.includes('/master-panel/clients/shift/list')) { 4724 ajaxUrl = "/master-panel/clients/shift/getShiftData"; 4725 } 4726 else { 4727 ajaxUrl = "/master-panel/scheduler/getData"; 4728 } 4729 $.ajax({ 4730 url: ajaxUrl, 4731 //url: "/master-panel/clients/shift/getShiftData", 4732 type: "GET", 4733 data: { 4734 start: startDate.toISOString(), 4735 end: endDate.toISOString(), 4736 project_id: project_id, 4737 user_id: user_id, // Pass user ID if set 4738 date: date // Pass selected date if set 4739 }, 4740 success: function (response) { 4741 var events = response.map(function (shift) { 4742 return { 4743 id: shift.shift_id, 4744 title: shift.shift_title, 4745 start: new Date(shift.start_time).toISOString(), 4746 end: new Date(shift.end_time).toISOString(),//shift.end_time, 4747 backgroundColor: shift.backgroundColor, 4748 borderColor: shift.borderColor, 4749 textColor: shift.textColor, 4750 shift_info_url: shift.shift_info_url, 4751 user_id: shift.user_id // Include user_id if you want to filter later on client side too 4752 }; 4753 }); 4754 4755 successCallback(events); 4756 }, 4757 error: function (xhr, status, error) { 4758 console.error(xhr.responseText); 4759 failureCallback(error); 4760 }, 4761 }); 4762} 4763function fetchShiftsStaff( 4764 startDate, 4765 endDate, 4766 successCallback, 4767 failureCallback, 4768 project_id, 4769 user_id = null, 4770 date = null 4771) { 4772 // const currentPath = window.location.pathname; 4773 const currentPath = window.location.pathname.replace(/\/+$/, ''); 4774 4775 let ajaxUrl = ''; // Declare in outer scope 4776 // console.log("ð currentPath:", currentPath); // Debug print 4777 4778 if (currentPath === '/master-panel/staffs/shift/calender') { 4779 ajaxUrl = "/master-panel/staffs/shift/getShiftData"; 4780 //console.log("â ajaxUrl set to:", ajaxUrl); 4781 } else if (currentPath.includes('/master-panel/change-request')) { 4782 ajaxUrl = "/master-panel/getChangerequestStaff"; 4783 } else { 4784 ajaxUrl = "/master-panel/scheduler/getData"; 4785 } 4786 4787 4788 $.ajax({ 4789 //url: "/master-panel/staffs/shift/getShiftData", 4790 url: ajaxUrl, 4791 type: "GET", 4792 data: { 4793 start: startDate.toISOString(), 4794 end: endDate.toISOString(), 4795 project_id: project_id, 4796 user_id: user_id, // Pass user ID if set 4797 date: date // Pass selected date if set 4798 }, 4799 success: function (response) { 4800 console.log(response); 4801 var events = response.map(function (shift) { 4802 4803 return { 4804 id: shift.shift_id, 4805 title: shift.shift_title, 4806 start: new Date(shift.start_time).toISOString(),// shift.start_time, 4807 end: new Date(shift.end_time).toISOString(),//shift.end_time, 4808 backgroundColor: shift.backgroundColor, 4809 borderColor: shift.borderColor, 4810 textColor: shift.textColor, 4811 shift_info_url: shift.shift_info_url, 4812 user_id: shift.user_id // Include user_id if you want to filter later on client side too 4813 }; 4814 }); 4815 4816 successCallback(events); 4817 }, 4818 error: function (xhr, status, error) { 4819 console.error(xhr.responseText); 4820 failureCallback(error); 4821 }, 4822 }); 4823} 4824 4825function meetingData( 4826 startDate, 4827 endDate, 4828 successCallback, 4829 failureCallback, 4830 project_id, 4831 user_id = null, 4832 date = null 4833) { 4834 const currentPath = window.location.pathname; 4835 let ajaxUrl = "/master-panel/meetings-data"; 4836 $.ajax({ 4837 url: ajaxUrl, 4838 type: "GET", 4839 data: { 4840 start: startDate.toISOString(), 4841 end: endDate.toISOString() 4842 }, 4843 success: function (response) { 4844 var events = response.map(function (meeting) { 4845 return { 4846 id: meeting.id, 4847 title: meeting.title, 4848 start: meeting.start_time, 4849 end: meeting.end_time, 4850 borderColor: meeting.borderColor, 4851 textColor: meeting.textColor, 4852 url: meeting.url 4853 // Include user_id if you want to filter later on client side too 4854 }; 4855 }); 4856 successCallback(events); 4857 }, 4858 error: function (xhr, status, error) { 4859 console.error(xhr.responseText); 4860 failureCallback(error); 4861 }, 4862 }); 4863} 4864 4865 4866function meetingCalender() { 4867 var calendar = document.getElementById("meetingCalender"); 4868 let isModalOpen = false;
4869 if (calendar) { 4870 var project_id = $("#project_id").val(); 4871 var WAcalendar = new FullCalendar.Calendar(calendar, { 4872 initialView: viewMode === 'monthly' ? 'dayGridMonth' : 'timeGridWeek', 4873 plugins: ["interaction", "dayGrid", "list"], 4874 headerToolbar: { 4875 left: viewMode === "monthly" ? "prev,next today" : "", 4876 center: "title", 4877 right: "dayGridMonth,listYear,timeGridWeek", 4878 }, 4879 displayEventTime: false, 4880 editable: false, 4881 height: "auto", 4882 selectable: true, 4883 events: function (fetchInfo, successCallback, failureCallback) { 4884 // â Use global selectedUserId and selectedDate 4885 meetingData( 4886 fetchInfo.start, 4887 fetchInfo.end, 4888 successCallback, 4889 failureCallback, 4890 project_id, 4891 selectedUserId, 4892 selectedDate 4893 ); 4894 }, 4895 eventClick: function (info) { 4896 info.jsEvent.preventDefault(); // don't let the browser navigate 4897 const eventId = info.event.id; // Event ID 4898 const eventDate = info.event.dateStr; // ISO formatted date-time string 4899 const eventDateOnly = info.event.start.toISOString().split('T')[0]; 4900 const event_url = '/master-panel/meetings-data/' + eventId + '/' + eventDateOnly; // ISO formatted date-time string 4901 4902 console.log(eventId); 4903 console.log(eventDate); 4904 console.log(info); 4905 $.ajax({ 4906 url: info.event.url, 4907 method: "GET", 4908 data: {}, 4909 success: function (response) { 4910 console.log(response); 4911 if (response) { 4912 console.log(response); 4913 // Clear old content if necessary 4914 $("#MeetingDivModal .modal-body").empty(); 4915 4916 // Title, Start & End Time 4917 $('#MeetingDivModal .modal-body').append(`<p><strong>Title:</strong> ${response.title}</p>`); 4918 $('#MeetingDivModal .modal-body').append(`<p><strong>Start Time:</strong> ${response.start_date_time}</p>`); 4919 $('#MeetingDivModal .modal-body').append(`<p><strong>End Time:</strong> ${response.end_date_time}</p>`); 4920 4921 // Admins 4922 if (response.admin && response.admin.length > 0) { 4923 $('#MeetingDivModal .modal-body').append('<p><strong>Admin:</strong></p>'); 4924 response.admin.forEach(admin => { 4925 $('#MeetingDivModal .modal-body').append(` 4926 <p> 4927 <img src="${admin.photo}" alt="${admin.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;"> 4928 ${admin.name}<!--(${admin.email})--> 4929 </p> 4930 `); 4931 }); 4932 } 4933 4934 // Staffs 4935 if (response.staffs && response.staffs.length > 0) { 4936 if (response.staffs.length > 1) { 4937 $('#MeetingDivModal .modal-body').append('<p><strong>Staffs:</strong></p>'); 4938 } else { 4939 $('#MeetingDivModal .modal-body').append('<p><strong>Staff:</strong></p>'); 4940 } 4941 response.staffs.forEach(staff => { 4942 $('#MeetingDivModal .modal-body').append(` 4943 <p> 4944 <img src="${staff.photo}" alt="${staff.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;"> 4945 ${staff.name}<!--(${staff.email})--> 4946 </p> 4947 `); 4948 }); 4949 } 4950 4951 // Clients 4952 if (response.clients && response.clients.length > 0) { 4953 if (response.clients.length > 1) { 4954 $('#MeetingDivModal .modal-body').append('<p><strong>Participants:</strong></p>'); 4955 } else { 4956 $('#MeetingDivModal .modal-body').append('<p><strong>Participant:</strong></p>'); 4957 }
4958 response.clients.forEach(client => { 4959 $('#MeetingDivModal .modal-body').append(` 4960 <p> 4961 <img src="${client.photo}" alt="${client.name}" width="30" height="30" style="border-radius:50%; margin-right:8px;"> 4962 ${client.name}<!--(${client.email})--> 4963 </p> 4964 `); 4965 }); 4966 } 4967 4968 // Clients 4969 if (response.url) { 4970 if (response.ended == 0) { 4971 $('#MeetingDivModal .modal-body').append(`<p><a target="_blank" class="btn btn-primary edit-link" style="display:block; text-align: center;" href="` + response.url + `" >Join Meeting</a></p>`); 4972 } else { 4973 $('#MeetingDivModal .modal-body').append(`<p style="color:red;">Meeting has expired.</p>`); 4974 } 4975 } 4976 4977 $("#MeetingDivModal").modal("show"); 4978 } else { 4979 $('#MeetingDivModal').modal('hide'); 4980 } 4981 }, 4982 error: function () { 4983 alert("Failed to fetch meeting data."); 4984 } 4985 }); 4986 }, 4987 }); 4988 WAcalendar.render(); 4989 } 4990 4991 $('#MeetingDivModal [data-dismiss="modal"]').on('click', function () { 4992 $('#MeetingDivModal').modal('hide'); 4993 }); 4994} 4995 4996 4997// Initialize the calendar on page load 4998meetingCalender(); 4999calenderView(); 5000calenderViewshift(); 5001calenderViewshiftC(); 5002calenderViewshiftClient(); 5003 5004$(document).ready(function () { 5005 $("#previewToast").click(function () { 5006 var previewToastPosition = $("#toastPosition").val(); 5007 var toastTimeoutInput = $("#toastTimeout"); 5008 var previewToastTimeout = parseFloat(toastTimeoutInput.val()); 5009 // Validate toast timeout is not blank and is a positive number 5010 if (isNaN(previewToastTimeout) || previewToastTimeout <= 0) { 5011 toastr.options = { 5012 positionClass: toastPosition, 5013 timeOut: parseFloat(toastTimeOut) * 1000, 5014 showDuration: "300", 5015 hideDuration: "1000", 5016 extendedTimeOut: "1000", 5017 progressBar: true, 5018 closeButton: true, 5019 }; 5020 toastr.error("Please enter a valid timeout value in seconds."); 5021 toastTimeoutInput.focus(); 5022 return; 5023 } 5024 // Convert timeout to milliseconds 5025 previewToastTimeout *= 1000; 5026 toastr.options = { 5027 positionClass: previewToastPosition, 5028 timeOut: previewToastTimeout, 5029 showDuration: "300", 5030 hideDuration: "1000", 5031 extendedTimeOut: "1000", 5032 progressBar: true, 5033 closeButton: true, 5034 }; 5035 toastr.success( 5036 "This is a preview of your toast message!", 5037 "Toast Preview" 5038 ); 5039 }); 5040}); 5041document.addEventListener("DOMContentLoaded", function () { 5042 var chatBox = document.getElementById("chatBox"); 5043 if (chatBox) { 5044 chatBox.scrollTop = chatBox.scrollHeight; 5045 } 5046}); 5047// Mention in the text area 5048function initializeMentionTextarea($textarea) { 5049 // Extract mention id and type from the data attributes of the textarea 5050 const mentionID = $textarea.data("mention-id"); 5051 const mentionType = $textarea.data("mention-type"); 5052 // Check if the textarea element exists 5053 if ($textarea.length === 0) { 5054 console.error("Textarea not found."); 5055 return; 5056 } 5057 // Initialize Tribute.js with the provided textarea 5058 const tribute = new Tribute({ 5059 values: function (text, cb) { 5060 // Fetch users based on the search term and mention info 5061 $.ajax({ 5062 url: `/master-panel/projects/get-users`, 5063 method: "GET", 5064 data: { 5065 search: text, 5066 mention_id: mentionID, 5067 mention_type: mentionType, 5068 }, 5069 success: function (response) { 5070 const mappedUsers = response.map((user) => ({ 5071 key: user.id, // Use 'id' as key 5072 value: user.first_name + " " + user.last_name, 5073 }));
5074 cb(mappedUsers); // Provide the data to Tribute.js callback 5075 }, 5076 error: function (xhr, status, error) { 5077 console.error("Error fetching users:", error); 5078 }, 5079 }); 5080 }, 5081 selectTemplate: function (item) { 5082 return `@${item.original.value}`; // What gets inserted when selected 5083 }, 5084 lookup: "value", // Attribute used for lookup 5085 menuItemTemplate: function (item) { 5086 return `${item.original.value}`; // How items appear in the dropdown 5087 }, 5088 }); 5089 // Attach Tribute.js to the textarea 5090 tribute.attach($textarea[0]); 5091} 5092function stripHtml(content) { 5093 // Replace <a> tags with the inner text, but only add '@' if the inner text doesn't already start with it 5094 return content.replace( 5095 /<a [^>]+>([^<]+)<\/a>/g, 5096 function (match, innerText) { 5097 // Check if the innerText already starts with @ 5098 return innerText.startsWith("@") ? innerText : "@" + innerText; 5099 } 5100 ); 5101} 5102// Initialize the Select2 and Ajax in the select 5103function initSelect2Ajax( 5104 elementId, 5105 ajaxUrl, 5106 placeholderText = "", 5107 allowClear = true, 5108 minimumInputLength = 0, 5109 initialData = true 5110) { 5111 const $element = $(elementId); 5112 const $modalParent = $element.closest('.modal'); 5113 5114 $element.select2({ 5115 placeholder: placeholderText, 5116 dropdownParent: $modalParent.length ? $modalParent : $(document.body), // â Conditional handling 5117 ajax: { 5118 url: ajaxUrl, 5119 dataType: "json", 5120 delay: 250, 5121 data: function (params) { 5122 return { 5123 q: params.term || "", // Search term 5124 page: params.page || 1, // Pagination 5125 }; 5126 }, 5127 processResults: function (data, params) { 5128 params.page = params.page || 1; 5129 return { 5130 results: data.items, 5131 pagination: { 5132 more: data.pagination.more, 5133 }, 5134 }; 5135 }, 5136 cache: true, 5137 }, 5138 minimumInputLength: minimumInputLength, 5139 allowClear: allowClear, 5140 initSelection: function (element, callback) { 5141 if (initialData) { 5142 $.ajax({ 5143 url: ajaxUrl, 5144 data: { 5145 q: "", 5146 page: 1, 5147 }, 5148 dataType: "json", 5149 success: function (data) { 5150 callback(data.items); 5151 }, 5152 }); 5153 } 5154 }, 5155 }); 5156} 5157function initPhoneInput(inputId, initialCountryCode = "", initialISOCode = "") { 5158 const input = document.querySelector(`#${inputId}`); 5159 // Create a wrapper and clear button for the input 5160 const wrapper = document.createElement("div"); 5161 wrapper.style.position = "relative"; 5162 input.parentNode.insertBefore(wrapper, input); 5163 wrapper.appendChild(input); 5164 const clearButton = document.createElement("button"); 5165 clearButton.innerHTML = "â"; // Use an X or any icon for clear 5166 clearButton.style.position = "absolute"; 5167 clearButton.style.right = "10px"; // Adjust as needed 5168 clearButton.style.top = "50%"; 5169 clearButton.style.transform = "translateY(-50%)"; 5170 clearButton.style.border = "none"; 5171 clearButton.style.background = "none"; 5172 clearButton.style.cursor = "pointer"; 5173 clearButton.style.display = "none"; // Initially hidden 5174 wrapper.appendChild(clearButton); 5175 const iti = window.intlTelInput(input, { 5176 utilsScript: 5177 "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/utils.js", 5178 separateDialCode: true, 5179 initialCountry: "auto", 5180 preferredCountries: ["US", "GB", "CA", "IN"], 5181 geoIpLookup: function (callback) { 5182 callback("US"); // Default to US for geo IP lookup 5183 }, 5184 }); 5185 // Show the clear button when input has a value 5186 input.addEventListener("input", () => { 5187 clearButton.style.display = input.value ? "block" : "none"; 5188 }); 5189 // Clear input on button click 5190 clearButton.addEventListener("click", (e) => { 5191 e.preventDefault(); 5192 iti.setNumber(""); // Clear the input 5193 clearButton.style.display = "none"; 5194 }); 5195 // Set initial country if provided 5196 if (initialCountryCode) { 5197 const allCountries = window.intlTelInputGlobals.getCountryData(); 5198 let country; 5199 if (initialISOCode) { 5200 country = allCountries.find( 5201 (c) => 5202 `+${c.dialCode}` === initialCountryCode && 5203 c.iso2 === initialISOCode 5204 ); 5205 } 5206 if (!country) { 5207 country = allCountries.find( 5208 (c) => `+${c.dialCode}` === initialCountryCode 5209 ); 5210 } 5211 if (country) { 5212 iti.setCountry(country.iso2); 5213 } 5214 } 5215 function getNumber() { 5216 return input.value; 5217 } 5218 function getCountryCode() { 5219 const countryData = iti.getSelectedCountryData(); 5220 return countryData.dialCode ? `+${countryData.dialCode}` : ""; 5221 } 5222 function getISOCode() { 5223 const countryData = iti.getSelectedCountryData(); 5224 return countryData.iso2 ? countryData.iso2 : ""; 5225 }
5226 function setNumber(phoneNumber, countryCode) { 5227 if (countryCode) { 5228 const allCountries = window.intlTelInputGlobals.getCountryData(); 5229 const country = allCountries.find( 5230 (c) => `+${c.dialCode}` === countryCode 5231 ); 5232 if (country) { 5233 iti.setCountry(country.iso2); 5234 } 5235 } 5236 iti.setNumber(phoneNumber); 5237 } 5238 input.phoneInputMethods = { 5239 getNumber, 5240 getCountryCode, 5241 setNumber, 5242 getISOCode, 5243 isValidNumber: () => iti.isValidNumber(), 5244 getValidationError: () => iti.getValidationError(), 5245 }; 5246 return input.phoneInputMethods; 5247} 5248$(function () { 5249 if ($("#project_users").length) { 5250 initSelect2Ajax( 5251 "#project_users", 5252 "/master-panel/users/search-users", 5253 label_select_user, 5254 true, 5255 0, 5256 true 5257 ); 5258 } 5259 if ($("#user_filter").length) { 5260 initSelect2Ajax( 5261 "#user_filter", 5262 "/master-panel/users/search-users", 5263 label_select_user, 5264 true, 5265 0, 5266 true 5267 ); 5268 } 5269 if ($("#project_clients").length) { 5270 initSelect2Ajax( 5271 "#project_clients", 5272 "/master-panel/clients/search-clients", 5273 label_select_client, 5274 true, 5275 0, 5276 true 5277 ); 5278 } 5279}); 5280$(document).ready(function () { 5281 $("#generate-password").on("click", function () { 5282 function generatePassword(length) { 5283 var charset = 5284 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()"; 5285 var password = ""; 5286 for (var i = 0, n = charset.length; i < length; ++i) { 5287 password += charset.charAt(Math.floor(Math.random() * n)); 5288 } 5289 return password; 5290 } 5291 // Generate a new random password 5292 var newPassword = generatePassword(12); 5293 // Set the generated password in both password and confirm password fields 5294 $("#password").val(newPassword); 5295 $("#password_confirmation").val(newPassword); 5296 // Ensure password is visible after generation 5297 var passwordField = $("#password"); 5298 var toggleIcon = $(".toggle-password i"); 5299 // Explicitly set the password field type to 'text' 5300 if (passwordField.attr("type") === "password") { 5301 passwordField.attr("type", "text"); // Show password 5302 // Ensure the toggle icon is in 'show' state 5303 toggleIcon.removeClass("bx-hide").addClass("bx-show"); 5304 } 5305 }); 5306}); 5307$(document).ready(function () { 5308 // Handle delete selected notes or todos 5309 $("#delete-selected").on("click", function () { 5310 const itemType = $(this).data("type"); 5311 const selectedIds = $(".selected-items:checked") 5312 .map(function () { 5313 return $(this).val(); 5314 }) 5315 .get(); 5316 if (selectedIds.length > 0) { 5317 $("#confirmDeleteSelectedModal").modal("show"); // show the confirmation modal 5318 $("#confirmDeleteSelectedModal").off( 5319 "click", 5320 "#confirmDeleteSelections" 5321 ); 5322 $("#confirmDeleteSelectedModal").on( 5323 "click", 5324 "#confirmDeleteSelections", 5325 function (e) { 5326 $("#confirmDeleteSelections") 5327 .html(label_please_wait) 5328 .attr("disabled", true); 5329 $.ajax({ 5330 url: 5331 "/master-panel" + 5332 "/" + 5333 itemType + 5334 "/destroy_multiple", // Adjust URL based on item type 5335 data: { 5336 ids: selectedIds, 5337 }, 5338 type: "POST", 5339 headers: { 5340 "X-CSRF-TOKEN": $('input[name="_token"]').attr( 5341 "value" 5342 ), 5343 }, 5344 success: function (response) { 5345 $("#confirmDeleteSelections") 5346 .html(label_yes) 5347 .attr("disabled", false); 5348 $("#confirmDeleteSelectedModal").modal("hide"); 5349 location.reload(); 5350 }, 5351 error: function (data) { 5352 $("#confirmDeleteSelections") 5353 .html(label_yes) 5354 .attr("disabled", false); 5355 $("#confirmDeleteSelectedModal").modal("hide"); 5356 toastr.error(label_something_went_wrong); 5357 }, 5358 }); 5359 } 5360 ); 5361 } else { 5362 toastr.error(label_please_select_records_to_delete); 5363 } 5364 }); 5365}); 5366$("#select-all").on("click", function () { 5367 $(".selected-items").prop("checked", this.checked); 5368}); 5369$(function () { 5370 if ($("#birthday_user_filter").length) { 5371 initSelect2Ajax( 5372 "#birthday_user_filter", 5373 "/master-panel/users/search-users", 5374 label_select_user, 5375 true, 5376 0, 5377 true 5378 ); 5379 } 5380 if ($("#wa_user_filter").length) { 5381 initSelect2Ajax( 5382 "#wa_user_filter", 5383 "/master-panel/users/search-users", 5384 label_select_user, 5385 true, 5386 0, 5387 true 5388 ); 5389 } 5390 if ($("#mol_user_filter").length) { 5391 initSelect2Ajax( 5392 "#mol_user_filter", 5393 "/master-panel/users/search-users", 5394 label_select_user, 5395 true, 5396 0, 5397 true 5398 ); 5399 } 5400}); 5401// Check Email Settings Functionality
5402$(document).on("click", "#test-email-settings", function () { 5403 const label_test_email_settings = $(this).html(); 5404 const test_url = $(this).data('url') || "/superadmin/settings/email/test-email-settings"; 5405 5406 $(this).html(label_please_wait).attr("disabled", true); 5407 $.ajax({ 5408 url: test_url, 5409 type: "POST", 5410 headers: { 5411 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 5412 }, 5413 success: function (response) { 5414 if (response.error) { 5415 toastr.error(response.message); 5416 } else { 5417 toastr.success(response.message); 5418 } 5419 $("#test-email-settings") 5420 .html(label_test_email_settings) 5421 .attr("disabled", false); 5422 }, 5423 error: function (data) { 5424 $("#test-email-settings") 5425 .html(label_test_email_settings) 5426 .attr("disabled", false); 5427 if (data.responseJSON && data.responseJSON.message) { 5428 toastr.error(data.responseJSON.message); 5429 } else { 5430 toastr.error(label_something_went_wrong); 5431 } 5432 }, 5433 }); 5434}); 5435 5436$(document).on("click", "#send-test-email-btn", function (e) { 5437 e.preventDefault(); 5438 const btn = $(this); 5439 const original_text = btn.html(); 5440 const test_url = $("#test-email-settings").data('url') || "/superadmin/settings/email/test-email-settings"; 5441 const email = $("#test_email_input").val(); 5442 5443 if (!email) { 5444 toastr.error("Please enter an email address."); 5445 return; 5446 } 5447 5448 const form = $("#test-email-settings").closest("form"); 5449 // Remove _method=PUT so Laravel doesn't spoof the AJAX POST request to PUT 5450 let serializedData = form.serialize().replace(/&?_method=(PUT|PATCH|DELETE)/gi, ''); 5451 const formData = serializedData + (serializedData ? "&" : "") + "test_email=" + encodeURIComponent(email); 5452 5453 btn.html(label_please_wait).attr("disabled", true); 5454 $.ajax({ 5455 url: test_url, 5456 type: "POST", 5457 data: formData, 5458 headers: { 5459 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), 5460 }, 5461 success: function (response) { 5462 if (response.error) { 5463 toastr.error(response.message); 5464 } else { 5465 toastr.success(response.message); 5466 $("#testEmailModal").modal('hide'); 5467 } 5468 btn.html(original_text).attr("disabled", false); 5469 }, 5470 error: function (data) { 5471 btn.html(original_text).attr("disabled", false); 5472 if (data.responseJSON && data.responseJSON.message) { 5473 toastr.error(data.responseJSON.message); 5474 } else { 5475 toastr.error(label_something_went_wrong); 5476 } 5477 }, 5478 }); 5479}); 5480function announcementCalendar() { 5481 const calendarEl = $("#announcements_calendar")[0]; // jQuery selector to get the DOM element 5482 5483 const editButton = '#editAnnouncementBtn'; 5484 const deleteButton = "#deleteAnnouncementBtn"; 5485 // FullCalendar Initialization 5486 const calendar = new FullCalendar.Calendar(calendarEl, { 5487 plugins: ["interaction", "dayGrid", "list"], 5488 headerToolbar: { 5489 left: "prev,next today", 5490 center: "title", 5491 right: "dayGridMonth,listYear", 5492 }, 5493 events: async function (info, successCallback, failureCallback) { 5494 try { 5495 // Make AJAX request to fetch dynamic data 5496 const response = await $.ajax({ 5497 url: "/master-panel/announcements/events", 5498 type: "GET", 5499 data: { 5500 startDate: info.startStr, 5501 endDate: info.endStr, 5502 }, 5503 }); 5504 console.log("Raw Response:", response); 5505 // Parse and format dynamic data for FullCalendar 5506 const events = response.map(event => ({ 5507 5508 id: event.id, 5509 title: event.title, 5510 start: event.start, 5511 end: event.end, 5512 created_by: event.created_by, 5513 backgroundColor: event.backgroundColor, 5514 borderColor: event.borderColor || event.backgroundColor, // Fallback 5515 textColor: event.textColor, 5516 extendedProps: event.extendedProps, // Pass extendedProps directly 5517 })); 5518 console.log("Parsed Events:", events); 5519 // Invoke success callback with dynamic data 5520 successCallback(events); 5521 } catch (error) { 5522 console.error("Error fetching events:", error); 5523 failureCallback(error); // Call failureCallback on error 5524 } 5525 }, 5526 eventClick: function (info) { 5527 // Show announcement details 5528 const event = info.event; 5529 $("#announcementTitle").text(event.title); 5530 $("#announcementContent").text(event.extendedProps.content); 5531 $("#announcementPriority").text(event.extendedProps.priority); 5532 $("#announcementCreatedBy").text(event.extendedProps.createdBy); 5533 const startDate = moment(event.start).format(js_date_format);
5534 const endDate = moment(event.end).subtract(1, 'day').format(js_date_format); 5535 $("#announcementStartDate").text(startDate); 5536 $("#announcementEndDate").text(endDate); 5537 const canEdit = $("#canEdit").val(); 5538 const canDelete = $("#canDelete").val(); 5539 const userId = $("#userId").val(); 5540 const isAdminOrHasAllDataAccess = $("#isAdminOrHasAllDataAccess").val(); 5541 // Show action buttons if the user is admin or the creator of the announcement 5542 $(editButton).data("id", event.id); 5543 $(deleteButton).data("id", event.id); 5544 $(editButton).attr("data-id", event.id); 5545 $(deleteButton).attr("data-id", event.id); 5546 // Debugging: log data-id values 5547 console.log("Edit Button data-id:", $(editButton).data("id")); 5548 console.log("Delete Button data-id:", $(deleteButton).data("id")); 5549 // Toggle button visibility 5550 5551 if (canEdit == 1 && userId == event.extendedProps.created_by) { 5552 5553 $(editButton).removeClass("d-none"); 5554 } else { 5555 $(editButton).addClass("d-none"); 5556 } 5557 if (canDelete == 1 || isAdminOrHasAllDataAccess == 1) { 5558 $(deleteButton).removeClass("d-none"); 5559 } else { 5560 $(deleteButton).addClass("d-none"); 5561 } 5562 5563 // Show the modal 5564 $("#announcementModal").modal("show"); 5565 }, 5566 timezone: 'UTC', // Adjust the timezone if necessary 5567 }); 5568 calendar.render(); 5569} 5570$(document).ready(function () { 5571 if ($('#announcements_calendar').length) { 5572 announcementCalendar(); 5573 } 5574}); 5575 5576// Announcements Update 5577 5578$(document).on("click", "#mark-all-announcement-as-read", function (e) { 5579 e.preventDefault(); 5580 $("#mark_all_announcements_as_read_modal").modal("show"); // show the confirmation modal 5581 $("#mark_all_announcements_as_read_modal").on( 5582 "click", 5583 "#confirmAnnouncementMarkAllAsRead", 5584 function () { 5585 $("#confirmAnnouncementMarkAllAsRead") 5586 .html(label_please_wait) 5587 .attr("disabled", true); 5588 $.ajax({ 5589 url: "/master-panel/announcements/mark-all-as-read", 5590 type: "PUT", 5591 headers: { 5592 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 5593 }, 5594 success: function (response) { 5595 location.reload(); 5596 5597 }, 5598 }); 5599 } 5600 ); 5601}); 5602 5603$(document).on("click", ".update-announcement-status", function (e) { 5604 var announcementId = $(this).data("id"); 5605 var needConfirm = $(this).data("needconfirm") || false; 5606 if (needConfirm) { 5607 // Show the confirmation modal 5608 $("#update_announcement_status_modal").modal("show"); 5609 // Attach click event handler to the confirmation button 5610 $("#update_announcement_status_modal").off( 5611 "click", 5612 "#confirmAnnouncementStatus" 5613 ); 5614 $("#update_announcement_status_modal").on( 5615 "click", 5616 "#confirmAnnouncementStatus", 5617 function () { 5618 $("#confirmAnnouncementStatus") 5619 .html(label_please_wait) 5620 .attr("disabled", true); 5621 performAnnouncementUpdate(announcementId, needConfirm); 5622 } 5623 ); 5624 } else { 5625 // If confirmation is not needed, directly perform the update and handle response 5626 performAnnouncementUpdate(announcementId); 5627 } 5628}); 5629function performAnnouncementUpdate(announcementId, needConfirm = "") { 5630 $.ajax({ 5631 url: "/master-panel/announcements/update-status", 5632 type: "PUT", 5633 data: { id: announcementId, needConfirm: needConfirm }, 5634 headers: { 5635 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 5636 }, 5637 success: function (response) { 5638 console.log(response); 5639 5640 if (needConfirm) { 5641 $("#confirmAnnouncementStatus") 5642 .html(label_yes) 5643 .attr("disabled", false); 5644 if (response.error == false) { 5645 toastr.success(response.message); 5646 $("#table").bootstrapTable("refresh"); 5647 } else { 5648 toastr.error(response.message); 5649 } 5650 $("#update_announcement_status_modal").modal("hide"); 5651 } 5652 }, 5653 }); 5654} 5655 5656const body = document.body; 5657
5658// If body does NOT have class "superadmin" 5659if (!body.classList.contains("superadmin")) { 5660 5661 /*if ( 5662 typeof manage_announcements !== "undefined" && 5663 manage_announcements == "true" 5664 ) { 5665 function updateUnreadAnnouncements() { 5666 // Make an AJAX request to fetch the count and HTML of unread announcements 5667 $.ajax({ 5668 url: "/master-panel/announcements/get-unread-announcements", 5669 type: "GET", 5670 dataType: "json", 5671 success: function (data) { 5672 const unreadAnnouncementsCount = data.count; 5673 const unreadAnnouncementsHtml = data.html; 5674 // Update the count in the badge 5675 $("#unreadAnnouncementsCount").text(unreadAnnouncementsCount); 5676 if (unreadNotificationsCount > 0) { 5677 $("#unreadNotificationsCount").removeClass('d-none'); 5678 } else { 5679 $("#unreadNotificationsCount").addClass('d-none'); 5680 } 5681 5682 // Update the announcements list with the new HTML 5683 $("#unreadAnnouncementsContainer").html(unreadAnnouncementsHtml); 5684 } 5685 }); 5686 } 5687 5688 updateUnreadAnnouncements(); 5689 // Update the unread announcements every 30 seconds 5690 setInterval(updateUnreadAnnouncements, 30000); 5691 }*/ 5692 5693 function updateUnreadNotifications() { 5694 //alert('aaaa=='); 5695 // Make an AJAX request to fetch the count and HTML of unread notifications 5696 $.ajax({ 5697 url: "/master-panel/notifications/get-unread-notifications", 5698 type: "GET", 5699 dataType: "json", 5700 success: function (data) { 5701 const unreadNotificationsCount = data.count; 5702 const unreadNotificationsHtml = data.html; 5703 console.log('unreadNotificationsCount', unreadNotificationsCount); 5704 // Update the count in the badge 5705 $("#unreadNotificationsCount").text(unreadNotificationsCount); 5706 if (unreadNotificationsCount > 0) { 5707 $("#unreadNotificationsCount").removeClass('d-none'); 5708 } else { 5709 $("#unreadNotificationsCount").addClass('d-none'); 5710 } 5711 5712 // Update the notifications list with the new HTML 5713 $("#unreadNotificationsContainer").html( 5714 unreadNotificationsHtml 5715 ); 5716 } 5717 }); 5718 } 5719 // Call the updateUnreadNotifications function initially 5720 updateUnreadNotifications(); 5721 // Update the unread notifications every 30 seconds 5722 setInterval(updateUnreadNotifications, 30000); 5723} 5724 5725 5726 5727// Task Reminder Settings 5728 5729$(document).ready(function () { 5730 // Toggle Reminder Settings Visibility 5731 $('#reminder-switch').on('change', function () { 5732 if ($(this).is(':checked')) { 5733 $('#reminder-settings').removeClass('d-none'); 5734 $('#time-of-day').prop('required', true); 5735 } else { 5736 $('#reminder-settings').addClass('d-none'); 5737 $('#time-of-day').prop('required', false); 5738 } 5739 }); 5740 5741 // Dynamic Display Based on Frequency Type 5742 $('#frequency-type').on('change', function () { 5743 const value = $(this).val(); 5744 $('#day-of-week-group').addClass('d-none'); 5745 $('#day-of-month-group').addClass('d-none'); 5746 5747 if (value === 'weekly') { 5748 $('#day-of-week-group').removeClass('d-none'); 5749 } else if (value === 'monthly') { 5750 $('#day-of-month-group').removeClass('d-none'); 5751 } 5752 }); 5753 5754 $('#edit-reminder-switch').on('change', function () { 5755 if ($(this).is(':checked')) { 5756 $('#edit-reminder-settings').removeClass('d-none'); 5757 } else { 5758 $('#edit-reminder-settings').addClass('d-none'); 5759 } 5760 }); 5761 $('#edit-frequency-type').on('change', function () { 5762 const value = $(this).val(); 5763 $('#edit-day-of-week-group').addClass('d-none'); 5764 $('#edit-day-of-month-group').addClass('d-none'); 5765 5766 if (value === 'weekly') { 5767 $('#edit-day-of-week-group').removeClass('d-none'); 5768 } else if (value === 'monthly') { 5769 $('#edit-day-of-month-group').removeClass('d-none'); 5770 } 5771 }); 5772}); 5773 5774// Recurring Task Settings 5775$(document).ready(function () { 5776 // Toggle Recurring Task Settings Visibility 5777 $('#recurring-task-switch').on('change', function () { 5778 if ($(this).is(':checked')) { 5779 $('#recurring-task-settings').removeClass('d-none'); 5780 $('#recurrence-frequency').prop('required', true); 5781 $('#recurrence-starts-from').prop('required', true); 5782 $('#recurrence-occurrences').prop('required', true); 5783 } else { 5784 $('#recurring-task-settings').addClass('d-none'); 5785 $('#recurrence-frequency').prop('required', false); 5786 $('#recurrence-starts-from').prop('required', false); 5787 $('#recurrence-occurrences').prop('required', false); 5788 } 5789 }); 5790 5791 // Dynamic Display Based on Recurrence Frequency Type 5792 $('#recurrence-frequency').on('change', function () { 5793 const value = $(this).val(); 5794 $('#recurrence-day-of-week-group').addClass('d-none'); 5795 $('#recurrence-day-of-month-group').addClass('d-none'); 5796 $('#recurrence-month-of-year-group').addClass('d-none'); 5797 5798 if (value === 'weekly') { 5799 $('#recurrence-day-of-week-group').removeClass('d-none'); 5800 } else if (value === 'monthly') { 5801 $('#recurrence-day-of-month-group').removeClass('d-none'); 5802 } else if (value === 'yearly') { 5803 $('#recurrence-day-of-month-group').removeClass('d-none'); 5804 $('#recurrence-month-of-year-group').removeClass('d-none'); 5805 } 5806 }); 5807 5808 // Initialize Settings on Page Load 5809 const initializeSettings = function () { 5810 if ($('#recurring-task-switch').is(':checked')) { 5811 $('#recurring-task-settings').removeClass('d-none'); 5812 } else { 5813 $('#recurring-task-settings').addClass('d-none'); 5814 } 5815 5816 const value = $('#recurrence-frequency').val(); 5817 if (value === 'weekly') { 5818 $('#recurrence-day-of-week-group').removeClass('d-none'); 5819 } else if (value === 'monthly') { 5820 $('#recurrence-day-of-month-group').removeClass('d-none'); 5821 } else if (value === 'yearly') { 5822 $('#recurrence-day-of-month-group').removeClass('d-none'); 5823 $('#recurrence-month-of-year-group').removeClass('d-none'); 5824 } 5825 }; 5826 5827 initializeSettings(); 5828}); 5829 5830//Edit Recurring Task Settings 5831$(document).ready(function () { 5832 // Toggle Recurring Task Settings Visibility 5833 $('#edit-recurring-task-switch').on('change', function () { 5834 if ($(this).is(':checked')) { 5835 $('#edit-recurring-task-settings').removeClass('d-none'); 5836 $('#edit-recurrence-frequency').prop('required', true); 5837 $('#edit-recurrence-starts-from').prop('required', true); 5838 $('#edit-recurrence-occurrences').prop('required', true); 5839 } else { 5840 $('#edit-recurring-task-settings').addClass('d-none'); 5841 $('#edit-recurrence-frequency').prop('required', false); 5842 $('#edit-recurrence-starts-from').prop('required', false); 5843 $('#edit-recurrence-occurrences').prop('required', false); 5844 } 5845 }); 5846 5847 // Dynamic Display Based on Recurrence Frequency Type 5848 $('#edit-recurrence-frequency').on('change', function () { 5849 const value = $(this).val(); 5850 $('#edit-recurrence-day-of-week-group').addClass('d-none'); 5851 $('#edit-recurrence-day-of-month-group').addClass('d-none'); 5852 $('#edit-recurrence-month-of-year-group').addClass('d-none'); 5853 5854 if (value === 'weekly') { 5855 $('#edit-recurrence-day-of-week-group').removeClass('d-none'); 5856 } else if (value === 'monthly') { 5857 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 5858 } else if (value === 'yearly') { 5859 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 5860 $('#edit-recurrence-month-of-year-group').removeClass('d-none'); 5861 } 5862 }); 5863 5864 // Initialize Settings on Page Load 5865 const editinitializeSettings = function () { 5866 if ($('#edit-recurring-task-switch').is(':checked')) { 5867 $('#edit-recurring-task-settings').removeClass('d-none'); 5868 } else { 5869 $('#edit-recurring-task-settings').addClass('d-none'); 5870 } 5871 5872 const value = $('#edit-recurrence-frequency').val(); 5873 if (value === 'weekly') { 5874 $('#edit-recurrence-day-of-week-group').removeClass('d-none'); 5875 } else if (value === 'monthly') { 5876 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 5877 } else if (value === 'yearly') { 5878 $('#edit-recurrence-day-of-month-group').removeClass('d-none'); 5879 $('#edit-recurrence-month-of-year-group').removeClass('d-none'); 5880 } 5881 }; 5882 5883 editinitializeSettings(); 5884}); 5885$(function () { 5886 if ($('.project-select').length > 0) { 5887 initSelect2Ajax('.project-select', 'tasks/search-projects', label_project); 5888 } 5889}) 5890 5891$(document).on("click", ".edit-task-list", function () { 5892 var id = $(this).data("id"); 5893 var routePrefix = $("#table").data("routePrefix"); 5894 $("#edit_task_list_modal").modal("show"); 5895 $.ajax({ 5896 url: "/master-panel/task-lists/get/" + id, 5897 type: "get", 5898 headers: { 5899 "X-CSRF-TOKEN": $('input[name="_token"]').attr("value"), // Replace with your method of getting the CSRF token 5900 }, 5901 dataType: "json", 5902 success: function (response) { 5903 console.log(response.task_list.id); 5904 5905 $("#task_list_id").val(response.task_list.id); 5906 $("#task_list_project").val(response.task_list.project.title); 5907 $("#task_list_name").val(response.task_list.name); 5908 var projectData = { 5909 id: response.task_list.project.id, // Ensure this matches your project's ID field 5910 text: response.task_list.project.title, // Ensure this matches your project's title field 5911 }; 5912 5913 var $projectSelect = $("#task_list_project_id"); 5914 $projectSelect.empty().append(new Option(projectData.text, projectData.id, true, true)).trigger("change"); 5915 }, 5916 }); 5917}); 5918 5919// Show the Active Tab 5920document.querySelectorAll('[data-bs-toggle="tab"]').forEach(function (button) { 5921 button.addEventListener("click", function () { 5922 // Check if the clicked button has the "list-button" or "calendar-button" class 5923 if ( 5924 this.classList.contains("list-button") || 5925 this.classList.contains("calendar-button") 5926 ) { 5927 // Remove bg-primary and text-white from "List" and "Calendar" buttons only 5928 document 5929 .querySelectorAll(".list-button, .calendar-button") 5930 .forEach(function (specificButton) { 5931 specificButton.classList.remove("bg-primary", "text-white"); 5932 }); 5933 5934 // Add bg-primary and text-white to the clicked button 5935 this.classList.add("bg-primary", "text-white"); 5936 } 5937 5938 // Handle nested tabs 5939 const parentPane = document.querySelector(this.dataset.bsTarget); 5940 if (parentPane) { 5941 parentPane 5942 .querySelectorAll(".list-button, .calendar-button") 5943 .forEach(function (subTab) { 5944 subTab.classList.remove("bg-primary", "text-white"); 5945 }); 5946 5947 const activeSubTab = parentPane.querySelector( 5948 ".list-button.active, .calendar-button.active" 5949 ); 5950 if (activeSubTab) { 5951 activeSubTab.classList.add("bg-primary", "text-white"); 5952 } 5953 } 5954 }); 5955});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.