gantt-1.0.8/js/api.js
js/api.js
(function () {
var apiUrl = "https://export.dhtmlx.com/gantt";
var templates = [
"leftside_text",
"rightside_text",
"task_text",
"progress_text",
"task_class"
];
function xdr(url, pack, cb) {
switch (true) {
case gantt.env.isIE:
gantt.env.isIE = false;
gantt.ajax.post(url, pack, cb);
gantt.env.isIE = true;
break;
case gantt.env.isNode:
const http = require('http');
let parts1 = url.split("://")[1];
let parts2 = parts1.split("/")[0].split(":");
let parts3 = parts1.split("/");
let hostname = parts2[0];
let port = parts2[1] || 80;
let path = "/" + parts3.slice(1).join("/");
const options = {
hostname: hostname,
port: port,
path: path,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': JSON.stringify(pack).length
}
}
const req = http.request(options, function (res) {
let resData = []
res.on('data', function (d) {
resData.push(d)
})
res.on('end', function (d) {
cb(Buffer.concat(resData))
})
})
req.on('error', function (error) {
console.error(error)
})
req.write(JSON.stringify(pack))
req.end()
break;
default:
gantt.ajax.post(url, pack, cb);
}
}
function defaults(obj, std) {
for (let key in std) {
if (!obj[key]) {
obj[key] = std[key];
}
}
return obj;
}
function mark_columns(base) {
let columns = base.config.columns;
if (columns){
for (let i = 0; i < columns.length; i++) {
if (columns[i].template) {
columns[i].$template = true;
}
}
}
}
function add_export_methods(gantt) {
let color_box = null;
let color_hash = {};
function get_styles(css) {
if (!color_box) {
let color_box = document.createElement("DIV");
color_box.style.cssText = "position:absolute; display:none;";
document.body.appendChild(color_box);
}
if (color_hash[css]) {
return color_hash[css];
}
color_box.className = css;
return (color_hash[css] = get_color(color_box, "color") + ";" + get_color(color_box, "backgroundColor"));
}
function getMinutesWorktimeSettings(parsedRanges) {
let minutes = [];
parsedRanges.forEach(function (range) {
minutes.push(range.startMinute);
minutes.push(range.endMinute);
});
return minutes;
}
//compatibility for new versions of gantt
if (typeof gantt != 'undefined' && !gantt.ajax) {
if (window.dhtmlxAjax) {
gantt.ajax = window.dhtmlxAjax;
} else if (window.dhx4) {
gantt.ajax = window.dhx4.ajax;
}
}
gantt._getWorktimeSettings = function () {
let defaultWorkTimes = {
hours: [0, 24],
minutes: null,
dates: {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true}
};
let time;
if (!gantt.config.work_time) {
time = defaultWorkTimes;
} else {
let wTime = gantt._working_time_helper;
if (wTime && wTime.get_calendar) {
time = wTime.get_calendar();
} else if (wTime) {
time = {
hours: wTime.hours,
minutes: null,
dates: wTime.dates
};
} else if (gantt.config.worktimes && gantt.config.worktimes.global) {
let settings = gantt.config.worktimes.global;
if (settings.parsed) {
let minutes = getMinutesWorktimeSettings(settings.parsed.hours);
time = {
hours: null,
minutes: minutes,
dates: {}
};
for (let i in settings.parsed.dates) {
if (Array.isArray(settings.parsed.dates[i])) {
time.dates[i] = getMinutesWorktimeSettings(settings.parsed.dates[i]);
} else {
time.dates[i] = settings.parsed.dates[i];
}
}
} else {
time = {
hours: settings.hours,
minutes: null,
dates: settings.dates
};
}
} else {
time = defaultWorkTimes;
}
}
return time;
};
gantt.exportToPDF = function (config) {
if (config && config.raw) {
config = defaults(config, {
name: "gantt.pdf", data: this._serialize_html()
});
} else {
config = defaults((config || {}), {
name: "gantt.pdf",
data: this._serialize_all(),
config: this.config
});
fix_columns(gantt, config.config.columns);
}
config.version = this.version;
this._send_to_export(config, "pdf");
};
gantt.exportToPNG = function (config) {
if (config && config.raw) {
config = defaults(config, {
name: "gantt.png", data: this._serialize_html()
});
} else {
config = defaults((config || {}), {
name: "gantt.png",
data: this._serialize_all(),
config: this.config
});
fix_columns(gantt, config.config.columns);
}
config.version = this.version;
this._send_to_export(config, "png");
};
gantt.exportToICal = function (config) {
config = defaults((config || {}), {
name: "gantt.ical",
data: this._serialize_plain().data,
version: this.version
});
this._send_to_export(config, "ical");
};
function eachTaskTimed(start, end) {
return function (code, parent, master) {
parent = parent || this.config.root_id;
master = master || this;
let branch = this.getChildren(parent);
if (branch) {
for (let i = 0; i < branch.length; i++) {
let item = this._pull[branch[i]];
if ((!start || item.end_date > start) && (!end || item.start_date < end)) {
code.call(master, item);
}
if (this.hasChild(item.id)) {
this.eachTask(code, item.id, master);
}
}
}
};
}
gantt.exportToExcel = function (config) {
config = config || {};
let tasks, dates;
let state, scroll;
if (config.start || config.end) {
state = this.getState();
dates = [this.config.start_date, this.config.end_date];
scroll = this.getScrollState();
let convert = this.date.str_to_date(this.config.date_format);
tasks = this.eachTask;
if (config.start) {
this.config.start_date = convert(config.start);
}
if (config.end) {
this.config.end_date = convert(config.end);
}
this.render();
this.eachTask = eachTaskTimed(this.config.start_date, this.config.end_date);
}
this._no_progress_colors = config.visual === "base-colors";
let data = null;
if (!gantt.env.isNode) {
data = this._serialize_table(config).data;
}
config = defaults(config, {
name: "gantt.xlsx",
title: "Tasks",
data: data,
columns: this._serialize_columns({rawDates: true}),
version: this.version
});
if (config.visual) {
config.scales = this._serialize_scales(config);
}
this._send_to_export(config, "excel");
if (config.start || config.end) {
this.config.start_date = state.min_date;
this.config.end_date = state.max_date;
this.eachTask = tasks;
this.render();
this.scrollTo(scroll.x, scroll.y);
this.config.start_date = dates[0];
this.config.end_date = dates[1];
}
};
gantt.exportToJSON = function (config) {
config = defaults((config || {}), {
name: "gantt.json",
data: this._serialize_all(),
config: this.config,
columns: this._serialize_columns(),
worktime: gantt._getWorktimeSettings(),
version: this.version
});
this._send_to_export(config, "json");
};
function sendImportAjax(config) {
let url = config.server || apiUrl;
let store = config.store || 0;
let formData = config.data;
let callback = config.callback;
formData.append("type", "excel-parse");
formData.append("data", JSON.stringify({
sheet: config.sheet || 0,
server: url
}));
if (store) {
formData.append("store", store);
}
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 0) {// network error
if (callback) {
callback(null);
}
}
};
xhr.onload = function () {
let fail = xhr.status > 400;
let info = null;
if (!fail) {
try {
info = JSON.parse(xhr.responseText);
} catch (e) {
}
}
if (callback) {
callback(info);
}
};
xhr.open('POST', url, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.send(formData);
}
function nodejsImportExcel(config) {
const http = require('http');
let FormData = require('form-data');
let url = config.server || apiUrl;
let parts1 = url.split("://")[1];
let parts2 = parts1.split("/")[0].split(":");
let parts3 = parts1.split("/");
let hostname = parts2[0];
let port = parts2[1] || 80;
let path = "/" + parts3.slice(1).join("/");
const options = {
hostname: hostname,
port: port,
path: path,
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
}
let formData = new FormData();
formData.append("file", config.data);
formData.append("type", "excel-parse");
formData.append("data", JSON.stringify({
sheet: config.sheet || 0
}));
options.headers['Content-Type'] = formData.getHeaders()['content-type']
const req = http.request(options, function (res) {
let resData = '';
res.on('data', function (d) {
resData += d;
})
res.on('end', function (d) {
config.callback(resData.toString())
})
})
req.on('error', function (error) {
console.error(error)
})
formData.pipe(req);
}
gantt.importFromExcel = function (config) {
try {
let formData = config.data;
if (formData instanceof FormData) {
} else if (formData instanceof File) {
let data = new FormData();
data.append("file", formData);
config.data = data;
}
} catch (error) {
}
if (gantt.env.isNode) {
nodejsImportExcel(config)
} else {
sendImportAjax(config);
}
};
gantt._msp_config = function (config) {
if (config.project) {
for (let i in config.project) {
if (!config._custom_data) {
config._custom_data = {};
}
config._custom_data[i] = config.project[i](this.config);
}
}
if (config.tasks) {
for (let j = 0; j < config.data.length; j++) {
let el = this.getTask(config.data[j].id);
if (!el._custom_data) {
el._custom_data = {};
}
for (let i in config.tasks) {
el._custom_data[i] = config.tasks[i](el, this.config);
}
}
}
delete config.project;
delete config.tasks;
config.time = gantt._getWorktimeSettings();
let p_dates = this.getSubtaskDates();
let format = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
config.start_end = {
start_date: format(p_dates.start_date),
end_date: format(p_dates.end_date)
};
};
gantt._msp_data = function () {
let old_xml_format = this.templates.xml_format;
let old_format_date = this.templates.format_date;
this.templates.xml_format = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
this.templates.format_date = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
let data = this._serialize_all();
this.templates.xml_format = old_xml_format;
this.templates.format_date = old_format_date;
return data;
};
gantt._ajax_to_export = function (data, type, callback) {
delete data.callback;
let url = data.server || apiUrl;
let pack = "type=" + type + "&store=1&data=" + encodeURIComponent(JSON.stringify(data));
let cb = function (loader) {
let xdoc = loader.xmlDoc || loader;
let fail = xdoc.status > 400;
let info = null;
if (!fail) {
try {
info = JSON.parse(xdoc.responseText);
} catch (e) {
}
}
callback(info);
};
xdr(url, pack, cb);
};
gantt._send_to_export = function (data, type) {
let convert = this.date.date_to_str(this.config.date_format || this.config.xml_date);
if (data.config) {
data.config = this.copy(data.config);
mark_columns(data, type);
if (data.config.start_date && data.config.end_date) {
if (data.config.start_date instanceof Date) {
data.config.start_date = convert(data.config.start_date)
}
if (data.config.end_date instanceof Date) {
data.config.end_date = convert(data.config.end_date)
}
}
}
if (gantt.env.isNode) {
let url = data.server || apiUrl;
let pack = {
type: type,
store: 0,
data: JSON.stringify(data)
}
let callbackFunction = data.callback || function (response) {
console.log(response)
}
return xdr(url, pack, callbackFunction)
}
if (data.callback) {
return gantt._ajax_to_export(data, type, data.callback);
}
let form = this._create_hidden_form();
form.firstChild.action = data.server || apiUrl;
form.firstChild.childNodes[0].value = JSON.stringify(data);
form.firstChild.childNodes[1].value = type;
form.firstChild.submit();
};
gantt._create_hidden_form = function () {
if (!this._hidden_export_form) {
let t = this._hidden_export_form = document.createElement("div");
t.style.display = "none";
t.innerHTML = "<form method='POST' target='_blank'><textarea name='data' style='width:0px; height:0px;' readonly='true'></textarea><input type='hidden' name='type' value=''></form>";
document.body.appendChild(t);
}
return this._hidden_export_form;
};
//patch broken json serialization in gantt 2.1
let original = gantt.json._copyObject;
function copy_object_base(obj) {
let copy = {};
for (let key in obj) {
if (key.charAt(0) === "$") {
continue;
}
copy[key] = obj[key];
}
let formatDate = gantt.templates.xml_format || gantt.templates.format_date;
copy.start_date = formatDate(copy.start_date);
if (copy.end_date) {
copy.end_date = formatDate(copy.end_date);
}
return copy;
}
function copy_object_plain(obj) {
let text = gantt.templates.task_text(obj.start_date, obj.end_date, obj);
let copy = copy_object_base(obj);
copy.text = text || copy.text;
return copy;
}
function get_color(node, style) {
let value = node.currentStyle ? node.currentStyle[style] : getComputedStyle(node, null)[style];
let rgb = value.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+)/i);
return ((rgb && rgb.length === 4) ?
("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : value).replace("#", "");
}
// Excel interprets UTC time as local time in every timezone, send local time instead of actual UTC time.
// https://github.com/SheetJS/js-xlsx/issues/126#issuecomment-60531614
let toISOstring = gantt.date.date_to_str("%Y-%m-%dT%H:%i:%s.000Z");
// excel serialization
function copy_object_table(obj) {
let copy = copy_object_columns(obj, copy_object_plain(obj));
if (copy.start_date) {
copy.start_date = toISOstring(obj.start_date);
}
if (copy.end_date) {
copy.end_date = toISOstring(obj.end_date);
}
// private gantt._day_index_by_date was replaced by public gantt.columnIndexByDate in gantt 5.0
let getDayIndex = gantt._day_index_by_date ? gantt._day_index_by_date : gantt.columnIndexByDate;
copy.$start = getDayIndex.call(gantt, obj.start_date);
copy.$end = getDayIndex.call(gantt, obj.end_date);
copy.$level = obj.$level;
copy.$type = obj.$rendered_type;
let tmps = gantt.templates;
copy.$text = tmps.task_text(obj.start, obj.end_date, obj);
copy.$left = tmps.leftside_text ? tmps.leftside_text(obj.start, obj.end_date, obj) : "";
copy.$right = tmps.rightside_text ? tmps.rightside_text(obj.start, obj.end_date, obj) : "";
return copy;
}
function copy_object_colors(obj) {
let copy = copy_object_table(obj);
let node = gantt.getTaskNode(obj.id);
if (node && node.firstChild) {
let color = get_color((gantt._no_progress_colors ? node : node.firstChild), "backgroundColor");
if (color === "363636") {
color = get_color(node, "backgroundColor");
}
copy.$color = color;
} else if (obj.color) {
copy.$color = obj.color;
}
return copy;
}
function copy_object_columns(obj, copy) {
for (let i = 0; i < gantt.config.columns.length; i++) {
let ct = gantt.config.columns[i].template;
if (ct) {
let val = ct(obj);
if (val instanceof Date) {
val = gantt.templates.date_grid(val, obj);
}
copy["_" + i] = val;
}
}
return copy;
}
function copy_object_all(obj) {
let copy = copy_object_base(obj);
//serialize all text templates
for (let i = 0; i < templates.length; i++) {
let template = gantt.templates[templates[i]];
if (template) {
copy["$" + i] = template(obj.start_date, obj.end_date, obj);
}
}
copy_object_columns(obj, copy);
copy.open = obj.$open;
return copy;
}
function fix_columns(gantt, columns) {
for (let i = 0; i < columns.length; i++) {
columns[i].label = columns[i].label || gantt.locale.labels["column_" + columns[i].name];
if (typeof columns[i].width === "string") {
columns[i].width = columns[i].width * 1;
}
}
}
gantt._serialize_html = function () {
let smartScales = gantt.config.smart_scales;
let smartRendering = gantt.config.smart_rendering;
if (smartScales || smartRendering) {
gantt.config.smart_rendering = false;
gantt.config.smart_scales = false;
gantt.render();
}
let html = this.$container.parentNode.innerHTML;
if (smartScales || smartRendering) {
gantt.config.smart_scales = smartScales;
gantt.config.smart_rendering = smartRendering;
gantt.render();
}
return html;
};
gantt._serialize_all = function () {
gantt.json._copyObject = copy_object_all;
let data = export_serialize();
gantt.json._copyObject = original;
return data;
};
gantt._serialize_plain = function () {
let oldXmlFormat = gantt.templates.xml_format;
let oldFormatDate = gantt.templates.format_date;
gantt.templates.xml_format = gantt.date.date_to_str("%Y%m%dT%H%i%s", true);
gantt.templates.format_date = gantt.date.date_to_str("%Y%m%dT%H%i%s", true);
gantt.json._copyObject = copy_object_plain;
let data = export_serialize();
gantt.templates.xml_format = oldXmlFormat;
gantt.templates.format_date = oldFormatDate;
gantt.json._copyObject = original;
delete data.links;
return data;
};
function get_raw() {
// support Gantt < 5.0
if (gantt._scale_helpers) {
let scales = gantt._get_scales(),
min_width = gantt.config.min_column_width,
autosize_min_width = gantt._get_resize_options().x ? Math.max(gantt.config.autosize_min_width, 0) : config.$task.offsetWidth,
height = config.config.scale_height - 1;
return gantt._scale_helpers.prepareConfigs(scales, min_width, autosize_min_width, height);
} else { // Gantt >= 5.0
let timeline = gantt.$ui.getView("timeline");
if (timeline) {
let availWidth = timeline.$config.width;
if (gantt.config.autosize === "x" || gantt.config.autosize === "xy") {
availWidth = Math.max(gantt.config.autosize_min_width, 0);
}
let state = gantt.getState(),
scales = timeline._getScales(),
min_width = gantt.config.min_column_width,
height = gantt.config.scale_height - 1,
rtl = gantt.config.rtl;
return timeline.$scaleHelper.prepareConfigs(scales, min_width, availWidth, height, state.min_date, state.max_date, rtl);
}
}
}
gantt._serialize_table = function (config) {
gantt.json._copyObject = config.visual ? copy_object_colors : copy_object_table;
let data = export_serialize();
gantt.json._copyObject = original;
delete data.links;
if (config.cellColors) {
let css = this.templates.timeline_cell_class || this.templates.task_cell_class;
if (css) {
let raw = get_raw();
let steps = raw[0].trace_x;
for (let i = 1; i < raw.length; i++) {
if (raw[i].trace_x.length > steps.length) {
steps = raw[i].trace_x;
}
}
for (let i = 0; i < data.data.length; i++) {
data.data[i].styles = [];
let task = this.getTask(data.data[i].id);
for (let j = 0; j < steps.length; j++) {
let date = steps[j];
let cell_css = css(task, date);
if (cell_css) {
data.data[i].styles.push({index: j, styles: get_styles(cell_css)});
} }
}
}
}
return data;
};
gantt._serialize_scales = function (config) {
let scales = [];
let raw = get_raw();
let min = Infinity;
let max = 0;
for (let i = 0; i < raw.length; i++) {
min = Math.min(min, raw[i].col_width);
}
for (let i = 0; i < raw.length; i++) {
let start = 0;
let end = 0;
let row = [];
scales.push(row);
let step = raw[i];
max = Math.max(max, step.trace_x.length);
let template = step.format || step.template || (step.date ? gantt.date.date_to_str(step.date) : gantt.config.date_scale);
for (let j = 0; j < step.trace_x.length; j++) {
let date = step.trace_x[j];
end = start + Math.round(step.width[j] / min);
let scale_cell = {text: template(date), start: start, end: end};
if (config.cellColors) {
let css = step.css || this.templates.scale_cell_class;
if (css) {
let scale_css = css(date);
if (scale_css) {
scale_cell.styles = get_styles(scale_css);
}
}
}
row.push(scale_cell);
start = end;
}
}
return {width: max, height: scales.length, data: scales};
};
gantt._serialize_columns = function (config) {
gantt.exportMode = true;
let columns = [];
let cols = gantt.config.columns;
let ccount = 0;
for (let i = 0; i < cols.length; i++) {
if (cols[i].name === "add" || cols[i].name === "buttons") {
continue;
}
columns[ccount] = {
id: ((cols[i].template) ? ("_" + i) : cols[i].name),
header: cols[i].label || gantt.locale.labels["column_" + cols[i].name],
width: (cols[i].width ? Math.floor(cols[i].width / 4) : "")
};
if (cols[i].name === "duration") {
columns[ccount].type = "number";
}
if (cols[i].name === "start_date" || cols[i].name === "end_date") {
columns[ccount].type = "date";
if (config && config.rawDates) {
columns[ccount].id = cols[i].name;
}
}
ccount++;
}
gantt.exportMode = false;
return columns;
};
function export_serialize() {
gantt.exportMode = true;
let xmlFormat = gantt.templates.xml_format;
let formatDate = gantt.templates.format_date;
// use configuration date format for serialization so date could be parsed on the export
// required when custom format date function is defined
gantt.templates.xml_format =
gantt.templates.format_date =
gantt.date.date_to_str(gantt.config.date_format || gantt.config.xml_date);
let data = gantt.serialize();
gantt.templates.xml_format = xmlFormat;
gantt.templates.format_date = formatDate;
gantt.exportMode = false;
return data;
}
}
add_export_methods(gantt);
try {
if (window && window.Gantt && Gantt.plugin) {
Gantt.plugin(add_export_methods);
}
} catch (error) {
}
})();
(function () {
var apiUrl = "https://export.dhtmlx.com/gantt";
function set_level(data) {
for (let i = 0; i < data.length; i++) {
if (data[i].parent === 0) {
data[i]._lvl = 1;
}
for (let j = i + 1; j < data.length; j++) {
if (data[i].id === data[j].parent) {
data[j]._lvl = data[i]._lvl + 1;
}
}
}
}
function clear_level(data) {
for (let i = 0; i < data.length; i++) {
delete data[i]._lvl
}
}
function clear_rec_links(data) {
set_level(data.data);
let tasks = {};
for (let i = 0; i < data.data.length; i++) {
tasks[data.data[i].id] = data.data[i];
}
let links = {};
for (let i = 0; i < data.links.length; i++) {
let link = data.links[i];
if (gantt.isTaskExists(link.source) && gantt.isTaskExists(link.target) &&
tasks[link.source] && tasks[link.target]) {
links[link.id] = link;
}
}
for (let i in links) {
make_links_same_level(links[i], tasks);
}
const skippedLinks = {};
for (let i in tasks) {
clear_circ_dependencies(tasks[i], links, tasks, {}, skippedLinks, null);
}
for (let i in links) {
clear_links_same_level(links, tasks);
}
for (let i = 0; i < data.links.length; i++) {
if (!links[data.links[i].id]) {
data.links.splice(i, 1);
i--;
}
}
clear_level(data.data);
}
function clear_circ_dependencies(task, links, tasks, usedTasks, skippedLinks, prevLink) {
let sources = task.$_source;
if (!sources) {
return;
}
if (usedTasks[task.id]) {
on_circ_dependency_find(prevLink, links, usedTasks, skippedLinks);
}
usedTasks[task.id] = true;
let targets = {};
for (let i = 0; i < sources.length; i++) {
if (skippedLinks[sources[i]]) {
continue;
}
let curLink = links[sources[i]];
let targetTask = tasks[curLink._target];
if (targets[targetTask.id]) { // two link from one task to another
on_circ_dependency_find(curLink, links, usedTasks, skippedLinks);
}
targets[targetTask.id] = true;
clear_circ_dependencies(targetTask, links, tasks, usedTasks, skippedLinks, curLink);
}
usedTasks[task.id] = false;
}
function on_circ_dependency_find(link, links, usedTasks, skippedLinks) {
if (link) {
if (gantt.callEvent("onExportCircularDependency", [link.id, link])) {
delete links[link.id];
}
delete usedTasks[link._source];
delete usedTasks[link._target];
skippedLinks[link.id] = true;
}
}
function make_links_same_level(link, tasks) {
let task,
targetLvl,
linkT = {
target: tasks[link.target],
source: tasks[link.source]
};
if (linkT.target._lvl != linkT.source._lvl) {
if (linkT.target._lvl < linkT.source._lvl) {
task = "source";
targetLvl = linkT.target._lvl
} else {
task = "target";
targetLvl = linkT.source._lvl;
}
do {
let parent = tasks[linkT[task].parent];
if (!parent) {
break;
}
linkT[task] = parent;
} while (linkT[task]._lvl < targetLvl);
let sourceParent = tasks[linkT.source.parent],
targetParent = tasks[linkT.target.parent];
while (sourceParent && targetParent && sourceParent.id != targetParent.id) {
linkT.source = sourceParent;
linkT.target = targetParent;
sourceParent = tasks[linkT.source.parent];
targetParent = tasks[linkT.target.parent];
}
}
link._target = linkT.target.id;
link._source = linkT.source.id;
if (!linkT.target.$_target) {
linkT.target.$_target = [];
}
linkT.target.$_target.push(link.id);
if (!linkT.source.$_source) {
linkT.source.$_source = [];
}
linkT.source.$_source.push(link.id);
}
function clear_links_same_level(links, tasks) {
for (let link in links) {
delete links[link]._target;
delete links[link]._source;
}
for (let task in tasks) {
delete tasks[task].$_source;
delete tasks[task].$_target;
}
}
function customProjectProperties(data, config) {
if (config && config.project) {
for (let i in config.project) {
if (!gantt.config.$custom_data) {
gantt.config.$custom_data = {};
}
gantt.config.$custom_data[i] = typeof config.project[i] === "function" ? config.project[i](gantt.config) : config.project[i];
}
delete config.project;
}
}
function customTaskProperties(data, config) {
if (config && config.tasks) {
data.data.forEach(function (el) {
for (let i in config.tasks) {
if (!el.$custom_data) {
el.$custom_data = {};
}
el.$custom_data[i] = typeof config.tasks[i] === "function" ? config.tasks[i](el, gantt.config) : config.tasks[i];
}
});
delete config.tasks;
}
}
function exportConfig(data, config) {
let p_name = config.name || 'gantt.xml';
delete config.name;
gantt.config.custom = config;
let time = gantt._getWorktimeSettings();
let p_dates = gantt.getSubtaskDates();
if (p_dates.start_date && p_dates.end_date) {
let formatDate = gantt.templates.format_date || gantt.templates.xml_format;
gantt.config.start_end = {
start_date: formatDate(p_dates.start_date),
end_date: formatDate(p_dates.end_date)
};
}
let manual = config.auto_scheduling === undefined ? false : !!config.auto_scheduling;
let res = {
callback: config.callback || null,
config: gantt.config,
data: data,
manual: manual,
name: p_name,
worktime: time
};
for (let i in config) {
res[i] = config[i];
}
return res;
}
function add_export_methods(gantt) {
gantt._ms_export = {};
gantt.exportToMSProject = function (config) {
config = config || {};
config.skip_circular_links = config.skip_circular_links === undefined ? true : !!config.skip_circular_links;
let oldXmlFormat = this.templates.xml_format;
let oldFormatDate = this.templates.format_date;
let oldXmlDate = this.config.xml_date;
let oldDateFormat = this.config.date_format;
let exportServiceDateFormat = "%d-%m-%Y %H:%i:%s";
this.config.xml_date = exportServiceDateFormat;
this.config.date_format = exportServiceDateFormat;
this.templates.xml_format = this.date.date_to_str(exportServiceDateFormat);
this.templates.format_date = this.date.date_to_str(exportServiceDateFormat);
let data = this._serialize_all();
customProjectProperties(data, config);
customTaskProperties(data, config);
if (config.skip_circular_links) {
clear_rec_links(data);
}
config = exportConfig(data, config);
this._send_to_export(config, config.type || "msproject");
this.config.xml_date = oldXmlDate;
this.config.date_format = oldDateFormat;
this.templates.xml_format = oldXmlFormat;
this.templates.format_date = oldFormatDate;
this.config.$custom_data = null;
this.config.custom = null;
};
gantt.exportToPrimaveraP6 = function (config) {
config.type = "primaveraP6";
return gantt.exportToMSProject(config);
};
function sendImportAjax(config) {
let url = config.server || apiUrl;
let store = config.store || 0;
let formData = config.data;
let callback = config.callback;
let settings = {server: url};
if (config.durationUnit) {
settings.durationUnit = config.durationUnit
}
if (config.projectProperties) {
settings.projectProperties = config.projectProperties;
}
if (config.taskProperties) {
settings.taskProperties = config.taskProperties;
}
formData.append("type", config.type || "msproject-parse");
formData.append("data", JSON.stringify(settings));
if (store) {
formData.append("store", store);
}
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 0) {// network error
if (callback) {
callback(null);
}
}
};
xhr.onload = function () {
let fail = xhr.status > 400;
let info = null;
if (!fail) {
try {
info = JSON.parse(xhr.responseText);
} catch (e) {
}
}
if (callback) {
callback(info);
}
};
xhr.open('POST', url, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.send(formData);
}
function nodejsImportMSP(config) {
const http = require('http');
let FormData = require('form-data');
let url = config.server || apiUrl;
let parts1 = url.split("://")[1];
let parts2 = parts1.split("/")[0].split(":");
let parts3 = parts1.split("/");
let hostname = parts2[0];
let port = parts2[1] || 80;
let path = "/" + parts3.slice(1).join("/");
const options = {
hostname: hostname,
port: port,
path: path,
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
}
let settings = {};
if (config.durationUnit) {
settings.durationUnit = config.durationUnit
}
if (config.projectProperties) {
settings.projectProperties = config.projectProperties;
}
if (config.taskProperties) {
settings.taskProperties = config.taskProperties;
}
let formData = new FormData();
formData.append("file", config.data);
formData.append("type", config.type || "msproject-parse");
formData.append("data", JSON.stringify(settings), options);
options.headers['Content-Type'] = formData.getHeaders()['content-type']
const req = http.request(options, function (res) {
let resData = '';
res.on('data', function (d) {
resData += d;
})
res.on('end', function (d) {
config.callback(resData.toString())
})
})
req.on('error', function (error) {
console.error(error)
})
formData.pipe(req);
}
gantt.importFromMSProject = function (config) {
let formData = config.data;
try {
if (formData instanceof FormData) {
} else if (formData instanceof File) {
let data = new FormData();
data.append("file", formData);
config.data = data;
}
} catch (error) {
}
if (gantt.env.isNode) {
nodejsImportMSP(config);
} else {
sendImportAjax(config);
}
};
gantt.importFromPrimaveraP6 = function (config) {
config.type = "primaveraP6-parse";
return gantt.importFromMSProject(config);
};
}
add_export_methods(gantt);
try {
if (window && window.Gantt && Gantt.plugin) {
Gantt.plugin(add_export_methods);
}
} catch (error) {
}
})();
