const ganttId = getUrlParameter("gantt_id"); const readOnly = getUrlParameter("ro"); const proyekId = getUrlParameter("proyek_id"); let base_url = getUrlParameter("base_url"); const base_url_image = "https://adw-api.ospro.id/assets/image/"; const adwIntegrationUrl = "https://adw-api.ospro.id/api"; let userToVersionGanttId = 0 let activityId = 0; let actionHappen = false; let activityName = ""; let token = getUrlParameter("token"); if (!token || token == "") { token = `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvYXBpLWl1Lm9zcHJvLmlkXC9hcGlcL2xvZ2luIiwiaWF0IjoxNjQ2ODA3OTA4LCJleHAiOjE2NDY4OTQzMDgsIm5iZiI6MTY0NjgwNzkwOCwianRpIjoiNmdtcEx3cjlob1JFZ0hSNSIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.1xB2rvTJ6Edf7l_8jRPOmoMYnf8f59Rd8jJghJ39xps`; } const axiosInstance = axios.create({ headers: { "Authorization": `Bearer ${token}`, "Content-type": "application/json" } }); axiosInstance.interceptors.request.use(async (config) => { try{ $("body").addClass("loading"); } catch(e) { $("body").removeClass("loading"); alert('Error request' + e); } return config; }); axiosInstance.interceptors.response.use(async (config) => { try { $("body").removeClass("loading"); } catch(e) { $("body").removeClass("loading"); alert('Error response' + e); } return config; }); const HEADER = { headers: { 'Authorization': `Bearer ${token}`, "Content-type": `application/json` } }; $.ajaxSetup({ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}` } }); $(document).on({ ajaxStart: function(){ $("body").addClass("loading"); }, ajaxStop: function(){ $("body").removeClass("loading"); } }); gantt.plugins({ drag_timeline: true, critical_path: true , auto_scheduling: true }); gantt.config.date_format = "%Y-%m-%d %H:%i:%s"; gantt.config.auto_scheduling = true; gantt.config.fit_tasks = true; if (!base_url) { base_url = `https://api-iu.ospro.id/api/`; }else{ base_url = base_url+"/"; } // gantt plugins gantt.plugins({ marker: true, fullscreen: true }); // add today line var dateToStr = gantt.date.date_to_str(gantt.config.task_date); var markerId = gantt.addMarker({ start_date: new Date(), css: "today", text: "Today", title: dateToStr(new Date()) }); gantt.getMarker(markerId); //->{css:"today", text:"Now", id:...} var colHeader = '
', colContent = function (task) { var hasChild = gantt.hasChild(task.id); var optionsContent = '
'; optionsContent += ' '; optionsContent += ' '; optionsContent += ' '; optionsContent += !hasChild ? ' ' : ''; optionsContent += !hasChild ? ' ' : ''; optionsContent += !hasChild ? ' ' : ''; optionsContent += '
'; return (optionsContent); }; let no = 4; // for temporary change with last id in database m_activity var formatter = gantt.ext.formatters.durationFormatter({ enter: "day", store: "day", format: "auto" }); var progressEditor = {type: "progressCustom", map_to: "progress", min:0, max: 100}; var costPlanningEditor = {type: "costPlanningEditor", map_to: "rencana_biaya", min:0}; var linksFormatter = gantt.ext.formatters.linkFormatter({ durationFormatter: formatter }); function satuanLabel(task){ var value = task.satuan_id; var list = gantt.serverList("satuan"); if(value){ for(var i = 0; i < list.length; i++){ if(list[i].key == parseInt(value)){ return list[i].label; } } } return ""; } // use the default editor custom for end_date, but override set_value/get_value methods var dateEditor = gantt.config.editor_types.date; gantt.config.editor_types.end_date = gantt.mixin({ set_value: function(value, id, column, node){ var correctedValue = gantt.date.add(value, -1, "day"); return dateEditor.set_value.apply(this, [correctedValue, id, column, node]); }, get_value: function(id, column, node) { var selectedValue = dateEditor.get_value.apply(this, [id, column, node]); return gantt.date.add(selectedValue, 1, "day"); }, }, dateEditor); const editor = { text: { type: "text", map_to: "text" }, kode_sortname: { type: "text", map_to: "kode_sortname" }, start_date: { type: "date", map_to: "start_date", min: new Date(2018, 0, 1) }, end_date: { type: "date", map_to: "end_date", min: new Date(2018, 0, 1) }, duration: { type: "duration", map_to: "duration", min: 0, max: 365, formatter: formatter }, cost: { type: "number", map_to: "rencana_biaya", min: 0 }, costActual: { type: "number", map_to: "biaya_actual", min: 0 }, status: { type: "text", map_to: "status" }, job_count: { type: "number", map_to: "jumlah_pekerjaan", min: 0 }, job_unit: { type: "text", map_to: "satuan", min: 0 }, bobot_planning:{ type: "number", map_to: "bobot_planning", min: 0 }, human_resource: (`
   
`), satuan:{type: "select", map_to: "satuan_id", options:gantt.serverList("satuan")} } function addWithoutParent() { var task = gantt.getTaskByIndex(0); let start_date = new Date(); if (task) { start_date = task.start_date; } var taskId = gantt.addTask({ id: no, text: `New Activity`, start_date: start_date, biaya: 10000, duration: 1 }); gantt.selectTask(taskId); no = no + 1; } function addWithParent(id) { var task = gantt.getTask(id); let start_date = new Date(); if (task) { start_date = task.start_date; } gantt.addTask({ id: no, text: `New Activity`, start_date: start_date, duration: 0 }, id); no = no + 1; } function clickGridButton(id, action) { switch (action) { case "edit": gantt.showLightbox(id); break; case "add": addWithParent(id); break; case "delete": gantt.confirm({ title: gantt.locale.labels.confirm_deleting_title, text: gantt.locale.labels.confirm_deleting, callback: function (res) { if (res) gantt.deleteTask(id); } }); break; case "upload": showDocuments(id); break; case "comment": showComments(id); break; } } function createColumnsConfig(selectedColumns){ var newColumns = []; allColumns.forEach(function(column){ if(selectedColumns[column.name]){ newColumns.push(column); } }); return newColumns; } var allColumns = [ { name: "action", label: colHeader, align: "left", min_width: 115, template: colContent, resize: true }, { name: "kode_sortname", label: "Kode / Sortname",align: "center", min_width: 120, editor: editor.kode_sortname, resize: true }, { name: "text", label: "Activity", tree: true, min_width: 150, editor: editor.text, resize: true }, { name: "start_date", label: "Start Date", align: "center", min_width: 80, editor: editor.start_date, resize: true }, { name: "end_date", label: "Finish Date", align: "center", min_width: 80, editor: editor.end_date, resize: true }, { name: "duration", label: "Duration (Day)", align: "center", min_width: 50, resize: true, editor: editor.duration }, { name: "rencana_biaya", label: "Cost Planning", align: "right", min_width: 100, resize: true, template: function (text) { if(!text.rencana_biaya){ return } let rencana_biaya = roundToTwo(text.rencana_biaya) return "Rp. "+ formatRupiah(rencana_biaya) } }, { name: "cost_actual", label: "Cost Actual", align: "right", min_width: 100, resize: true, template: function (text) { if(!text.biaya_actual){ return } let biaya_actual = roundToTwo(text.biaya_actual) return "Rp. "+ formatRupiah(biaya_actual) } }, { name: "assign_hr", label: "Assign To", align: "center", min_width: 150, resize: true, template: function (text) { if(text.type=="project" || text.type=="milestone" || text.type=="header"){ return; } let html = ``; var assign_hr = text.assign_hr if(!assign_hr || !assign_hr.length){ html = `Unassigned`; }else{ if(assign_hr.length==1){ html = `${assign_hr[0]}`; }else{ assign_hr.forEach(function(val, index) { html += `${val.substr(0, 1)}`; }); } } return `
${html}
` } }, { name: "material", label: "Material", align: "center", min_width: 150, resize: true, template: function (text) { if(text.type=="project" || text.type=="milestone" || text.type=="header"){ return; } let html = ``; var assign_material = text.assign_material if(!assign_material || !assign_material.length){ html = `No Material`; }else{ if(assign_material.length > 0 ){ html = `See Material`; } } return `
${html}
` } }, { name: "expenses", label: "Overhead", align: "center", min_width: 150, resize: true, template: function (text) { if(text.type=="project" || text.type=="milestone" || text.type=="header"){ return; } let html = ``; var assign_expense = text.assign_expense if(!assign_expense || !assign_expense.length){ html = `No Overhead`; }else{ if(assign_expense.length > 0 ){ html = `See Overhead`; } } return `
${html}
` } }, { name: "tools", label: "Tools", align: "center", min_width: 150, resize: true, template: function (text) { if(text.type=="project" || text.type=="milestone" || text.type=="header"){ return; } let html = ``; var assign_tools = text.assign_tools if(!assign_tools || !assign_tools.length){ // html = `Unassigned`; }else{ if(assign_tools.length > 0 ){ html = `Assigned`; } } return `
${html}
` } }, // { name: "status", label: "Status", align: "center", editor: editor.status, resize: true }, { name: "bobot_planning", label: "Bobot Activity (%)", align: "center", editor: editor.bobot_planning, resize: true, min_width: 115, template: function (text) { if(text.bobot_planning > 100){ gantt.alert("Bobot tidak boleh lebih dari 100%!"); return; } if(!text.bobot_planning){ return } let bobot_planning = parseFloat(text.bobot_planning); return roundToTwo(bobot_planning); } }, { name: "progress", label: "Actual Progress (%)", align: "center", editor: progressEditor ,min_width: 125, template: function (text) { let progress = text.progress progress = progress*100 return roundToTwo(progress); }, resize: true }, { name:"progress_actual", label: "Total Actual Progress (%)", align: "center", min_width: 150, template: function (text) { let progress = text.progress progress = progress*100 if(progress > 100){ gantt.alert("Bobot tidak boleh lebih dari 100%!"); return; } let bobot = text.bobot_planning let actual = (progress*bobot) / 100 return roundToTwo(actual); }, resize: true }, { name: "jumlah_pekerjaan", label: "Volume Plan", align: "center", min_width: 100, resize: true, editor:editor.job_count }, { name: "jobs_done", label: "Report", align: "center", min_width: 100, resize: true, template: function (text) { if(text.type=="project" || text.type=="milestone" || text.type=="header"){ return; } if(text.jobs_done == 0){ html = `No Report`; }else{ html = `See Report`; } return `
${html}
` } }, { name: "satuan", label: "UOM", align: "center", min_width: 100, resize: true, editor:editor.satuan, template: satuanLabel }, { name: "predecessor", label: "Predecessor", align: "center", min_width: 100, template: function (text) { let links = text.$target let dataRes = ``; let no = 0; if (links.length > 0) { links.map((val, index) => { if (no > 0) { dataRes += `, `; } let link = gantt.getLink(val); let type = getCodeLinkByType(link.type); let source = link.source; var wbs_code = gantt.getWBSCode(gantt.getTask(source)); dataRes += wbs_code + type; no = no + 1; }); } return dataRes; }, resize: true }, { name: "updated_by", label: "Last Updated By", align: "center", min_width: 100, resize: true } ]; // set default to show (true) , hide (false) gantt.config.columns = createColumnsConfig({ action: true, kode_sortname: true, text: true, start_date: true, end_date: true, duration: true, rencana_biaya: true, cost_actual: true, assign_hr: true, material: true, tools: true, expenses: true, bobot_planning: true, progress: true, progress_actual: true, jumlah_pekerjaan: true, jobs_done:true, satuan: true, predecessor: true, updated_by: true }) gantt.config.reorder_grid_columns = true; gantt.config.resize_rows = true; gantt.config.grid_resize = true; gantt.config.min_column_width = 50; gantt.config.scale_height = 20; gantt.config.order_branch = "marker"; gantt.config.order_branch = true; gantt.config.order_branch_free = true; gantt.config.open_tree_initially = true; gantt.config.row_height = 30; gantt.config.task_height = 20; // adding baseline display gantt.addTaskLayer({ renderer: { render: function draw_planned(task) { if (task.planned_start && task.planned_end) { var sizes = gantt.getTaskPosition(task, task.planned_start, task.planned_end); var el = document.createElement('div'); el.className = 'baseline'; el.style.left = sizes.left - 6 + 'px'; el.style.width = sizes.width + 10+ 'px'; el.style.height= sizes.height + 'px'; el.style.top = sizes.top + 2 + 'px'; return el; } return false; }, getRectangle: function(task, view){ if (task.planned_start && task.planned_end) { return gantt.getTaskPosition(task, task.planned_start, task.planned_end); } return null; } } }); gantt.templates.task_class = function (start, end, task) { if (task.planned_end) { var classes = ['has-baseline']; if (end.getTime() > task.planned_end.getTime()) { classes.push('overdue'); } return classes.join(' '); } }; gantt.templates.task_end_date = function(date){ return gantt.templates.task_date(new Date(date.valueOf() - 1)); }; gantt.templates.rightside_text = function (start, end, task) { if (task.planned_end) { if (end.getTime() > task.planned_end.getTime()) { var plannedEndDate = gantt.calculateEndDate({ start_date: task.start_date, duration: gantt.calculateDuration({ start_date: task.start_date, end_date: task.planned_end }) }); var overdue = gantt.calculateDuration({ start_date: plannedEndDate, end_date: end, task: task }, 'day'); var text = "Overdue: " + overdue + " days"; return text; } } }; gantt.attachEvent("onTaskLoading", function(task){ task.planned_start = gantt.date.parseDate(task.planned_start, "xml_date"); task.planned_end = gantt.date.parseDate(task.planned_end, "xml_date"); return true; }); gantt.config.autoscroll = true; gantt.config.scroll_size = 30; gantt.config.layout = { css: "gantt_container", cols: [ { width: 400, min_width: 300, rows: [ { view: "grid", scrollX: "gridScroll", scrollable: true, scrollY: "scrollVer" }, { view: "scrollbar", id: "gridScroll", group: "horizontal" } ] }, { resizer: true, width: 3 }, { rows: [ { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer", scrollable: true}, { view: "scrollbar", id: "scrollHor", group: "horizontal" } ] }, { view: "scrollbar", id: "scrollVer" } ] }; gantt.templates.grid_folder = function (item) { return ""; }; gantt.templates.grid_file = function (item) { return ""; }; // Set workdays gantt.config.work_time = true; gantt.config.duration_unit = "day"; gantt.templates.timeline_cell_class = function (task, date) { if (!gantt.isWorkTime(date, 'day')) { return ("holidays"); } return ""; }; // Zoom Scales var zoomConfig = { levels: [ { name:"day", scale_height: 50, min_column_width:50, scales:[ {unit: "week", step: 1, format: function (date) { var dateToStr = gantt.date.date_to_str("%d %M"); var endDate = gantt.date.add(date, -6, "day"); var weekNum = gantt.date.date_to_str("%W")(date); var year = gantt.date.date_to_str("%Y")(date); return "W#" + weekNum + ", " + dateToStr(date) + " - " + dateToStr(endDate) + " " + year; }}, {unit: "day", step: 1, format: "%d %M"} ] }, { name:"week", scale_height: 50, min_column_width:50, scales:[ // {unit: "week", step: 1, format: function (date) { // var dateToStr = gantt.date.date_to_str("%d %M"); // var endDate = gantt.date.add(date, -6, "day"); // var weekNum = gantt.date.date_to_str("%W")(date); // var year = gantt.date.date_to_str("%Y")(date); // return "#" + weekNum + ", " + dateToStr(date) + " - " + dateToStr(endDate) + " " + year; // }}, {unit: "week", step: 1, format: function (date) { var weekNum = gantt.date.date_to_str("%W")(date); return "W#" + weekNum; }}, {unit: "month", format: "%F, %Y"}, // {unit: "day", step: 1, format: "%j %D"} ] }, { name:"month", scale_height: 50, min_column_width:120, scales:[ {unit: "month", format: "%F, %Y"}, // {unit: "week", format: "Week #%W"}, // {unit: "day", step: 1, format: "%j %D"} ] }, // { // name:"quarter", // height: 50, // min_column_width:90, // scales:[ // {unit: "month", step: 1, format: "%M"}, // { // unit: "quarter", step: 1, format: function (date) { // var dateToStr = gantt.date.date_to_str("%M"); // var endDate = gantt.date.add(gantt.date.add(date, 3, "month"), -1, "day"); // return dateToStr(date) + " - " + dateToStr(endDate); // } // } // ] // }, // { // name:"year", // scale_height: 50, // min_column_width: 30, // scales:[ // {unit: "year", step: 1, format: "%Y"} // ] // } ] }; gantt.ext.zoom.init(zoomConfig); gantt.ext.zoom.setLevel("month"); // trigger when zoomIn and zoomOut clicked gantt.ext.zoom.attachEvent("onAfterZoom", function(level, config){ document.querySelector(".gantt_radio[value='" +config.name+ "']").checked = true; }) function zoomIn(){ gantt.ext.zoom.zoomIn(); } function zoomOut(){ gantt.ext.zoom.zoomOut() } var radios = document.getElementsByName("scale"); for (var i = 0; i < radios.length; i++) { radios[i].onclick = function (event) { updateProperty({zoom:event.target.value}); gantt.ext.zoom.setLevel(event.target.value); }; } // end Zoom Scale function // GANTT PERFORMANCE CONFIG RECOMMENDATION gantt.config.scales = [ {unit: "month", step: 1, format: "%F, %Y"}, {unit: "week", step: 1, format: function (date) { return "Week #" + gantt.date.getWeek(date); }}, {unit: "day", step: 1, format: "%D", css: function(date) { if(!gantt.isWorkTime({ date: date, unit: "day"})){ return "weekend" } }} ]; gantt.config.show_task_cells = false; gantt.config.static_background = true; gantt.config.branch_loading = true; gantt.config.smart_scales = true; gantt.config.smart_rendering = true; // drag process gantt.config.drag_progress = false; // gantt initialization $(document).ready(function () { initializationProject(); getSatuan(); gantt.init("gantt_here"); linkLagEditor(); setTimeout(initializationColumn, 4500); setTimeout(initialProperty, 4500); });