|
|
|
function getUrlParameter(sParam) {
|
|
|
|
var sPageURL = window.location.search.substring(1),
|
|
|
|
sURLVariables = sPageURL.split('&'),
|
|
|
|
sParameterName,
|
|
|
|
i;
|
|
|
|
|
|
|
|
for (i = 0; i < sURLVariables.length; i++) {
|
|
|
|
sParameterName = sURLVariables[i].split('=');
|
|
|
|
|
|
|
|
if (sParameterName[0] === sParam) {
|
|
|
|
return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
const formatNumber = (angka) => {
|
|
|
|
var number_string = angka.replace(/[^,\d]/g, '').toString(),
|
|
|
|
split = number_string.split(','),
|
|
|
|
sisa = split[0].length % 3,
|
|
|
|
rupiah = split[0].substr(0, sisa),
|
|
|
|
ribuan = split[0].substr(sisa).match(/\d{3}/gi);
|
|
|
|
var separator = "";
|
|
|
|
if (ribuan) {
|
|
|
|
separator = sisa ? '.' : '';
|
|
|
|
rupiah += separator + ribuan.join('.');
|
|
|
|
}
|
|
|
|
|
|
|
|
rupiah = split[1] != undefined ? rupiah + ',' + split[1] : rupiah;
|
|
|
|
return rupiah
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCodeLinkByType(type) {
|
|
|
|
type = parseInt(type);
|
|
|
|
switch (type) {
|
|
|
|
case 1:
|
|
|
|
return "SS";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
return "FF";
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
return "SF";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return "FS";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var getInput = function (node) {
|
|
|
|
return node.querySelector("input");
|
|
|
|
};
|
|
|
|
|
|
|
|
gantt.config.editor_types.costPlanningEditor = {
|
|
|
|
show: function (id, column, config, placeholder) {
|
|
|
|
var min = config.min || 0
|
|
|
|
|
|
|
|
var html = "<div><input onkeyup='costPlanningChange(this)' type='text' min='" + min +
|
|
|
|
"' name='" + column.name + "'></div>";
|
|
|
|
placeholder.innerHTML = html;
|
|
|
|
},
|
|
|
|
hide: function () {
|
|
|
|
},
|
|
|
|
set_value: function (value, id, column, node) {
|
|
|
|
getInput(node).value = value;
|
|
|
|
},
|
|
|
|
get_value: function (id, column, node) {
|
|
|
|
return getInput(node).value || 0;
|
|
|
|
},
|
|
|
|
is_changed: function (value, id, column, node) {
|
|
|
|
var currentValue = this.get_value(id, column, node);
|
|
|
|
return value !== currentValue;
|
|
|
|
},
|
|
|
|
is_valid: function (value, id, column, node) {
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
focus: function (node) {
|
|
|
|
var input = getInput(node);
|
|
|
|
if (!input) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (input.focus) {
|
|
|
|
input.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (input.select) {
|
|
|
|
input.select();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
gantt.config.editor_types.progressCustom = {
|
|
|
|
show: function (id, column, config, placeholder) {
|
|
|
|
var min = config.min || 0,
|
|
|
|
max = config.max || 100;
|
|
|
|
|
|
|
|
var html = "<div><input type='number' min='" + min +
|
|
|
|
"' max='" + max + "' name='" + column.name + "'></div>";
|
|
|
|
placeholder.innerHTML = html;
|
|
|
|
},
|
|
|
|
hide: function () {
|
|
|
|
},
|
|
|
|
set_value: function (value, id, column, node) {
|
|
|
|
value = value * 100
|
|
|
|
getInput(node).value = value;
|
|
|
|
},
|
|
|
|
get_value: function (id, column, node) {
|
|
|
|
return getInput(node).value || 0;
|
|
|
|
},
|
|
|
|
is_changed: function (value, id, column, node) {
|
|
|
|
var currentValue = this.get_value(id, column, node);
|
|
|
|
return Number(value) !== Number(currentValue);
|
|
|
|
},
|
|
|
|
is_valid: function (value, id, column, node) {
|
|
|
|
return !isNaN(parseInt(value, 10));
|
|
|
|
},
|
|
|
|
focus: function (node) {
|
|
|
|
var input = getInput(node);
|
|
|
|
if (!input) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (input.focus) {
|
|
|
|
input.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (input.select) {
|
|
|
|
input.select();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function initializationProject() {
|
|
|
|
let projectId = getUrlParameter("proyek_id");
|
|
|
|
if (projectId && projectId > 0) {
|
|
|
|
$.ajax({
|
|
|
|
url: `${base_url}project/edit/${projectId}`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (result) {
|
|
|
|
let data = result.data;
|
|
|
|
let projectName = data.nama;
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
actionHappen = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSatuan() {
|
|
|
|
$.ajax({
|
|
|
|
url: `${base_url}satuan/list`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (result) {
|
|
|
|
let satuanList = [];
|
|
|
|
let resSatuan = result.data || []
|
|
|
|
resSatuan.map((val, index) => {
|
|
|
|
let satuan = {
|
|
|
|
key: val.id,
|
|
|
|
label: val.name,
|
|
|
|
text: val.name
|
|
|
|
}
|
|
|
|
satuanList.push(satuan)
|
|
|
|
});
|
|
|
|
|
|
|
|
// Clear the select element before appending new options
|
|
|
|
$('#uom-req-material').empty();
|
|
|
|
$('#uom-req-expense').empty();
|
|
|
|
|
|
|
|
// Append the new options to the select element
|
|
|
|
satuanList.forEach((option) => {
|
|
|
|
let newOption = new Option(option.label, option.label);
|
|
|
|
$('#uom-req-material').append(newOption);
|
|
|
|
});
|
|
|
|
|
|
|
|
satuanList.forEach((option) => {
|
|
|
|
let newOption = new Option(option.label, option.label);
|
|
|
|
$('#uom-req-expense').append(newOption);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Initialize select2 on the select element
|
|
|
|
$('#uom-req-material').select2({
|
|
|
|
dropdownParent: materialModal,
|
|
|
|
placeholder: 'Pilih satuan',
|
|
|
|
allowClear: true
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#uom-req-expense').select2({
|
|
|
|
dropdownParent: expenseModal,
|
|
|
|
placeholder: 'Pilih satuan',
|
|
|
|
allowClear: true
|
|
|
|
});
|
|
|
|
|
|
|
|
if (satuanList.length > 0) {
|
|
|
|
gantt.updateCollection("satuan", satuanList);
|
|
|
|
gantt.refreshData();
|
|
|
|
gantt.render();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateActivity(id) {
|
|
|
|
$.ajax({
|
|
|
|
url: `${base_url}task/get-update/${id}`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (result) {
|
|
|
|
let data = result.data;
|
|
|
|
gantt.getTask(id).assign_hr = data.assign_hr;
|
|
|
|
gantt.getTask(id).assign_material = data.assign_material;
|
|
|
|
gantt.getTask(id).assign_tools = data.assign_tools;
|
|
|
|
gantt.getTask(id).assign_expense = data.assign_expense;
|
|
|
|
gantt.getTask(id).bobot_planning = data.bobot_planning;
|
|
|
|
gantt.getTask(id).rencana_biaya = data.rencana_biaya;
|
|
|
|
gantt.getTask(id).biaya_actual = data.biaya_actual;
|
|
|
|
gantt.getTask(id).progress = data.progress;
|
|
|
|
gantt.getTask(id).jobs_done = data.jobs_done ? data.jobs_done : 0;
|
|
|
|
gantt.updateTask(id);
|
|
|
|
actionHappen = false;
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
actionHappen = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fungsi format ribuan label*/
|
|
|
|
function formatRupiah(n) {
|
|
|
|
var parts = n.toString().split(".");
|
|
|
|
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ".") + (parts[1] ? "," + parts[1] : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fungsi format ribuan inputan*/
|
|
|
|
function formatRibuanInput(angka, prefix) {
|
|
|
|
var number_string = angka.replace(/[^,\d]/g, '').toString(),
|
|
|
|
split = number_string.split(','),
|
|
|
|
sisa = split[0].length % 3,
|
|
|
|
rupiah = split[0].substr(0, sisa),
|
|
|
|
ribuan = split[0].substr(sisa).match(/\d{3}/gi);
|
|
|
|
|
|
|
|
if (ribuan) {
|
|
|
|
separator = sisa ? '.' : '';
|
|
|
|
rupiah += separator + ribuan.join('.');
|
|
|
|
}
|
|
|
|
|
|
|
|
rupiah = split[1] != undefined ? rupiah + ',' + split[1] : rupiah;
|
|
|
|
return prefix == undefined ? rupiah : (rupiah ? 'Rp. ' + rupiah : '');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fungsi replace titik, untuk save ke DB*/
|
|
|
|
function formatReplaceTitikRibuan(param) {
|
|
|
|
let myStr = param;
|
|
|
|
let newStr = myStr.replace(/\./g, '');
|
|
|
|
return newStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatDate(params) {
|
|
|
|
let today = new Date(params);
|
|
|
|
let yyyy = today.getFullYear();
|
|
|
|
let mm = today.getMonth() + 1; // Months start at 0!
|
|
|
|
let dd = today.getDate();
|
|
|
|
|
|
|
|
if (dd < 10) dd = '0' + dd;
|
|
|
|
if (mm < 10) mm = '0' + mm;
|
|
|
|
|
|
|
|
today = dd + '/' + mm + '/' + yyyy;
|
|
|
|
return today;
|
|
|
|
}
|
|
|
|
|
|
|
|
function roundToTwo(num) {
|
|
|
|
return +(Math.round(num + "e+2") + "e-2");
|
|
|
|
}
|
|
|
|
|
|
|
|
function initialProperty() {
|
|
|
|
$.ajax({
|
|
|
|
url: `${base_url}user-to-version-gantt/get-by-gantt/${ganttId}`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (result) {
|
|
|
|
let data = result.data;
|
|
|
|
if (data.status && data.status == "not have") {
|
|
|
|
toggleCollapseTasks();
|
|
|
|
} else {
|
|
|
|
if (data.id) {
|
|
|
|
userToVersionGanttId = data.id
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.critical_path) {
|
|
|
|
gantt.config.highlight_critical_path = true;
|
|
|
|
$("#critalPathBox").prop("checked", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.auto_schedule) {
|
|
|
|
gantt.config.auto_schedule = true;
|
|
|
|
$("#autoSchedule").prop("checked", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.committed_cost) {
|
|
|
|
$("#committedCostBox").val(data.committed_cost);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.cost_to_complete) {
|
|
|
|
$("#costToCompleteBox").val(data.cost_to_complete);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.zoom) {
|
|
|
|
gantt.ext.zoom.setLevel(data.zoom);
|
|
|
|
$('input[value="' + data.zoom + '"]').prop("checked", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.task_open) {
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
task.$open = true;
|
|
|
|
});
|
|
|
|
toggleTasks = "Collapse";
|
|
|
|
$("#gantt_toggle_task_btn").prop('title', 'Collapse Activities');
|
|
|
|
$("#gantt_toggle_task_btn").children().removeClass('fa-expand-alt');
|
|
|
|
$("#gantt_toggle_task_btn").children().addClass('fa-compress-alt');
|
|
|
|
} else {
|
|
|
|
toggleCollapseTasks();
|
|
|
|
}
|
|
|
|
|
|
|
|
gantt.render();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function initializationColumn() {
|
|
|
|
$.ajax({
|
|
|
|
url: `${base_url}gantt-show-hide/get-by-gantt/${ganttId}`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (result) {
|
|
|
|
let data = result.data;
|
|
|
|
if (data.status == "not yet have") {
|
|
|
|
addShowHideColumn();
|
|
|
|
} else if (data.status == "not have access") {
|
|
|
|
gantt.config.columns = createColumnsConfig(columnShows);
|
|
|
|
} else {
|
|
|
|
setUpForShowHideColumn(data);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setGanttOpen() {
|
|
|
|
let ganttOpen = [];
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
const existingIndex = ganttOpen.findIndex(item => item.id === task.id);
|
|
|
|
if (existingIndex !== -1) {
|
|
|
|
ganttOpen[existingIndex].open = task.$open;
|
|
|
|
} else {
|
|
|
|
ganttOpen.push({
|
|
|
|
"id": task.id,
|
|
|
|
"open": task.$open
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
localStorage.setItem('ganttOpen', JSON.stringify(ganttOpen));
|
|
|
|
}
|
|
|
|
|
|
|
|
function getGanttOpen() {
|
|
|
|
let ganttOpen = localStorage.getItem('ganttOpen');
|
|
|
|
if (ganttOpen) {
|
|
|
|
// Parse the stored data into a JavaScript object
|
|
|
|
ganttOpen = JSON.parse(ganttOpen);
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
const index = ganttOpen.findIndex(item => item.id == task.id);
|
|
|
|
if (index !== -1) {
|
|
|
|
task.$open = ganttOpen[index].open;
|
|
|
|
} else {
|
|
|
|
task.$open = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
$("#gantt_here").on("scroll", function () {
|
|
|
|
var container = $(this);
|
|
|
|
var scrollPositionX = container.scrollLeft();
|
|
|
|
});
|
|
|
|
|
|
|
|
$("#critalPathBox").on("change", function () {
|
|
|
|
let checked = $(this).is(":checked");
|
|
|
|
if (checked) {
|
|
|
|
gantt.config.highlight_critical_path = true;
|
|
|
|
updateProperty({ critical_path: true })
|
|
|
|
} else {
|
|
|
|
gantt.config.highlight_critical_path = false;
|
|
|
|
updateProperty({ critical_path: false })
|
|
|
|
}
|
|
|
|
gantt.render();
|
|
|
|
});
|
|
|
|
|
|
|
|
$("#autoSchedule").on("change", function () {
|
|
|
|
let checked = $(this).is(":checked");
|
|
|
|
if (checked) {
|
|
|
|
gantt.config.auto_schedule = true;
|
|
|
|
updateProperty({ auto_schedule: true })
|
|
|
|
} else {
|
|
|
|
gantt.config.auto_schedule = false;
|
|
|
|
updateProperty({ auto_schedule: false })
|
|
|
|
}
|
|
|
|
gantt.render();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
function linkLagEditor() {
|
|
|
|
|
|
|
|
function endPopup() {
|
|
|
|
modal = null;
|
|
|
|
editLinkId = null;
|
|
|
|
}
|
|
|
|
function cancelEditLink() {
|
|
|
|
endPopup()
|
|
|
|
}
|
|
|
|
|
|
|
|
function deleteLink() {
|
|
|
|
gantt.deleteLink(editLinkId);
|
|
|
|
endPopup()
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveLink() {
|
|
|
|
var link = gantt.getLink(editLinkId);
|
|
|
|
|
|
|
|
var lagValue = modal.querySelector(".lag-input").value;
|
|
|
|
if (!isNaN(parseInt(lagValue, 10))) {
|
|
|
|
link.lag = parseInt(lagValue, 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
gantt.updateLink(link.id);
|
|
|
|
if (gantt.autoSchedule) {
|
|
|
|
gantt.autoSchedule(link.source);
|
|
|
|
}
|
|
|
|
endPopup();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var modal;
|
|
|
|
var editLinkId;
|
|
|
|
gantt.attachEvent("onLinkDblClick", function (id, e) {
|
|
|
|
editLinkId = id;
|
|
|
|
var link = gantt.getLink(id);
|
|
|
|
var linkTitle;
|
|
|
|
switch (link.type) {
|
|
|
|
case gantt.config.links.finish_to_start:
|
|
|
|
linkTitle = "FS";
|
|
|
|
break;
|
|
|
|
case gantt.config.links.finish_to_finish:
|
|
|
|
linkTitle = "FF";
|
|
|
|
break;
|
|
|
|
case gantt.config.links.start_to_start:
|
|
|
|
linkTitle = "SS";
|
|
|
|
break;
|
|
|
|
case gantt.config.links.start_to_finish:
|
|
|
|
linkTitle = "SF";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
linkTitle += " " + gantt.getTask(link.source).text + " -> " + gantt.getTask(link.target).text;
|
|
|
|
|
|
|
|
modal = gantt.modalbox({
|
|
|
|
title: linkTitle,
|
|
|
|
text: "<div>" +
|
|
|
|
"<label>Lag <input type='number' class='lag-input' /></label>" +
|
|
|
|
"</div>",
|
|
|
|
buttons: [
|
|
|
|
{ label: "Save", css: "link-save-btn", value: "save" },
|
|
|
|
{ label: "Cancel", css: "link-cancel-btn", value: "cancel" },
|
|
|
|
{ label: "Delete", css: "link-delete-btn", value: "delete" }
|
|
|
|
],
|
|
|
|
width: "500px",
|
|
|
|
type: "popup-css-class-here",
|
|
|
|
callback: function (result) {
|
|
|
|
switch (result) {
|
|
|
|
case "save":
|
|
|
|
saveLink();
|
|
|
|
break;
|
|
|
|
case "cancel":
|
|
|
|
cancelEditLink();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "delete":
|
|
|
|
deleteLink();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
modal.querySelector(".lag-input").value = link.lag || 0;
|
|
|
|
|
|
|
|
//any custom logic here
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function addShowHideColumn() {
|
|
|
|
submitShowHideColumn(columnShows);
|
|
|
|
}
|
|
|
|
|
|
|
|
function submitShowHideColumn(allColumn) {
|
|
|
|
let payload = {
|
|
|
|
version_gantt_id: ganttId,
|
|
|
|
columns: allColumn
|
|
|
|
}
|
|
|
|
gantt.config.columns = createColumnsConfig(allColumn);
|
|
|
|
$.ajax({
|
|
|
|
data: JSON.stringify(payload),
|
|
|
|
url: `${base_url}gantt-show-hide/add`,
|
|
|
|
type: "POST",
|
|
|
|
processData: false,
|
|
|
|
contentType: false,
|
|
|
|
success: function (data) {
|
|
|
|
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setUpForShowHideColumn(data) {
|
|
|
|
let columns = data || []
|
|
|
|
|
|
|
|
let configColumn = {}
|
|
|
|
|
|
|
|
columns.map((val, index) => {
|
|
|
|
configColumn[val.column_name] = val.show
|
|
|
|
});
|
|
|
|
if (!isBaselineSet) {
|
|
|
|
configColumn.planned_start = undefined;
|
|
|
|
configColumn.planned_end = undefined;
|
|
|
|
configColumn.planned_duration = undefined;
|
|
|
|
configColumn.baseline_progress = undefined;
|
|
|
|
}
|
|
|
|
gantt.config.columns = createColumnsConfig(configColumn);
|
|
|
|
|
|
|
|
gantt.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateShowHideColumn(data) {
|
|
|
|
let payload = {
|
|
|
|
columns: data
|
|
|
|
}
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
data: JSON.stringify(payload),
|
|
|
|
url: `${base_url}gantt-show-hide/update/${ganttId}`,
|
|
|
|
type: "POST",
|
|
|
|
processData: false,
|
|
|
|
contentType: false,
|
|
|
|
success: function (data) {
|
|
|
|
console.log(data);
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
console.log(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function colAjaxReq(type) {
|
|
|
|
let ajx = $.ajax({
|
|
|
|
url: `${base_url}gantt-show-hide/get-column-by-type/${type}`,
|
|
|
|
type: "GET",
|
|
|
|
success: function (data) {
|
|
|
|
let ganttColumnsByType = data.data;
|
|
|
|
let isFound = false;
|
|
|
|
x = gantt.config.columns.filter((val) => {
|
|
|
|
isFound = ganttColumnsByType.find(obj => {
|
|
|
|
return obj.column_name == val.name;
|
|
|
|
});
|
|
|
|
if (isFound)
|
|
|
|
return val;
|
|
|
|
});
|
|
|
|
gantt.config.columns = x.filter(item => item);
|
|
|
|
allColumns = gantt.config.columns;
|
|
|
|
gantt.render();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async function reRenderColumns(type) {
|
|
|
|
await colAjaxReq(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateProperty(payload) {
|
|
|
|
if (userToVersionGanttId > 0 && readOnly && parseInt(readOnly) == 0) {
|
|
|
|
$.ajax({
|
|
|
|
data: JSON.stringify(payload),
|
|
|
|
url: `${base_url}user-to-version-gantt/update/${userToVersionGanttId}`,
|
|
|
|
type: "PUT",
|
|
|
|
processData: false,
|
|
|
|
contentType: false,
|
|
|
|
success: function (data) {
|
|
|
|
},
|
|
|
|
error: function (data) {
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function costPlanningChange(e) {
|
|
|
|
let value = e.value;
|
|
|
|
value = replaceAll(value, ".", "")
|
|
|
|
value = replaceAll(value, ",", ".")
|
|
|
|
let newValue = formatRupiah(value);
|
|
|
|
$(e).val(newValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
function escapeRegExp(string) {
|
|
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
|
}
|
|
|
|
|
|
|
|
function replaceAll(str, find, replace) {
|
|
|
|
if (str) {
|
|
|
|
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
|
|
|
|
}
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
function expandTask() {
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
task.$open = true;
|
|
|
|
});
|
|
|
|
toggleTasks = "Collapse";
|
|
|
|
$("#gantt_toggle_task_btn").prop('title', 'Collapse Activities');
|
|
|
|
$("#gantt_toggle_task_btn").children().removeClass('fa-expand-alt');
|
|
|
|
$("#gantt_toggle_task_btn").children().addClass('fa-compress-alt');
|
|
|
|
gantt.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Function to get the earliest planned start date among all tasks
|
|
|
|
function getEarliestTaskDate() {
|
|
|
|
var earliestDate = null;
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
var taskStartDate = task.planned_start || task.start_date;
|
|
|
|
if (!earliestDate || task.planned_start < earliestDate) {
|
|
|
|
earliestDate = taskStartDate;
|
|
|
|
if (task.start_date < earliestDate) {
|
|
|
|
earliestDate = task.start_date;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return earliestDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Function to get the latest planned end date among all tasks
|
|
|
|
function getLatestTaskDate() {
|
|
|
|
var latestDate = null;
|
|
|
|
gantt.eachTask(function (task) {
|
|
|
|
var taskEndDate = task.planned_end || task.end_date;
|
|
|
|
if (!latestDate || task.planned_end > latestDate) {
|
|
|
|
latestDate = taskEndDate;
|
|
|
|
if (task.end_date > latestDate) {
|
|
|
|
latestDate = task.end_date;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return latestDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
function batchUpdate(){
|
|
|
|
let data = localStorage.getItem('batchEntity');
|
|
|
|
$("body").addClass("loading");
|
|
|
|
return gantt.ajax.post({
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Authorization": `Bearer ${token}`
|
|
|
|
},
|
|
|
|
url: base_url + "activity/batch-update/" + ganttId,
|
|
|
|
data: data
|
|
|
|
}).then(function (response) {
|
|
|
|
$("body").removeClass("loading");
|
|
|
|
localStorage.setItem('batchEntity', '');
|
|
|
|
$("#save-activity").hide();
|
|
|
|
sendStorage();
|
|
|
|
refresData();
|
|
|
|
}).catch(function (error) {
|
|
|
|
$("body").removeClass("loading")
|
|
|
|
|
|
|
|
gantt.alert({
|
|
|
|
title: "Peringatan",
|
|
|
|
type: "alert-error",
|
|
|
|
text: "Update activity gagal"
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
$(window).on('beforeunload', function(event) {
|
|
|
|
let batchEntity = localStorage.getItem('batchEntity');
|
|
|
|
sendStorage();
|
|
|
|
if (batchEntity && batchEntity != '') {
|
|
|
|
event.preventDefault()
|
|
|
|
return event.returnValue = 'You have unsaved changes. Are you sure you want to leave this page?';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function sendStorage(){
|
|
|
|
const batchEntityData = localStorage.getItem('batchEntity');
|
|
|
|
window.parent.postMessage({ batchEntity: batchEntityData }, '*');
|
|
|
|
}
|