leantime.projectsController = (function () { function countTickets() { jQuery("#sortableTicketKanban .column").each(function () { var counting = jQuery(this).find('.moveable').length; jQuery(this).find(' .count').text(counting); }); } //Functions var initDates = function () { jQuery(".projectDateFrom, .projectDateTo").datepicker( { dateFormat: leantime.dateHelper.getFormatFromSettings("dateformat", "jquery"), dayNames: leantime.i18n.__("language.dayNames").split(","), dayNamesMin: leantime.i18n.__("language.dayNamesMin").split(","), dayNamesShort: leantime.i18n.__("language.dayNamesShort").split(","), monthNames: leantime.i18n.__("language.monthNames").split(","), currentText: leantime.i18n.__("language.currentText"), closeText: leantime.i18n.__("language.closeText"), buttonText: leantime.i18n.__("language.buttonText"), isRTL: leantime.i18n.__("language.isRTL") === "true" ? 1 : 0, nextText: leantime.i18n.__("language.nextText"), prevText: leantime.i18n.__("language.prevText"), weekHeader: leantime.i18n.__("language.weekHeader"), } ); }; var initProjectTabs = function () { jQuery('.projectTabs').tabs(); }; var initDuplicateProjectModal = function () { var regularModelConfig = { sizes: { minW: 450, minH: 350 }, resizable: true, autoSizable: true, callbacks: { afterShowCont: function () { jQuery(".showDialogOnLoad").show(); initDates(); jQuery(".duplicateProjectModal, .formModal").nyroModal(regularModelConfig); }, beforeClose: function () { location.reload(); } } }; jQuery(".duplicateProjectModal").nyroModal(regularModelConfig); }; var initProgressBar = function (percentage) { jQuery("#progressbar").progressbar({ value: percentage }); }; var initProjectTable = function () { jQuery(document).ready(function () { var size = 100; var allProjects = jQuery("#allProjectsTable").DataTable({ "language": { "decimal": leantime.i18n.__("datatables.decimal"), "emptyTable": leantime.i18n.__("datatables.emptyTable"), "info": leantime.i18n.__("datatables.info"), "infoEmpty": leantime.i18n.__("datatables.infoEmpty"), "infoFiltered": leantime.i18n.__("datatables.infoFiltered"), "infoPostFix": leantime.i18n.__("datatables.infoPostFix"), "thousands": leantime.i18n.__("datatables.thousands"), "lengthMenu": leantime.i18n.__("datatables.lengthMenu"), "loadingRecords": leantime.i18n.__("datatables.loadingRecords"), "processing": leantime.i18n.__("datatables.processing"), "search": leantime.i18n.__("datatables.search"), "zeroRecords": leantime.i18n.__("datatables.zeroRecords"), "paginate": { "first": leantime.i18n.__("datatables.first"), "last": leantime.i18n.__("datatables.last"), "next": leantime.i18n.__("datatables.next"), "previous": leantime.i18n.__("datatables.previous"), }, "aria": { "sortAscending": leantime.i18n.__("datatables.sortAscending"), "sortDescending":leantime.i18n.__("datatables.sortDescending"), } }, "dom": '<"top">rt<"bottom"ilp><"clear">', "searching": false, "displayLength":100 }); }); }; var initTodoStatusSortable = function (element) { var sortCounter = 1; jQuery(element).find("input.sorter").each(function (index) { jQuery(this).val(sortCounter); sortCounter++; }); jQuery(element).sortable({ stop: function ( event, ui ) { sortCounter = 1; jQuery(element).find("input.sorter").each(function (index) { jQuery(this).val(sortCounter); sortCounter++; }); } }); }; var initSelectFields = function () { jQuery(document).ready(function () { jQuery("#todosettings select.colorChosen").on('chosen:ready', function (e, params) { var id = jQuery(this).attr('id').replace("-", "_"); jQuery("#" + id + "_chosen a span").removeClass(); jQuery("#" + id + "_chosen a span").addClass(params.selected); }).chosen({ disable_search_threshold: 10 }); jQuery("#todosettings select.colorChosen").on('change', function (evt, params) { var id = jQuery(this).attr('id').replace("-", "_"); jQuery("#" + id + "_chosen a span").removeClass(); jQuery("#" + id + "_chosen a span").addClass(params.selected); }); }); }; var removeStatus = function (id) { jQuery("#todostatus-" + id).parent().remove(); }; var addToDoStatus = function (id) { var highestKey = -1; jQuery("#todosettings ul .statusList").each(function () { var keyInt = jQuery(this).find('.labelKey').val(); if (parseInt(keyInt) >= parseInt(highestKey)) { highestKey = keyInt; } }); var newKey = parseInt(highestKey) + 1; var statusCopy = jQuery(".newStatusTpl").clone(); statusCopy.html(function (i, oldHTML) { return updatedContent = oldHTML.replaceAll('XXNEWKEYXX', newKey); }); jQuery('#todoStatusList').append("
  • " + statusCopy.html() + "
  • "); jQuery("#todosettings select.colorChosen").chosen("destroy"); leantime.projectsController.initSelectFields(); jQuery("#todoStatusList").sortable("destroy"); leantime.projectsController.initTodoStatusSortable("#todoStatusList"); }; var readURL = function (input) { clearCroppie(); if (input.files && input.files[0]) { var reader = new FileReader(); var profileImg = jQuery('#projectAvatar'); reader.onload = function (e) { //profileImg.attr('src', e.currentTarget.result); _uploadResult = profileImg .croppie( { enableExif: true, viewport: { width: 200, height: 200, type: 'rectangle' }, boundary: { width: 250, height: 250 } } ); _uploadResult.croppie( 'bind', { url: e.currentTarget.result } ); jQuery("#previousImage").hide(); }; reader.readAsDataURL(input.files[0]); } }; var clearCroppie = function () { jQuery('#profileImg').croppie('destroy'); jQuery("#previousImage").show(); }; var saveCroppie = function () { jQuery('#save-picture').addClass('running'); jQuery('#profileImg').attr('src', leantime.appUrl + '/images/loaders/loader28.gif'); _uploadResult.croppie( 'result', { type: "blob", circle: false } ).then( function (result) { var formData = new FormData(); formData.append('file', result); jQuery.ajax( { type: 'POST', url: leantime.appUrl + '/projects/projectImage', data: formData, processData: false, contentType: false, success: function (resp) { jQuery('#save-picture').removeClass('running'); location.reload(); }, error: function (err) { console.log(err); } } ); } ); }; var initGanttChart = function (projects, viewMode, readonly) { function htmlEntities(str) { return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } jQuery(document).ready( function () { // The Gantt constructor fires on_view_change once while building. Persisting that // event would overwrite the user's saved scale with the default, so ignore any // view change until construction is finished; only user-driven changes save. var ganttInitializing = true; if (readonly === false) { var gantt_chart = new Gantt( "#gantt", projects, { header_height: 55, column_width: 20, step: 24, view_modes: ['Day', 'Week', 'Month'], bar_height: 40, static_progress_indicator: true, bar_corner_radius: 10, arrow_curve: 10, padding:20, view_mode: viewMode, date_format: leantime.i18n.__("language.momentJSDate"), language: 'en', // or 'es', 'it', 'ru', 'ptBr', 'fr', 'tr', 'zh' additional_rows: 5, custom_popup_html: function (project) { // the task object will contain the updated // dates and progress value var end_date = project._end; var popUpHTML = '
    '; if (project.projectName !== undefined) { popUpHTML += '

    ' + project.name + '

    '; } popUpHTML += '

    ' + htmlEntities(project.name) + '


    '; popUpHTML += '
    '; return popUpHTML; }, on_click: function (project) { //_initModals(); }, on_date_change: function (project, start, end) { var idParts = project.id.split("-"); let entityId = 0; let entityType = ""; if (idParts.length > 1) { if (idParts[0] == "ticket") { entityId = idParts[1]; entityType = "ticket" } else if (idParts[0] == "pgm") { entityId = idParts[1]; entityType = "project" } } else { entityId = idParts; } if (entityType == "ticket") { leantime.ticketsRepository.updateMilestoneDates(entityId, start, end, project._index+1); } else { leantime.rpc('Projects.Projects.patchProject', { id: entityId, values: { start: start, end: end, sortIndex: project._index + 1, } }).catch(function (e) { jQuery.growl({ message: (e && e.message) ? e.message : leantime.i18n.__("short_notifications.not_saved"), style: "error" }); console.error('Could not update project dates', e); }); } //leantime.ticketsRepository.updateMilestoneDates(task.id, start, end, task._index); //_initModals(); }, on_sort_change: function (projects) { var sortPayload = {}; for (var i = 0; i < projects.length; i++) { sortPayload[projects[i].id] = projects[i]._index+1; } leantime.rpc('Projects.Projects.sortProjects', { params: sortPayload }) .catch(function (e) { jQuery.growl({ message: (e && e.message) ? e.message : leantime.i18n.__("short_notifications.not_saved"), style: "error" }); console.error('Could not sort projects', e); }); }, on_progress_change: function (project, progress) { //_initModals(); }, on_view_change: function (mode) { if (ganttInitializing) { return; } leantime.usersRepository.updateUserViewSettings("projectGantt", mode); }, on_popup_show: function (project) { } } ); } else { var gantt_chart = new Gantt( "#gantt", projects, { readonlyGantt: true, resizing: false, progress: false, is_draggable: false, view_modes: ['Day', 'Week', 'Month'], view_mode: viewMode, custom_popup_html: function (project) { var popUpHTML = '
    '; if (project.projectName !== undefined) { popUpHTML += '

    ' + project.name + '

    '; } popUpHTML += '

    ' + htmlEntities(project.name) + '


    '; popUpHTML += '
    '; return popUpHTML; }, on_click: function (project) { }, on_date_change: function (project, start, end) { }, on_progress_change: function (project, progress) { //_initModals(); }, on_view_change: function (mode) { if (ganttInitializing) { return; } leantime.usersRepository.updateUserViewSettings("projectGantt", mode); } } ); } jQuery("#ganttTimeControl").on( "click", "a", function () { var $btn = jQuery(this); var mode = $btn.attr("data-value"); gantt_chart.change_view_mode(mode); $btn.parent().parent().find('a').removeClass('active'); $btn.addClass('active'); var label = $btn.text(); jQuery(".viewText").text(label); } ); // Constructor already built the chart at the saved viewMode; construction is done, // so from here on real user-driven view changes are allowed to persist. ganttInitializing = false; } ); }; var setUpKanbanColumns = function () { jQuery(document).ready(function () { countTickets(); jQuery(".filterBar .row-fluid").css("opacity", "1"); var height = jQuery("html").height() - 250; jQuery("#sortableProjectKanban .column .contentInner").each(function () { if (jQuery(this).height() > height) { height = jQuery(this).height(); } }); height = height + 50; jQuery("#sortableProjectKanban .column .contentInner").css("min-height", height); }); }; var initProjectsKanban = function (statusList) { jQuery("#sortableProjectKanban .projectBox").hover(function () { jQuery(this).css("background", "var(--kanban-card-hover)"); },function () { jQuery(this).css("background", "var(--kanban-card-bg)"); }); var position_updated = false; jQuery("#sortableProjectKanban .contentInner").sortable({ connectWith: ".contentInner", items: "> .moveable", tolerance: 'intersect', placeholder: "ui-state-highlight", forcePlaceholderSize: true, cancel: ".portlet-toggle,:input,a,input", distance: 25, start: function (event, ui) { ui.item.addClass('tilt'); tilt_direction(ui.item); }, stop: function (event, ui) { ui.item.removeClass("tilt"); jQuery("html").unbind('mousemove', ui.item.data("move_handler")); ui.item.removeData("move_handler"); countTickets(); var sortPayload = {}; var handler = ui.item[0].id; for (var i = 0; i < statusList.length; i++) { if (jQuery(".contentInner.status_" + statusList[i]).length) { sortPayload[statusList[i]] = jQuery(".contentInner.status_" + statusList[i]).sortable('serialize'); } } leantime.rpc('Projects.Projects.patchProjectStatusAndSorting', { params: sortPayload, handler: handler }) .catch(function (e) { jQuery.growl({ message: (e && e.message) ? e.message : leantime.i18n.__("short_notifications.not_saved"), style: "error" }); console.error('Could not update project sorting', e); }); } }); function tilt_direction(item) { var left_pos = item.position().left, move_handler = function (e) { if (e.pageX >= left_pos) { item.addClass("right"); item.removeClass("left"); } else { item.addClass("left"); item.removeClass("right"); } left_pos = e.pageX; }; jQuery("html").bind("mousemove", move_handler); item.data("move_handler", move_handler); } jQuery(".portlet") .addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all") .find(".portlet-header") .addClass("ui-widget-header ui-corner-all") .prepend(""); jQuery(".portlet-toggle").click(function () { var icon = jQuery(this); icon.toggleClass("ui-icon-minusthick ui-icon-plusthick"); icon.closest(".portlet").find(".portlet-content").toggle(); }); }; var favoriteProject = function(id, element) { jQuery(element).addClass("go"); if (jQuery(element).hasClass("isFavorite")) { leantime.reactionsController.removeReaction( 'project', id, 'favorite', function() { jQuery(element).find("i").removeClass("fa-solid").addClass("fa-regular"); jQuery(element).removeClass("isFavorite"); } ); } else { leantime.reactionsController.addReactions( 'project', id, 'favorite', function() { jQuery(element).find("i").removeClass("fa-regular").addClass("fa-solid"); jQuery(element).addClass("isFavorite"); } ); } } // Make public what you want to have public, everything else is private return { initDates:initDates, initProjectTabs:initProjectTabs, initProgressBar:initProgressBar, initProjectTable:initProjectTable, initDuplicateProjectModal:initDuplicateProjectModal, initTodoStatusSortable:initTodoStatusSortable, initSelectFields:initSelectFields, removeStatus:removeStatus, addToDoStatus:addToDoStatus, saveCroppie:saveCroppie, clearCroppie:clearCroppie, readURL:readURL, initGanttChart:initGanttChart, setUpKanbanColumns:setUpKanbanColumns, initProjectsKanban:initProjectsKanban, favoriteProject:favoriteProject }; })();