You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
701 lines
17 KiB
701 lines
17 KiB
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 |
|
}); |
|
|
|
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', ''); |
|
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'); |
|
if (batchEntity && batchEntity != '') { |
|
event.preventDefault() |
|
return event.returnValue = 'You have unsaved changes. Are you sure you want to leave this page?'; |
|
} |
|
}); |
|
|
|
const batchEntityData = localStorage.getItem('batchEntity'); |
|
window.parent.postMessage({ batchEntity: batchEntityData }, '*'); |