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.
1141 lines
45 KiB
1141 lines
45 KiB
3 years ago
|
<!DOCTYPE HTML>
|
||
|
<html>
|
||
|
|
||
|
<head>
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" />
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
|
<title>Gantt Chart</title>
|
||
|
|
||
|
|
||
|
|
||
|
<link rel=stylesheet href="./platform.css" type="text/css">
|
||
|
<link rel=stylesheet href="./libs/jquery/dateField/jquery.dateField.css" type="text/css">
|
||
|
|
||
|
<link rel=stylesheet href="./gantt.css" type="text/css">
|
||
|
<link rel=stylesheet href="./ganttPrint.css" type="text/css" media="print">
|
||
|
<link rel=stylesheet href="./libs/jquery/valueSlider/mb.slider.css" type="text/css" media="print">
|
||
|
<link rel=stylesheet href="./libs/orgchart.min.css" type="text/css">
|
||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.24.0/axios.min.js"
|
||
|
integrity="sha512-u9akINsQsAkG9xjc1cnGF4zw5TFDwkxuc9vUp5dltDWYCSmyd0meygbvgXrlc/z7/o4a19Fb5V0OUE58J7dcyw=="
|
||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||
|
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"
|
||
|
integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ=="
|
||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||
|
<script src="./libs/jquery/jquery.livequery.1.1.1.min.js"></script>
|
||
|
<script src="./libs/jquery/jquery.timers.js"></script>
|
||
|
|
||
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
|
||
|
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
|
||
|
crossorigin="" />
|
||
|
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
|
||
|
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
|
||
|
crossorigin=""></script>
|
||
|
|
||
|
<script src="./libs/utilities.js"></script>
|
||
|
<script src="./libs/forms.js"></script>
|
||
|
<script src="./libs/date.js"></script>
|
||
|
<script src="./libs/dialogs.js"></script>
|
||
|
<script src="./libs/layout.js"></script>
|
||
|
<script src="./libs/i18nJs.js"></script>
|
||
|
<script src="./libs/jquery/dateField/jquery.dateField.js"></script>
|
||
|
<script src="./libs/jquery/JST/jquery.JST.js"></script>
|
||
|
<script src="./libs/jquery/valueSlider/jquery.mb.slider.js"></script>
|
||
|
<script src="./libs/orgchart.min.js"></script>
|
||
|
|
||
|
|
||
|
|
||
|
<script type="text/javascript" src="./libs/jquery/svg/jquery.svg.min.js"></script>
|
||
|
<script type="text/javascript" src="./libs/jquery/svg/jquery.svgdom.1.8.js"></script>
|
||
|
|
||
|
|
||
|
<script src="./ganttUtilities.js"></script>
|
||
|
<script src="./ganttTask.js"></script>
|
||
|
<script src="./ganttDrawerSVG.js"></script>
|
||
|
<script src="./ganttZoom.js"></script>
|
||
|
<script src="./ganttGridEditor.js"></script>
|
||
|
<script src="./ganttMaster.js"></script>
|
||
|
|
||
|
|
||
|
<!--<script src="libs/profiling.js"></script>-->
|
||
|
<!--<script type="text/javascript" src="ganttTestSuite.js"></script>-->
|
||
|
|
||
|
<!-- <script type="text/javascript">
|
||
|
|
||
|
</script> -->
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body style="background-color: #fff;">
|
||
|
|
||
|
|
||
|
|
||
|
<div id="workSpace"
|
||
|
style="padding:0px; overflow-y:auto; overflow-x:hidden;border:1px solid #e5e5e5;position:relative;margin:0 5px">
|
||
|
</div>
|
||
|
|
||
|
<style>
|
||
|
#mapgantt {
|
||
|
height: 200px;
|
||
|
}
|
||
|
|
||
|
.resEdit {
|
||
|
padding: 15px;
|
||
|
}
|
||
|
|
||
|
.resLine {
|
||
|
width: 95%;
|
||
|
padding: 3px;
|
||
|
margin: 5px;
|
||
|
border: 1px solid #d0d0d0;
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
|
||
|
.ganttButtonBar h1 {
|
||
|
color: #000000;
|
||
|
font-weight: bold;
|
||
|
font-size: 28px;
|
||
|
margin-left: 10px;
|
||
|
}
|
||
|
|
||
|
.separator {
|
||
|
margin-top: 10px;
|
||
|
margin-bottom: 10px;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<form id="gimmeBack" style="display:none;" action="../gimmeBack.jsp" method="post" target="_blank"><input
|
||
|
type="hidden" name="prj" id="gimBaPrj"></form>
|
||
|
|
||
|
<script type="text/javascript">
|
||
|
var token = getUrlParameter('token');
|
||
|
var proyek_id = getUrlParameter('proyek_id');
|
||
|
var baseUrl = "https://oslog.id/simpro-api/v1/";
|
||
|
var baseUrlPHP = "http://siopas.co.id/custom-php/api/ospro/"
|
||
|
$.ajaxSetup({
|
||
|
headers: {
|
||
|
'Authorization': `Bearer ${token}`,
|
||
|
"Content-type": `application/json`
|
||
|
}
|
||
|
});
|
||
|
var ge;
|
||
|
$(function () {
|
||
|
var canWrite = true; //this is the default for test purposes
|
||
|
|
||
|
// here starts gantt initialization
|
||
|
ge = new GanttMaster();
|
||
|
ge.set100OnClose = true;
|
||
|
|
||
|
ge.shrinkParent = true;
|
||
|
|
||
|
ge.init($("#workSpace"));
|
||
|
loadI18n(); //overwrite with localized ones
|
||
|
|
||
|
//in order to force compute the best-fitting zoom level
|
||
|
delete ge.gantt.zoom;
|
||
|
$.when(loadFromLocalStorage()).done(res => {
|
||
|
console.log("res from project", res)
|
||
|
var project = res;
|
||
|
console.log("project", project)
|
||
|
|
||
|
if (!project.canWrite)
|
||
|
$(".ganttButtonBar button.requireWrite").attr("disabled", "true");
|
||
|
// if (datagantt.lengt > 0) project.tasks = datagantt
|
||
|
ge.loadProject(project);
|
||
|
ge.checkpoint(); //empty the undo stack
|
||
|
|
||
|
initializeHistoryManagement(ge.tasks[0].id);
|
||
|
});
|
||
|
// var project = loadFromLocalStorage();
|
||
|
// console.log("project", project)
|
||
|
|
||
|
// if (!project.canWrite)
|
||
|
// $(".ganttButtonBar button.requireWrite").attr("disabled", "true");
|
||
|
// // if (datagantt.lengt > 0) project.tasks = datagantt
|
||
|
// ge.loadProject(project);
|
||
|
// ge.checkpoint(); //empty the undo stack
|
||
|
|
||
|
// initializeHistoryManagement(ge.tasks[0].id);
|
||
|
});
|
||
|
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
|
||
|
function getDataProject() {
|
||
|
return $.ajax({
|
||
|
url: `${baseUrl}gantt-subproyek/${proyek_id}`,
|
||
|
// url: `${baseUrlPHP}gantt.php?act=get_data&proyek_id=${proyek_id}`,
|
||
|
method: 'GET',
|
||
|
dataType: 'json',
|
||
|
crossDomain: true,
|
||
|
});
|
||
|
|
||
|
}
|
||
|
|
||
|
async function getDemoProject() {
|
||
|
//console.debug("getDemoProject")
|
||
|
// let data = getDataProject();
|
||
|
var result = await $.when(getDataProject()).done(res => res);
|
||
|
|
||
|
const {
|
||
|
tasks,
|
||
|
resources,
|
||
|
roles
|
||
|
} = result.data
|
||
|
// var data = datagantt
|
||
|
// console.log('data gantt async', JSON.stringify(data))
|
||
|
|
||
|
ret = {
|
||
|
"tasks": tasks,
|
||
|
"selectedRow": 0,
|
||
|
"deletedTaskIds": [],
|
||
|
"resources": resources,
|
||
|
"roles": roles,
|
||
|
"canWrite": true,
|
||
|
"canDelete": true,
|
||
|
"canWriteOnParent": true,
|
||
|
"canAdd": true
|
||
|
}
|
||
|
|
||
|
|
||
|
//actualize data
|
||
|
var offset = new Date().getTime() - ret.tasks[0].start;
|
||
|
for (var i = 0; i < ret.tasks.length; i++) {
|
||
|
ret.tasks[i].start = ret.tasks[i].start + offset;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
function loadGanttFromServer(taskId, callback) {
|
||
|
|
||
|
//this is a simulation: load data from the local storage if you have already played with the demo or a textarea with starting demo data
|
||
|
var ret = loadFromLocalStorage();
|
||
|
|
||
|
//this is the real implementation
|
||
|
/*
|
||
|
//var taskId = $("#taskSelector").val();
|
||
|
var prof = new Profiler("loadServerSide");
|
||
|
prof.reset();
|
||
|
|
||
|
$.getJSON("ganttAjaxController.jsp", {CM:"LOADPROJECT",taskId:taskId}, function(response) {
|
||
|
//console.debug(response);
|
||
|
if (response.ok) {
|
||
|
prof.stop();
|
||
|
|
||
|
ge.loadProject(response.project);
|
||
|
ge.checkpoint(); //empty the undo stack
|
||
|
|
||
|
if (typeof(callback)=="function") {
|
||
|
callback(response);
|
||
|
}
|
||
|
} else {
|
||
|
jsonErrorHandling(response);
|
||
|
}
|
||
|
});
|
||
|
*/
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
function upload(uploadedFile) {
|
||
|
var fileread = new FileReader();
|
||
|
|
||
|
fileread.onload = function (e) {
|
||
|
var content = e.target.result;
|
||
|
var intern = JSON.parse(content); // Array of Objects.
|
||
|
//console.log(intern); // You can index every object
|
||
|
|
||
|
ge.loadProject(intern);
|
||
|
ge.checkpoint(); //empty the undo stack
|
||
|
|
||
|
};
|
||
|
|
||
|
fileread.readAsText(uploadedFile);
|
||
|
}
|
||
|
|
||
|
function saveAllDataGantt() {
|
||
|
const prjl = ge.saveProject();
|
||
|
console.log("payload", prjl)
|
||
|
var payload = new FormData();
|
||
|
payload.append('proyek_id', proyek_id)
|
||
|
payload.append('gantt_data', JSON.stringify(prjl))
|
||
|
const url = `${baseUrlPHP}gantt.php?act=input`
|
||
|
// const url = `${baseUrlPHP}gantt.php?act=input2`
|
||
|
axios.post(url, payload).then(res => {
|
||
|
console.log(res)
|
||
|
alert("Update Gantt berhasil")
|
||
|
}).catch(err => console.log(err.response))
|
||
|
// $.ajax({
|
||
|
// url: `http://siopas.co.id/custom-php/api/ospro/gantt.php?act=input`,
|
||
|
// method: 'POST',
|
||
|
// dataType: 'json',
|
||
|
// data: payload,
|
||
|
// processData: false,
|
||
|
// contentType: false,
|
||
|
// headers: {
|
||
|
// "Content-type": `multipart/form-data`
|
||
|
// },
|
||
|
// success: function (data) {
|
||
|
// console.log(data)
|
||
|
// }
|
||
|
// })
|
||
|
}
|
||
|
|
||
|
function saveGanttOnServer() {
|
||
|
|
||
|
//this is a simulation: save data to the local storage or to the textarea
|
||
|
//saveInLocalStorage();
|
||
|
|
||
|
console.log("all data", ge)
|
||
|
var prj = ge.saveProject();
|
||
|
console.log(prj)
|
||
|
const dataAssigs = prj.tasks.filter(res => res.assigs.length > 0)
|
||
|
const deletedTaskId = prj.deletedTaskIds
|
||
|
const newData = prj.tasks.filter(res => res.id.includes("tmp"))
|
||
|
console.log({
|
||
|
newData,
|
||
|
deletedTaskId,
|
||
|
dataAssigs
|
||
|
})
|
||
|
saveAllDataGantt()
|
||
|
|
||
|
// download(JSON.stringify(prj, null, '\t'), "MyProject.json", "application/json");
|
||
|
|
||
|
/*
|
||
|
|
||
|
delete prj.resources;
|
||
|
delete prj.roles;
|
||
|
|
||
|
var prof = new Profiler("saveServerSide");
|
||
|
prof.reset();
|
||
|
|
||
|
if (ge.deletedTaskIds.length>0) {
|
||
|
if (!confirm("TASK_THAT_WILL_BE_REMOVED\n"+ge.deletedTaskIds.length)) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$.ajax("ganttAjaxController.jsp", {
|
||
|
dataType:"json",
|
||
|
data: {CM:"SVPROJECT",prj:JSON.stringify(prj)},
|
||
|
type:"POST",
|
||
|
|
||
|
success: function(response) {
|
||
|
if (response.ok) {
|
||
|
prof.stop();
|
||
|
if (response.project) {
|
||
|
ge.loadProject(response.project); //must reload as "tmp_" ids are now the good ones
|
||
|
} else {
|
||
|
ge.reset();
|
||
|
}
|
||
|
} else {
|
||
|
var errMsg="Errors saving project\n";
|
||
|
if (response.message) {
|
||
|
errMsg=errMsg+response.message+"\n";
|
||
|
}
|
||
|
|
||
|
if (response.errorMessages.length) {
|
||
|
errMsg += response.errorMessages.join("\n");
|
||
|
}
|
||
|
|
||
|
alert(errMsg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
// Function to download data to a file
|
||
|
function download(data, filename, type) {
|
||
|
var file = new Blob([data], {
|
||
|
type: type
|
||
|
});
|
||
|
if (window.navigator.msSaveOrOpenBlob) // IE10+
|
||
|
window.navigator.msSaveOrOpenBlob(file, filename);
|
||
|
else { // Others
|
||
|
var a = document.createElement("a"),
|
||
|
url = URL.createObjectURL(file);
|
||
|
a.href = url;
|
||
|
a.download = filename;
|
||
|
document.body.appendChild(a);
|
||
|
a.click();
|
||
|
setTimeout(function () {
|
||
|
document.body.removeChild(a);
|
||
|
window.URL.revokeObjectURL(url);
|
||
|
}, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function newProject() {
|
||
|
clearGantt();
|
||
|
}
|
||
|
|
||
|
|
||
|
function clearGantt() {
|
||
|
ge.reset();
|
||
|
}
|
||
|
|
||
|
//------------------------------------------- Get project file as JSON (used for migrate project from gantt to Teamwork) ------------------------------------------------------
|
||
|
function getFile() {
|
||
|
$("#gimBaPrj").val(JSON.stringify(ge.saveProject()));
|
||
|
$("#gimmeBack").submit();
|
||
|
$("#gimBaPrj").val("");
|
||
|
|
||
|
/* var uriContent = "data:text/html;charset=utf-8," + encodeURIComponent(JSON.stringify(prj));
|
||
|
neww=window.open(uriContent,"dl");*/
|
||
|
}
|
||
|
|
||
|
|
||
|
function loadFromLocalStorage() {
|
||
|
var ret;
|
||
|
if (localStorage) {
|
||
|
if (localStorage.getObject("teamworkGantDemo")) {
|
||
|
ret = localStorage.getObject("teamworkGantDemo");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//if not found create a new example task
|
||
|
if (!ret || !ret.tasks || ret.tasks.length == 0) {
|
||
|
ret = getDemoProject();
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
function saveInLocalStorage() {
|
||
|
var prj = ge.saveProject();
|
||
|
|
||
|
if (localStorage) {
|
||
|
localStorage.setObject("teamworkGantDemo", prj);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------- Open a black popup for managing resources. This is only an axample of implementation (usually resources come from server) ------------------------------------------------------
|
||
|
function editResources() {
|
||
|
|
||
|
//make resource editor
|
||
|
var resourceEditor = $.JST.createFromTemplate({}, "RESOURCE_EDITOR");
|
||
|
var resTbl = resourceEditor.find("#resourcesTable");
|
||
|
|
||
|
for (var i = 0; i < ge.resources.length; i++) {
|
||
|
var res = ge.resources[i];
|
||
|
resTbl.append($.JST.createFromTemplate(res, "RESOURCE_ROW"))
|
||
|
}
|
||
|
|
||
|
|
||
|
//bind add resource
|
||
|
resourceEditor.find("#addResource").click(function () {
|
||
|
resTbl.append($.JST.createFromTemplate({
|
||
|
id: "new",
|
||
|
name: "resource"
|
||
|
}, "RESOURCE_ROW"))
|
||
|
});
|
||
|
|
||
|
//bind save event
|
||
|
resourceEditor.find("#resSaveButton").click(function () {
|
||
|
var newRes = [];
|
||
|
//find for deleted res
|
||
|
for (var i = 0; i < ge.resources.length; i++) {
|
||
|
var res = ge.resources[i];
|
||
|
var row = resourceEditor.find("[resId=" + res.id + "]");
|
||
|
if (row.length > 0) {
|
||
|
//if still there save it
|
||
|
var name = row.find("input[name]").val();
|
||
|
if (name && name != "")
|
||
|
res.name = name;
|
||
|
newRes.push(res);
|
||
|
} else {
|
||
|
//remove assignments
|
||
|
for (var j = 0; j < ge.tasks.length; j++) {
|
||
|
var task = ge.tasks[j];
|
||
|
var newAss = [];
|
||
|
for (var k = 0; k < task.assigs.length; k++) {
|
||
|
var ass = task.assigs[k];
|
||
|
if (ass.resourceId != res.id)
|
||
|
newAss.push(ass);
|
||
|
}
|
||
|
task.assigs = newAss;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//loop on new rows
|
||
|
var cnt = 0
|
||
|
resourceEditor.find("[resId=new]").each(function () {
|
||
|
cnt++;
|
||
|
var row = $(this);
|
||
|
var name = row.find("input[name]").val();
|
||
|
if (name && name != "")
|
||
|
newRes.push(new Resource("tmp_" + new Date().getTime() + "_" + cnt, name));
|
||
|
});
|
||
|
|
||
|
ge.resources = newRes;
|
||
|
|
||
|
closeBlackPopup();
|
||
|
ge.redraw();
|
||
|
});
|
||
|
|
||
|
|
||
|
var ndo = createModalPopup(400, 500).append(resourceEditor);
|
||
|
}
|
||
|
|
||
|
function getDataNetworkDiagram(taskId) {
|
||
|
return $.ajax({
|
||
|
url: `${baseUrl}diagram-network/${taskId}`,
|
||
|
method: 'GET',
|
||
|
dataType: 'json',
|
||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||
|
// console.log('error getDataNetworkDiagram', jqXHR);
|
||
|
alert('Error show network diagram: ' + jqXHR.responseJSON.message);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
}
|
||
|
|
||
|
//------------------------------------------- Open a black popup for managing resources. This is only an axample of implementation (usually resources come from server) ------------------------------------------------------
|
||
|
async function showNetworkDiagram() {
|
||
|
if (!proyek_id) {
|
||
|
alert('Please define proyek_id in the URL');
|
||
|
return;
|
||
|
}
|
||
|
let getData = await getDataNetworkDiagram(proyek_id);
|
||
|
|
||
|
console.log('getData', getData);
|
||
|
|
||
|
|
||
|
var resourceEditor = $.JST.createFromTemplate({}, "NETWORK_DIAGRAM");
|
||
|
var resTbl = resourceEditor.find("#networkDiagramContainer");
|
||
|
|
||
|
resTbl.orgchart({
|
||
|
'data': getData.data,
|
||
|
'nodeContent': 'range_date',
|
||
|
'direction': 'l2r',
|
||
|
'parentNodeSymbol':'',
|
||
|
'createNode': function(node, data) {
|
||
|
console.log('data', node.parentNode);
|
||
|
let html = `Duration ${data.duration} Days<br>Start ${moment(data.start_date).format("DD-MM-YYYY")}<br>Finish ${moment(data.start_date).format("DD-MM-YYYY")}`;
|
||
|
node[0].children[1].innerHTML = html
|
||
|
// node.firstChild.html("CEK CEK CEK 1 2 3");
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var ndo = createModalPopup('90%', 500).append(resourceEditor);
|
||
|
}
|
||
|
|
||
|
// async function showMap() {
|
||
|
|
||
|
// var resourceEditor = $.JST.createFromTemplate({}, "OPEN_MAP");
|
||
|
// var resTbl = resourceEditor.find("#mapGantt");
|
||
|
|
||
|
// // resTbl.orgchart({
|
||
|
// // 'data': getData.data,
|
||
|
// // 'nodeContent': 'title',
|
||
|
// // 'direction': 'l2r'
|
||
|
// // });
|
||
|
|
||
|
// var ndo = createModalPopup('90%', 500).append(resourceEditor);
|
||
|
// }
|
||
|
|
||
|
function initializeHistoryManagement(taskId) {
|
||
|
|
||
|
//retrieve from server the list of history points in millisecond that represent the instant when the data has been recorded
|
||
|
//response: {ok:true, historyPoints: [1498168800000, 1498600800000, 1498687200000, 1501538400000, …]}
|
||
|
$.getJSON(contextPath + "/applications/teamwork/task/taskAjaxController.jsp", {
|
||
|
CM: "GETGANTTHISTPOINTS",
|
||
|
OBJID: taskId
|
||
|
}, function (response) {
|
||
|
|
||
|
//if there are history points
|
||
|
if (response.ok == true && response.historyPoints && response.historyPoints.length > 0) {
|
||
|
|
||
|
//add show slider button on button bar
|
||
|
var histBtn = $("<button>").addClass("button textual icon lreq30 lreqLabel").attr("title", "SHOW_HISTORY")
|
||
|
.append("<span class=\"teamworkIcon\">`</span>");
|
||
|
|
||
|
//clicking it
|
||
|
histBtn.click(function () {
|
||
|
var el = $(this);
|
||
|
var ganttButtons = $(".ganttButtonBar .buttons");
|
||
|
|
||
|
//is it already on?
|
||
|
if (!ge.element.is(".historyOn")) {
|
||
|
ge.element.addClass("historyOn");
|
||
|
ganttButtons.find(".requireCanWrite").hide();
|
||
|
|
||
|
//load the history points from server again
|
||
|
showSavingMessage();
|
||
|
$.getJSON(contextPath + "/applications/teamwork/task/taskAjaxController.jsp", {
|
||
|
CM: "GETGANTTHISTPOINTS",
|
||
|
OBJID: ge.tasks[0].id
|
||
|
}, function (response) {
|
||
|
jsonResponseHandling(response);
|
||
|
hideSavingMessage();
|
||
|
if (response.ok == true) {
|
||
|
var dh = response.historyPoints;
|
||
|
if (dh && dh.length > 0) {
|
||
|
//si crea il div per lo slider
|
||
|
var sliderDiv = $("<div>").prop("id", "slider").addClass("lreq30 lreqHide").css({
|
||
|
"display": "inline-block",
|
||
|
"width": "500px"
|
||
|
});
|
||
|
ganttButtons.append(sliderDiv);
|
||
|
|
||
|
var minVal = 0;
|
||
|
var maxVal = dh.length - 1;
|
||
|
|
||
|
$("#slider").show().mbSlider({
|
||
|
rangeColor: '#2f97c6',
|
||
|
minVal: minVal,
|
||
|
maxVal: maxVal,
|
||
|
startAt: maxVal,
|
||
|
showVal: false,
|
||
|
grid: 1,
|
||
|
formatValue: function (val) {
|
||
|
return new Date(dh[val]).format();
|
||
|
},
|
||
|
onSlideLoad: function (obj) {
|
||
|
this.onStop(obj);
|
||
|
|
||
|
},
|
||
|
onStart: function (obj) {},
|
||
|
onStop: function (obj) {
|
||
|
var val = $(obj).mbgetVal();
|
||
|
showSavingMessage();
|
||
|
/**
|
||
|
* load the data history for that milliseconf from server
|
||
|
* response in this format {ok: true, baselines: {...}}
|
||
|
*
|
||
|
* baselines: {61707: {duration:1,endDate:1550271599998,id:61707,progress:40,startDate:1550185200000,status:"STATUS_WAITING",taskId:"3055"},
|
||
|
* {taskId:{duration:in days,endDate:in millis,id:history record id,progress:in percent,startDate:in millis,status:task status,taskId:"3055"}....}} */
|
||
|
|
||
|
$.getJSON(contextPath +
|
||
|
"/applications/teamwork/task/taskAjaxController.jsp", {
|
||
|
CM: "GETGANTTHISTORYAT",
|
||
|
OBJID: ge.tasks[0].id,
|
||
|
millis: dh[val]
|
||
|
},
|
||
|
function (response) {
|
||
|
jsonResponseHandling(response);
|
||
|
hideSavingMessage();
|
||
|
if (response.ok) {
|
||
|
ge.baselines = response.baselines;
|
||
|
ge.showBaselines = true;
|
||
|
ge.baselineMillis = dh[val];
|
||
|
ge.redraw();
|
||
|
}
|
||
|
})
|
||
|
|
||
|
},
|
||
|
onSlide: function (obj) {
|
||
|
clearTimeout(obj.renderHistory);
|
||
|
var self = this;
|
||
|
obj.renderHistory = setTimeout(function () {
|
||
|
self.onStop(obj);
|
||
|
}, 200)
|
||
|
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
// closing the history
|
||
|
} else {
|
||
|
//remove the slider
|
||
|
$("#slider").remove();
|
||
|
ge.element.removeClass("historyOn");
|
||
|
if (ge.permissions.canWrite)
|
||
|
ganttButtons.find(".requireCanWrite").show();
|
||
|
|
||
|
ge.showBaselines = false;
|
||
|
ge.baselineMillis = undefined;
|
||
|
ge.redraw();
|
||
|
}
|
||
|
|
||
|
});
|
||
|
$("#saveGanttButton").before(histBtn);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function showBaselineInfo(event, element) {
|
||
|
//alert(element.attr("data-label"));
|
||
|
$(element).showBalloon(event, $(element).attr("data-label"));
|
||
|
ge.splitter.secondBox.one("scroll", function () {
|
||
|
$(element).hideBalloon();
|
||
|
})
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<div id="gantEditorTemplates" style="display:none;">
|
||
|
<div class="__template__" type="GANTBUTTONS">
|
||
|
<!--
|
||
|
<div class="ganttButtonBar noprint">
|
||
|
<div class="buttons">
|
||
|
<button onclick="$('#workSpace').trigger('undo.gantt');return false;" class="button textual icon requireCanWrite" title="undo"><span class="teamworkIcon">'</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('redo.gantt');return false;" class="button textual icon requireCanWrite" title="redo"><span class="teamworkIcon">·</span></button>
|
||
|
<span class="ganttButtonSeparator requireCanWrite requireCanAdd"></span>
|
||
|
<button onclick="$('#workSpace').trigger('addAboveCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanAdd" title="insert above"><span class="teamworkIcon">l</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('addBelowCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanAdd" title="insert below"><span class="teamworkIcon">X</span></button>
|
||
|
<span class="ganttButtonSeparator requireCanWrite requireCanInOutdent"></span>
|
||
|
<button onclick="$('#workSpace').trigger('outdentCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanInOutdent" title="un-indent task"><span class="teamworkIcon">.</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('indentCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanInOutdent" title="indent task"><span class="teamworkIcon">:</span></button>
|
||
|
<span class="ganttButtonSeparator requireCanWrite requireCanMoveUpDown"></span>
|
||
|
<button onclick="$('#workSpace').trigger('moveUpCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanMoveUpDown" title="move up"><span class="teamworkIcon">k</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('moveDownCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanMoveUpDown" title="move down"><span class="teamworkIcon">j</span></button>
|
||
|
<span class="ganttButtonSeparator requireCanWrite requireCanDelete"></span>
|
||
|
<button onclick="$('#workSpace').trigger('deleteFocused.gantt');return false;" class="button textual icon delete requireCanWrite" title="Elimina"><span class="teamworkIcon">¢</span></button>
|
||
|
<span class="ganttButtonSeparator"></span>
|
||
|
<button onclick="$('#workSpace').trigger('expandAll.gantt');return false;" class="button textual icon " title="EXPAND_ALL"><span class="teamworkIcon">6</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('collapseAll.gantt'); return false;" class="button textual icon " title="COLLAPSE_ALL"><span class="teamworkIcon">5</span></button>
|
||
|
|
||
|
<span class="ganttButtonSeparator"></span>
|
||
|
<button onclick="$('#workSpace').trigger('zoomMinus.gantt'); return false;" class="button textual icon " title="zoom out"><span class="teamworkIcon">)</span></button>
|
||
|
<button onclick="$('#workSpace').trigger('zoomPlus.gantt');return false;" class="button textual icon " title="zoom in"><span class="teamworkIcon">(</span></button>
|
||
|
<span class="ganttButtonSeparator"></span>
|
||
|
<button onclick="$('#workSpace').trigger('print.gantt');return false;" class="button textual icon " title="Print"><span class="teamworkIcon">p</span></button>
|
||
|
<span class="ganttButtonSeparator"></span>
|
||
|
<button onclick="ge.gantt.showCriticalPath=!ge.gantt.showCriticalPath; ge.redraw();return false;" class="button textual icon requireCanSeeCriticalPath" title="CRITICAL_PATH"><span class="teamworkIcon">£</span></button>
|
||
|
<span class="ganttButtonSeparator requireCanSeeCriticalPath"></span>
|
||
|
<button onclick="ge.splitter.resize(.1);return false;" class="button textual icon" ><span class="teamworkIcon">F</span></button>
|
||
|
<button onclick="ge.splitter.resize(50);return false;" class="button textual icon" ><span class="teamworkIcon">O</span></button>
|
||
|
<button onclick="ge.splitter.resize(100);return false;" class="button textual icon"><span class="teamworkIcon">R</span></button>
|
||
|
<span class="ganttButtonSeparator"></span>
|
||
|
<button onclick="$('#workSpace').trigger('fullScreen.gantt');return false;" class="button textual icon" title="FULLSCREEN" id="fullscrbtn"><span class="teamworkIcon">@</span></button>
|
||
|
<button onclick="ge.element.toggleClass('colorByStatus' );return false;" class="button textual icon"><span class="teamworkIcon">§</span></button>
|
||
|
|
||
|
<button onclick="editResources();" class="button textual requireWrite" title="Edit Resources"><span class="teamworkIcon">M</span></button>
|
||
|
<button onclick="showNetworkDiagram();" class="button textual requireWrite" title="Show Network Diagram"><span class="teamworkIcon">|</span></button>
|
||
|
|
||
|
<button onclick="saveGanttOnServer();" class="button first big requireWrite" title="Save">Save</button>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="TASKSEDITHEAD">
|
||
|
<!-- <table class="gdfTable" cellspacing="0" cellpadding="0">
|
||
|
<thead>
|
||
|
<tr style="height:40px">
|
||
|
<th class="gdfColHeader" style="width:35px;"></th>
|
||
|
<th class="gdfColHeader" style="width:25px;"></th>
|
||
|
<th class="gdfColHeader gdfResizable" style="width:300px;">Activity</th>
|
||
|
<th class="gdfColHeader" style="width:17px;" title="Start date is a milestone."><span class="teamworkIcon" style="font-size: 8px;">^</span></th>
|
||
|
<th class="gdfColHeader gdfResizable" style="width:80px;">Start</th>
|
||
|
<th class="gdfColHeader" style="width:17px;" title="End date is a milestone."><span class="teamworkIcon" style="font-size: 8px;">^</span></th>
|
||
|
<th class="gdfColHeader gdfResizable" style="width:80px;">End</th>
|
||
|
<th class="gdfColHeader" style="width:50px;">Biaya</th>
|
||
|
<th class="gdfColHeader" style="width:50px;">Dur.</th>
|
||
|
<th class="gdfColHeader" style="width:20px;">%</th>
|
||
|
<th class="gdfColHeader requireCanSeeDep" style="width:50px;">Depe.</th>
|
||
|
<th class="gdfColHeader" style="width:100px; text-align: center; padding-left: 10px;">Assignees</th>
|
||
|
<th class="gdfColHeader" style="width:100px; text-align: center; padding-left: 10px;">Material</th>
|
||
|
<th class="gdfColHeader" style="width:100px; text-align: center; padding-left: 10px;">Tools</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
</table> -->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="TASKROW">
|
||
|
<!--
|
||
|
<tr id="tid_(#=obj.id#)" taskId="(#=obj.id#)" class="taskEditRow (#=obj.isParent()?'isParent':''#) (#=obj.collapsed?'collapsed':''#)" level="(#=level#)">
|
||
|
<th class="gdfCell edit" align="right" style="cursor:pointer;"><span class="taskRowIndex">(#=obj.getRow()+1#)</span> <span class="teamworkIcon edit-icon" style="font-size:12px;" title="Edit" >e</span> </th>
|
||
|
<td class="gdfCell noClip" align="center"><div class="taskStatus cvcColorSquare" status="(#=obj.status#)"></div></td>
|
||
|
<td class="gdfCell indentCell" style="padding-left:(#=obj.level*10+18#)px;">
|
||
|
<div class="exp-controller" align="center"></div>
|
||
|
<input type="text" name="name" value="(#=obj.name#)" placeholder="name">
|
||
|
</td>
|
||
|
<td class="gdfCell" align="center"><input type="checkbox" name="startIsMilestone"></td>
|
||
|
<td class="gdfCell"><input type="text" name="start" value="" class="date"></td>
|
||
|
<td class="gdfCell" align="center"><input type="checkbox" name="endIsMilestone"></td>
|
||
|
<td class="gdfCell"><input type="text" name="end" value="" class="date"></td>
|
||
|
<td class="gdfCell"><input type="text" name="cost" autocomplete="off" value="(#=obj.cost#)"></td>
|
||
|
<td class="gdfCell"><input type="text" name="duration" autocomplete="off" value="(#=obj.duration#)"></td>
|
||
|
<td class="gdfCell"><input type="text" name="progress" class="validated" entrytype="PERCENTILE" autocomplete="off" value="(#=obj.progress?obj.progress:''#)" (#=obj.progressByWorklog?"readOnly":""#)></td>
|
||
|
<td class="gdfCell requireCanSeeDep"><input type="text" name="depends" autocomplete="off" value="(#=obj.depends#)" (#=obj.hasExternalDep?"readonly":""#)></td>
|
||
|
<td class="gdfCell taskAssigs">(#=obj.getAssigsString()#)</td>
|
||
|
<td class="gdfCell materialAssigs">(#=obj.getMaterialString()#)</td>
|
||
|
<td class="gdfCell toolsAssigs">(#=obj.getToolsString()#)</td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="TASKEMPTYROW">
|
||
|
<!--
|
||
|
<tr class="taskEditRow emptyRow" >
|
||
|
<th class="gdfCell" align="right"></th>
|
||
|
<td class="gdfCell noClip" align="center"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell requireCanSeeDep"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
<td class="gdfCell"></td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="TASKBAR">
|
||
|
<!--
|
||
|
<div class="taskBox taskBoxDiv" taskId="(#=obj.id#)" >
|
||
|
<div class="layout (#=obj.hasExternalDep?'extDep':''#)">
|
||
|
<div class="taskStatus" status="(#=obj.status#)"></div>
|
||
|
<div class="taskProgress" style="width:(#=obj.progress>100?100:obj.progress#)%; background-color:(#=obj.progress>100?'red':'rgb(153,255,51);'#);"></div>
|
||
|
<div class="milestone (#=obj.startIsMilestone?'active':''#)" ></div>
|
||
|
|
||
|
<div class="taskLabel"></div>
|
||
|
<div class="milestone end (#=obj.endIsMilestone?'active':''#)" ></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<div class="__template__" type="CHANGE_STATUS">
|
||
|
<!--
|
||
|
<div class="taskStatusBox">
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_ACTIVE" title="Active"></div>
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_DONE" title="Completed"></div>
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_FAILED" title="Failed"></div>
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_SUSPENDED" title="Suspended"></div>
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_WAITING" title="Waiting" style="display: none;"></div>
|
||
|
<div class="taskStatus cvcColorSquare" status="STATUS_UNDEFINED" title="Undefined"></div>
|
||
|
</div>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<div class="__template__" type="TASK_EDITOR">
|
||
|
|
||
|
<div class="ganttTaskEditor">
|
||
|
<h2 class="taskData">Activity editor</h2>
|
||
|
<table cellspacing="1" cellpadding="5" width="100%" class="taskData table" border="0">
|
||
|
<tr>
|
||
|
|
||
|
<td colspan="3" valign="top"><label for="name" class="required">name</label><br><input type="text"
|
||
|
name="name" id="name" class="formElements" autocomplete='off' maxlength=255 style='width:100%' value=""
|
||
|
required="true" oldvalue="1"></td>
|
||
|
</tr>
|
||
|
|
||
|
|
||
|
<tr class="dateRow">
|
||
|
<td nowrap="">
|
||
|
<div style="position:relative">
|
||
|
<label for="start">start</label>
|
||
|
<input type="checkbox" id="startIsMilestone" name="startIsMilestone" value="yes"> <label
|
||
|
for="startIsMilestone">is milestone</label>
|
||
|
<br><input type="text" name="start" id="start" size="8" class="formElements dateField validated date"
|
||
|
autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="DATE">
|
||
|
<span title="calendar" id="starts_inputDate" class="teamworkIcon openCalendar"
|
||
|
onclick="$(this).dateField({inputField:$(this).prevAll(':input:first'),isSearchField:false});">m</span>
|
||
|
</div>
|
||
|
</td>
|
||
|
<td nowrap="">
|
||
|
<label for="end">End</label>
|
||
|
<input type="checkbox" id="endIsMilestone" name="endIsMilestone" value="yes"> <label
|
||
|
for="endIsMilestone">is milestone</label>
|
||
|
<br><input type="text" name="end" id="end" size="8" class="formElements dateField validated date"
|
||
|
autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="DATE">
|
||
|
<span title="calendar" id="ends_inputDate" class="teamworkIcon openCalendar"
|
||
|
onclick="$(this).dateField({inputField:$(this).prevAll(':input:first'),isSearchField:false});">m</span>
|
||
|
</td>
|
||
|
<td nowrap="">
|
||
|
<label for="duration" class=" ">Days</label><br>
|
||
|
<input type="text" name="duration" id="duration" size="4" class="formElements validated durationdays"
|
||
|
title="Duration is in working days." autocomplete="off" maxlength="255" value="" oldvalue="1"
|
||
|
entrytype="DURATIONDAYS">
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
|
||
|
<td valign="top" nowrap>
|
||
|
<label>progress</label><br>
|
||
|
<input type="text" name="progress" id="progress" size="7" class="formElements validated percentile"
|
||
|
autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="PERCENTILE">
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td colspan="4">
|
||
|
<label for="description">Description</label><br>
|
||
|
<textarea rows="3" cols="30" id="description" name="description" class="formElements"
|
||
|
style="width:100%"></textarea>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<hr class="separator assignmentsData" />
|
||
|
<h2 class="assignmentsData" >Assignments</h2>
|
||
|
<table cellspacing="1" cellpadding="0" width="100%" id="assigsTable" class="assignmentsData">
|
||
|
<tr>
|
||
|
<th style="width:100px;">Name</th>
|
||
|
<th style="width:70px;">Role</th>
|
||
|
<th style="width:30px;">Est. Worklog</th>
|
||
|
<th style="width:30px;" id="addAssig"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<hr class="separator materialData" />
|
||
|
<h2 class="materialData">Material</h2>
|
||
|
<table cellspacing="1" cellpadding="0" width="100%" id="materialTable" class="materialData">
|
||
|
<tr>
|
||
|
<th style="width:100px;">Name</th>
|
||
|
<th style="width:30px;" id="addMaterial"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<hr class="separator toolsData" />
|
||
|
<h2 class="toolsData">Tools</h2>
|
||
|
<table cellspacing="1" cellpadding="0" width="100%" id="toolsTable" class="toolsData">
|
||
|
<tr>
|
||
|
<th style="width:100px;">Name</th>
|
||
|
<th style="width:30px;" id="addTools"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
<hr class="separator geofenceData" />
|
||
|
<h2 class="geofenceData">Geofence</h2>
|
||
|
<div style="padding-top: 20px" id="mapgantt"></div>
|
||
|
|
||
|
<div style="text-align: right; padding-top: 20px">
|
||
|
<span id="saveButton" class="button first" onClick="$(this).trigger('saveFullEditor.gantt');">Save</span>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<div class="__template__" type="ASSIGNMENT_ROW">
|
||
|
<!--
|
||
|
<tr taskId="(#=obj.task.id#)" assId="(#=obj.assig.id#)" class="assigEditRow" >
|
||
|
<td ><select name="resourceId" class="formElements" (#=obj.assig.id.indexOf("tmp_")==0?"":"disabled"#) ></select></td>
|
||
|
<td ><select type="select" name="roleId" class="formElements"></select></td>
|
||
|
<td ><input type="text" name="effort" value="(#=getMillisInHoursMinutes(obj.assig.effort)#)" size="5" class="formElements"></td>
|
||
|
<td align="center"><span class="teamworkIcon delAssig del" style="cursor: pointer">d</span></td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="MATERIAL_ROW">
|
||
|
<!--
|
||
|
<tr taskId="(#=obj.task.id#)" materialId="(#=obj.material.id#)" class="materialEditRow" >
|
||
|
<td ><select name="resourceId" class="formElements" (#=obj.material.id.indexOf("tmp_")==0?"":"disabled"#) ></select></td>
|
||
|
<td align="center"><span class="teamworkIcon delMaterial del" style="cursor: pointer">d</span></td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
<div class="__template__" type="TOOLS_ROW">
|
||
|
<!--
|
||
|
<tr taskId="(#=obj.task.id#)" toolsId="(#=obj.tools.id#)" class="toolsEditRow" >
|
||
|
<td ><select name="resourceId" class="formElements" (#=obj.tools.id.indexOf("tmp_")==0?"":"disabled"#) ></select></td>
|
||
|
<td align="center"><span class="teamworkIcon delTools del" style="cursor: pointer">d</span></td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<div class="__template__" type="RESOURCE_EDITOR">
|
||
|
<!--
|
||
|
<div class="resourceEditor" style="padding: 5px;">
|
||
|
|
||
|
<h2>Project team</h2>
|
||
|
<table cellspacing="1" cellpadding="0" width="100%" id="resourcesTable">
|
||
|
<tr>
|
||
|
<th style="width:100px;">name</th>
|
||
|
<th style="width:30px;" id="addResource"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
<div style="text-align: right; padding-top: 20px"><button id="resSaveButton" class="button big">Save</button></div>
|
||
|
</div>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<div class="__template__" type="RESOURCE_ROW">
|
||
|
<!--
|
||
|
<tr resId="(#=obj.id#)" class="resRow" >
|
||
|
<td ><input type="text" name="name" value="(#=obj.name#)" style="width:100%;" class="formElements"></td>
|
||
|
<td align="center"><span class="teamworkIcon delRes del" style="cursor: pointer">d</span></td>
|
||
|
</tr>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<div class="__template__" type="NETWORK_DIAGRAM">
|
||
|
<!--
|
||
|
<div class="resourceEditor" style="padding: 5px;">
|
||
|
|
||
|
<h2>Network Diagram</h2>
|
||
|
<div id="networkDiagramContainer"></div>
|
||
|
</div>
|
||
|
-->
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<script type="text/javascript">
|
||
|
// init map
|
||
|
var map = L.map('mapgantt').setView([-6.918700869941362, 109.94052459570662], 13);
|
||
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
|
}).addTo(map);
|
||
|
|
||
|
$.JST.loadDecorator("RESOURCE_ROW", function (resTr, res) {
|
||
|
resTr.find(".delRes").click(function () {
|
||
|
$(this).closest("tr").remove()
|
||
|
});
|
||
|
});
|
||
|
|
||
|
$.JST.loadDecorator("ASSIGNMENT_ROW", function (assigTr, taskAssig) {
|
||
|
var resEl = assigTr.find("[name=resourceId]");
|
||
|
var opt = $("<option>");
|
||
|
resEl.append(opt);
|
||
|
for (var i = 0; i < taskAssig.task.master.resources.length; i++) {
|
||
|
var res = taskAssig.task.master.resources[i];
|
||
|
opt = $("<option>");
|
||
|
opt.val(res.id).html(res.name);
|
||
|
if (taskAssig.assig.resourceId == res.id)
|
||
|
opt.attr("selected", "true");
|
||
|
resEl.append(opt);
|
||
|
}
|
||
|
var roleEl = assigTr.find("[name=roleId]");
|
||
|
for (var i = 0; i < taskAssig.task.master.roles.length; i++) {
|
||
|
var role = taskAssig.task.master.roles[i];
|
||
|
var optr = $("<option>");
|
||
|
optr.val(role.id).html(role.name);
|
||
|
if (taskAssig.assig.roleId == role.id)
|
||
|
optr.attr("selected", "true");
|
||
|
roleEl.append(optr);
|
||
|
}
|
||
|
|
||
|
if (taskAssig.task.master.permissions.canWrite && taskAssig.task.canWrite) {
|
||
|
assigTr.find(".delAssig").click(function () {
|
||
|
var tr = $(this).closest("[assId]").fadeOut(200, function () {
|
||
|
$(this).remove()
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
$.JST.loadDecorator("MATERIAL_ROW", function (materialTr, taskMaterial) {
|
||
|
materialTr.find(".delMaterial").click(function () {
|
||
|
var tr = $(this).closest("[materialId]").fadeOut(200, function () {
|
||
|
$(this).remove()
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
$.JST.loadDecorator("TOOLS_ROW", function (toolsTr, taskTools) {
|
||
|
toolsTr.find(".delTools").click(function () {
|
||
|
var tr = $(this).closest("[toolsId]").fadeOut(200, function () {
|
||
|
$(this).remove()
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
|
||
|
function loadI18n() {
|
||
|
GanttMaster.messages = {
|
||
|
"CANNOT_WRITE": "No permission to change the following task:",
|
||
|
"CHANGE_OUT_OF_SCOPE": "Project update not possible as you lack rights for updating a parent project.",
|
||
|
"START_IS_MILESTONE": "Start date is a milestone.",
|
||
|
"END_IS_MILESTONE": "End date is a milestone.",
|
||
|
"TASK_HAS_CONSTRAINTS": "Task has constraints.",
|
||
|
"GANTT_ERROR_DEPENDS_ON_OPEN_TASK": "Error: there is a dependency on an open task.",
|
||
|
"GANTT_ERROR_DESCENDANT_OF_CLOSED_TASK": "Error: due to a descendant of a closed task.",
|
||
|
"TASK_HAS_EXTERNAL_DEPS": "This task has external dependencies.",
|
||
|
"GANNT_ERROR_LOADING_DATA_TASK_REMOVED": "GANNT_ERROR_LOADING_DATA_TASK_REMOVED",
|
||
|
"CIRCULAR_REFERENCE": "Circular reference.",
|
||
|
"CANNOT_DEPENDS_ON_ANCESTORS": "Cannot depend on ancestors.",
|
||
|
"INVALID_DATE_FORMAT": "The data inserted are invalid for the field format.",
|
||
|
"GANTT_ERROR_LOADING_DATA_TASK_REMOVED": "An error has occurred while loading the data. A task has been trashed.",
|
||
|
"CANNOT_CLOSE_TASK_IF_OPEN_ISSUE": "Cannot close a task with open issues",
|
||
|
"TASK_MOVE_INCONSISTENT_LEVEL": "You cannot exchange tasks of different depth.",
|
||
|
"CANNOT_MOVE_TASK": "CANNOT_MOVE_TASK",
|
||
|
"PLEASE_SAVE_PROJECT": "PLEASE_SAVE_PROJECT",
|
||
|
"GANTT_SEMESTER": "Semester",
|
||
|
"GANTT_SEMESTER_SHORT": "s.",
|
||
|
"GANTT_QUARTER": "Quarter",
|
||
|
"GANTT_QUARTER_SHORT": "q.",
|
||
|
"GANTT_WEEK": "Week",
|
||
|
"GANTT_WEEK_SHORT": "w."
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
function createNewResource(el) {
|
||
|
var row = el.closest("tr[taskid]");
|
||
|
var name = row.find("[name=resourceId_txt]").val();
|
||
|
var url = contextPath + "/applications/teamwork/resource/resourceNew.jsp?CM=ADD&name=" + encodeURI(name);
|
||
|
|
||
|
openBlackPopup(url, 700, 320, function (response) {
|
||
|
//fillare lo smart combo
|
||
|
if (response && response.resId && response.resName) {
|
||
|
//fillare lo smart combo e chiudere l'editor
|
||
|
row.find("[name=resourceId]").val(response.resId);
|
||
|
row.find("[name=resourceId_txt]").val(response.resName).focus().blur();
|
||
|
}
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
$(document).on("change", "#load-file", function () {
|
||
|
var uploadedFile = $("#load-file").prop("files")[0];
|
||
|
upload(uploadedFile);
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
|
||
|
</html>
|