836 lines
23 KiB
JavaScript
836 lines
23 KiB
JavaScript
/*
|
|
* Axelor Business Solutions
|
|
*
|
|
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
// localization
|
|
|
|
(function () {
|
|
|
|
/* global gantt: true */
|
|
|
|
"use strict";
|
|
|
|
$(function () {
|
|
$('<script>')
|
|
.attr('type', 'text/javascript')
|
|
.attr('src', 'https://export.dhtmlx.com/gantt/api.js').appendTo('head');
|
|
});
|
|
|
|
var regional = {
|
|
month_full: [
|
|
_t('January'),
|
|
_t('February'),
|
|
_t('March'),
|
|
_t('April'),
|
|
_t('May'),
|
|
_t('June'),
|
|
_t('July'),
|
|
_t('August'),
|
|
_t('September'),
|
|
_t('October'),
|
|
_t('November'),
|
|
_t('December')],
|
|
month_short: [
|
|
_t('Jan'),
|
|
_t('Feb'),
|
|
_t('Mar'),
|
|
_t('Apr'),
|
|
_t('May'),
|
|
_t('Jun'),
|
|
_t('Jul'),
|
|
_t('Aug'),
|
|
_t('Sep'),
|
|
_t('Oct'),
|
|
_t('Nov'),
|
|
_t('Dec')],
|
|
day_full: [
|
|
_t('Sunday'),
|
|
_t('Monday'),
|
|
_t('Tuesday'),
|
|
_t('Wednesday'),
|
|
_t('Thursday'),
|
|
_t('Friday'),
|
|
_t('Saturday')],
|
|
day_short : [_t('Sun'), _t('Mon'), _t('Tue'), _t('Wed'), _t('Thu'), _t('Fri'), _t('Sat')]
|
|
};
|
|
|
|
gantt.locale = {
|
|
date: regional,
|
|
labels:{
|
|
new_task: _t("New task"),
|
|
icon_save: _t("Save"),
|
|
icon_cancel: _t("Cancel"),
|
|
icon_details: _t("Details"),
|
|
icon_edit: _t("Edit"),
|
|
icon_delete: _t("Delete"),
|
|
confirm_closing:"",// Your changes will be lost, are your sure ?
|
|
confirm_deleting: _t("Task will be deleted permanently, are you sure?"),
|
|
section_description: _t("Description"),
|
|
section_time: _t("Time period"),
|
|
section_type: _t("Type"),
|
|
|
|
/* grid columns */
|
|
|
|
column_text : _t("Task name"),
|
|
column_start_date : _t("Start time"),
|
|
column_duration : _t("Duration"),
|
|
column_add : "",
|
|
|
|
/* link confirmation */
|
|
link: _t("Link"),
|
|
confirm_link_deleting: _t("will be deleted"),
|
|
link_start: " " + _t("(start)"),
|
|
link_end: " " + _t("(end)"),
|
|
|
|
type_task: _t("Task"),
|
|
type_project: _t("Project"),
|
|
type_milestone: _t("Milestone"),
|
|
|
|
minutes: _t("Minutes"),
|
|
hours: _t("Hours"),
|
|
days: _t("Days"),
|
|
weeks: _t("Week"),
|
|
months: _t("Months"),
|
|
years: _t("Years")
|
|
}
|
|
};
|
|
|
|
var ui = angular.module('axelor.ui');
|
|
ui.controller('GanttViewCtrl', GanttViewCtrl);
|
|
|
|
GanttViewCtrl.$inject = ['$scope', '$element'];
|
|
|
|
function GanttViewCtrl($scope, $element) {
|
|
|
|
ui.DSViewCtrl('gantt', $scope, $element);
|
|
var ds = $scope._dataSource;
|
|
var view = $scope._views.gantt;
|
|
var initialized = false;
|
|
|
|
$scope.onShow = function(viewPromise) {
|
|
|
|
if (initialized) {
|
|
return $scope.refresh();
|
|
}
|
|
|
|
viewPromise.then(function(){
|
|
var schema = $scope.schema;
|
|
initialized = true;
|
|
$scope._viewResolver.resolve(schema, $element);
|
|
$scope.updateRoute();
|
|
});
|
|
|
|
};
|
|
|
|
$scope.select = function() {
|
|
|
|
};
|
|
|
|
$scope.fetchItems = function(callback) {
|
|
|
|
var schema = $scope.schema;
|
|
|
|
var searchFields = _.pluck(this.fields, "name");
|
|
searchFields.push(schema.taskStart);
|
|
|
|
var optionalFields = [schema.taskProgress,
|
|
schema.taskEnd,
|
|
schema.taskDuration,
|
|
schema.taskParent,
|
|
schema.taskSequence,
|
|
schema.taskProgress,
|
|
schema.finishToStart,
|
|
schema.startToStart,
|
|
schema.finishToFinish,
|
|
schema.startToFinish,
|
|
schema.taskUser
|
|
];
|
|
|
|
_.each(optionalFields,function(optField){
|
|
if(optField){
|
|
searchFields.push(optField);
|
|
}
|
|
});
|
|
|
|
var opts = {
|
|
fields: searchFields,
|
|
filter: false,
|
|
domain: this._domain,
|
|
store: false
|
|
};
|
|
|
|
ds.search(opts).success(function(records) {
|
|
callback(records);
|
|
});
|
|
};
|
|
|
|
$scope.getContext = function() {
|
|
return _.extend({}, $scope._context);
|
|
};
|
|
|
|
$scope.getRouteOptions = function() {
|
|
return {
|
|
mode: 'gantt',
|
|
args: []
|
|
};
|
|
};
|
|
|
|
$scope.setRouteOptions = function(options) {
|
|
var opts = options || {};
|
|
if (opts.mode === "gantt") {
|
|
return $scope.updateRoute();
|
|
}
|
|
var params = $scope._viewParams;
|
|
if (params.viewType !== "calendar") {
|
|
return $scope.show();
|
|
}
|
|
};
|
|
|
|
$scope.doSave = function(task, callback){
|
|
var record = _.clone(task.record);
|
|
return ds.save(record).success(function(res){
|
|
callback(task, res);
|
|
});
|
|
};
|
|
|
|
$scope.doRemove = function(id, task){
|
|
var record = _.clone(task.record);
|
|
return ds.remove(record).success(function(res){
|
|
return true;
|
|
});
|
|
};
|
|
|
|
}
|
|
|
|
ui.directive('uiViewGantt', ['ViewService', 'ActionService', function(ViewService, ActionService) {
|
|
|
|
function link(scope, element, attrs, controller) {
|
|
var main = element.children(".gantt-main");
|
|
var schema = scope.schema;
|
|
var fields = scope.fields;
|
|
var fieldNames = _.pluck(schema.items, "name");
|
|
var firstField = fields[fieldNames[0]];
|
|
var mode = schema.mode || "week";
|
|
var editor = null;
|
|
ganttInit();
|
|
|
|
function byId(list, id) {
|
|
for (var i = 0; i < list.length; i++) {
|
|
if (list[i].key == id)
|
|
return list[i].label || "";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function setScaleConfig(value){
|
|
|
|
switch (value) {
|
|
case "day":
|
|
gantt.config.scale_unit = "day";
|
|
gantt.config.date_scale = "%d/%m/%Y";
|
|
gantt.config.subscales = [{unit:"hour", step:1, date:"%H:%i"}];
|
|
gantt.templates.date_scale = null;
|
|
gantt.config.min_column_width = 50;
|
|
break;
|
|
case "week":
|
|
var weekScaleTemplate = function(date){
|
|
var dateToStr = gantt.date.date_to_str("%d/%m/%Y");
|
|
var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
|
|
return gantt.date.date_to_str("%W")(date) + "(" + dateToStr(date) + " - " + dateToStr(endDate) + ")";
|
|
};
|
|
gantt.config.scale_unit = "week";
|
|
gantt.templates.date_scale = weekScaleTemplate;
|
|
gantt.config.min_column_width = 50;
|
|
gantt.config.subscales = [
|
|
{unit:"day", step:1, date:"%D %d" }];
|
|
break;
|
|
case "month":
|
|
gantt.config.scale_unit = "month";
|
|
gantt.config.date_scale = "%F, %Y";
|
|
gantt.config.subscales = [
|
|
{unit:"week", step:1, date:"%W" }
|
|
];
|
|
gantt.templates.date_scale = null;
|
|
gantt.config.min_column_width = 50;
|
|
break;
|
|
case "year":
|
|
gantt.config.scale_unit = "year";
|
|
gantt.config.date_scale = "%Y";
|
|
gantt.templates.date_scale = null;
|
|
gantt.config.min_column_width = 100;
|
|
gantt.config.subscales = [
|
|
{unit:"month", step:1, date:"%M" }
|
|
];
|
|
break;
|
|
}
|
|
}
|
|
|
|
function getGanttColumns() {
|
|
|
|
var colHeader = '<div class="gantt_grid_head_cell gantt_grid_head_add" onclick="gantt.createTask()"></div>';
|
|
|
|
var colContent = function(task){
|
|
return '<i class="fa gantt_button_grid gantt_grid_add fa-plus" onclick="gantt.createTask(null, '+task.id+')"></i>'+
|
|
'<i class="fa gantt_button_grid gantt_grid_delete fa-times" onclick="gantt.confirm({ ' +
|
|
'title: gantt.locale.labels.confirm_deleting_title,'+
|
|
'text: gantt.locale.labels.confirm_deleting,'+
|
|
'callback: function(res){ '+
|
|
' if(res)'+
|
|
' gantt.deleteTask('+task.id+');'+
|
|
'}})"></i>';
|
|
};
|
|
|
|
|
|
var columns = [];
|
|
|
|
if (schema.taskUser) {
|
|
columns.push({name: "users", label: fields[schema.taskUser].title, align: "center", template: function (item) {
|
|
return byId(gantt.serverList("users"), item.user_id);
|
|
}});
|
|
}
|
|
|
|
var isTree = true;
|
|
_.each(fieldNames, function(fname){
|
|
var field = fields[fname];
|
|
if (columns.length == 0) {
|
|
columns.push({ name:"text", label:field.title, tree:isTree,
|
|
template: function(item){
|
|
if(moment(item[fname], moment.ISO_8601, true).isValid()) {
|
|
return moment(item[fname], moment.ISO_8601, true).format("MM/DD/YYYY h:mm:ss");
|
|
}
|
|
return item.text;
|
|
}});
|
|
}
|
|
else {
|
|
columns.push({ name:field.name, label:field.title, tree:isTree,
|
|
template: function(item){
|
|
if (!item.label) {
|
|
if(moment(item[fname], moment.ISO_8601, true).isValid()) {
|
|
return moment(item[fname], moment.ISO_8601, true).format("MM/DD/YYYY h:mm:ss");
|
|
}
|
|
return item[fname];
|
|
}
|
|
return "";
|
|
}
|
|
});
|
|
}
|
|
isTree = false;
|
|
});
|
|
columns.push({ name:"buttons", label:colHeader, width:30, template:colContent });
|
|
|
|
return columns;
|
|
}
|
|
|
|
function setChildTaskDisplay() {
|
|
|
|
function createBox(sizes, class_name){
|
|
var box = document.createElement('div');
|
|
box.style.cssText = [
|
|
"height:" + sizes.height + "px",
|
|
"line-height:" + sizes.height + "px",
|
|
"width:" + sizes.width + "px",
|
|
"top:" + sizes.top + 'px',
|
|
"left:" + sizes.left + "px",
|
|
"position:absolute"
|
|
].join(";");
|
|
box.className = class_name;
|
|
|
|
return box;
|
|
}
|
|
|
|
gantt.templates.grid_row_class = gantt.templates.task_class=function(start, end, task){
|
|
var css = [];
|
|
if(gantt.hasChild(task.id)){
|
|
css.push("task-parent");
|
|
}
|
|
if (!task.$open && gantt.hasChild(task.id)) {
|
|
css.push("task-collapsed");
|
|
}
|
|
|
|
if (task.$virtual || task.type == gantt.config.types.project)
|
|
css.push("summary-bar");
|
|
|
|
if(task.user_id){
|
|
css.push("gantt_resource_task gantt_resource_" + task.user_id);
|
|
}
|
|
|
|
return css.join(" ");
|
|
};
|
|
|
|
}
|
|
|
|
function ganttInit(){
|
|
gantt = main.dhx_gantt();
|
|
setScaleConfig("week");
|
|
gantt.templates.leftside_text = function(start, end, task){
|
|
if (!task.progress){
|
|
return "";
|
|
}
|
|
return "<span style='text-align:left;'>"+Math.round(task.progress*100)+ "% </span>";
|
|
};
|
|
gantt.config.step = 1;
|
|
gantt.config.duration_unit = "hour";
|
|
gantt.config.duration_step = 1;
|
|
gantt.config.scale_height = 75;
|
|
gantt.config.grid_width = 400;
|
|
gantt.config.fit_tasks = true;
|
|
gantt.config.columns = getGanttColumns();
|
|
gantt._onTaskIdChange = null;
|
|
gantt._onLinkIdChange = null;
|
|
gantt.config.autosize = "x";
|
|
gantt.config.grid_resize = true;
|
|
gantt.config.order_branch = true;
|
|
gantt.config.date_grid = "%d/%m/%Y %H %i";
|
|
gantt.serverList("users", []);
|
|
|
|
gantt.eachSuccessor = function(callback, root){
|
|
if(!this.isTaskExists(root))
|
|
return;
|
|
|
|
// remember tasks we've already iterated in order to avoid infinite loops
|
|
var traversedTasks = arguments[2] || {};
|
|
if(traversedTasks[root])
|
|
return;
|
|
traversedTasks[root] = true;
|
|
|
|
var rootTask = this.getTask(root);
|
|
var links = rootTask.$source;
|
|
if(links){
|
|
for(var i=0; i < links.length; i++){
|
|
var link = this.getLink(links[i]);
|
|
if(this.isTaskExists(link.target)){
|
|
callback.call(this, this.getTask(link.target));
|
|
|
|
// iterate the whole branch, not only first-level dependencies
|
|
this.eachSuccessor(callback, link.target, traversedTasks);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
gantt.templates.task_class=function(start, end, task){
|
|
if(task.$virtual)
|
|
return "summary-bar";
|
|
};
|
|
ganttAttachEvents();
|
|
setChildTaskDisplay();
|
|
fetchRecords();
|
|
}
|
|
|
|
function ganttAttachEvents(){
|
|
|
|
gantt.templates.rightside_text = function(start, end, task){
|
|
return byId(gantt.serverList("users"), task.user_id);
|
|
};
|
|
|
|
if (schema.taskUser) {
|
|
gantt.attachEvent("onParse", function(){
|
|
var styleId = "dynamicGanttStyles";
|
|
var element = document.getElementById(styleId);
|
|
if(!element){
|
|
element = document.createElement("style");
|
|
element.id = styleId;
|
|
document.querySelector("head").appendChild(element);
|
|
}
|
|
var html = [".gantt_cell:nth-child(1) .gantt_tree_content{" +
|
|
" border-radius: 16px;" +
|
|
" width: 100%;" +
|
|
" height: 70%;" +
|
|
" margin: 5% 0;" +
|
|
" line-height: 230%;}"];
|
|
var resources = gantt.serverList("users");
|
|
|
|
resources.forEach(function(r){
|
|
html.push(".gantt_task_line.gantt_resource_" + r.key + "{" +
|
|
"background-color:"+r.backgroundColor+"; " +
|
|
"color:"+r.textColor+";" +
|
|
"}");
|
|
html.push(".gantt_row.gantt_resource_" + r.key + " .gantt_cell:nth-child(1) .gantt_tree_content{" +
|
|
"background-color:"+r.backgroundColor+"; " +
|
|
"color:"+r.textColor+";" +
|
|
"}");
|
|
});
|
|
element.innerHTML = html.join("");
|
|
});
|
|
}
|
|
|
|
gantt.attachEvent("onAfterTaskAdd", updateRecord);
|
|
gantt.attachEvent("onAfterTaskUpdate", updateRecord);
|
|
gantt.attachEvent("onAfterTaskDelete", scope.doRemove);
|
|
|
|
gantt.attachEvent("onAfterLinkAdd", updateLink);
|
|
gantt.attachEvent("onAfterLinkUpdate", updateLink);
|
|
gantt.attachEvent("onAfterLinkDelete", deleteLink);
|
|
|
|
gantt.attachEvent("onTaskCreated",function(task){
|
|
scope.showEditor(task, true);
|
|
return false;
|
|
});
|
|
|
|
gantt.attachEvent("onBeforeLightbox", function(id) {
|
|
var task = gantt.getTask(id);
|
|
scope.showEditor(task, false);
|
|
return false;
|
|
});
|
|
|
|
var diff = 0;
|
|
|
|
gantt.attachEvent("onBeforeTaskChanged", function(id, mode, originalTask){
|
|
var modes = gantt.config.drag_mode;
|
|
if(mode == modes.move ){
|
|
var modifiedTask = gantt.getTask(id);
|
|
diff = modifiedTask.start_date - originalTask.start_date;
|
|
}
|
|
return true;
|
|
});
|
|
|
|
//rounds positions of the child items to scale
|
|
gantt.attachEvent("onAfterTaskDrag", function(id, mode, e){
|
|
var modes = gantt.config.drag_mode;
|
|
if(mode == modes.move ){
|
|
gantt.eachSuccessor(function(child){
|
|
child.start_date = gantt.roundDate(new Date(child.start_date.valueOf() + diff));
|
|
child.end_date = gantt.calculateEndDate(child.start_date, child.duration);
|
|
gantt.updateTask(child.id);
|
|
},id );
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function fetchRecords() {
|
|
|
|
scope.fetchItems(function(records) {
|
|
var data = [];
|
|
var links = [];
|
|
_.each(records, function(rec) {
|
|
addData(data, rec);
|
|
addLinks(links, rec);
|
|
});
|
|
gantt.parse({ "data":data, "links":links });
|
|
});
|
|
|
|
}
|
|
|
|
function updateRecordItem(id,link,toRemove){
|
|
|
|
var linkMap = {
|
|
"0":"finishToStart",
|
|
"1":"startToStart",
|
|
"2":"finishToFinish",
|
|
"3":"startToFinish"
|
|
};
|
|
|
|
var linkField = schema[linkMap[link.type]];
|
|
var task = gantt.getTask(link.target);
|
|
var record = task.record;
|
|
|
|
if(record && linkField){
|
|
var endRecord = gantt.getTask(link.source).record;
|
|
if(endRecord){
|
|
var recordList = record[linkField];
|
|
recordList = recordList.filter(function(item, idx) {
|
|
return item.id != endRecord.id;
|
|
});
|
|
|
|
if(!toRemove){
|
|
recordList.push(endRecord);
|
|
}
|
|
record[linkField] = recordList;
|
|
task.record = record;
|
|
scope.doSave(task, updateTaskRecord);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function updateLink(id,link){
|
|
updateRecordItem(id, link, false);
|
|
}
|
|
|
|
function updateTaskRecord(task, rec){
|
|
task.record = rec;
|
|
}
|
|
|
|
function deleteLink(id, link){
|
|
updateRecordItem(id, link, true);
|
|
}
|
|
|
|
function updateRecord(id, item){
|
|
|
|
var record = item.record;
|
|
if(!record){ record = {}; }
|
|
|
|
var duration = item.duration || 1;
|
|
|
|
record[schema.taskStart] = item.start_date.toJSON();
|
|
record[firstField.name] = item.text;
|
|
|
|
if(schema.taskProgress){
|
|
record[schema.taskProgress] = item.progress*100;
|
|
}
|
|
if(schema.taskSequence){
|
|
record[schema.taskSequence] = item.order;
|
|
}
|
|
if(schema.taskDuration){
|
|
record[schema.taskDuration] = duration;
|
|
}
|
|
if(schema.taskEnd){
|
|
record[schema.taskEnd] = item.end_date.toJSON();
|
|
}
|
|
|
|
if(schema.taskParent && item.parent && !record[schema.taskParent]){
|
|
var parentTask = gantt.getTask(item.parent);
|
|
var parentRecord = parentTask.record;
|
|
if(parentRecord){
|
|
record[schema.taskParent] = parentRecord;
|
|
}
|
|
}
|
|
|
|
return scope.doSave(item, updateTaskRecord);
|
|
}
|
|
|
|
function addData(data, rec){
|
|
|
|
if(rec[schema.taskStart]){
|
|
var dict = {
|
|
id:rec.id,
|
|
open:true,
|
|
isNew:true
|
|
};
|
|
dict = updateData(dict, rec);
|
|
dict.isNew = false;
|
|
|
|
if(dict.start_date){
|
|
data.push(dict);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function addLinkDict(links, targetRecordId, sourceRecords, linkType){
|
|
|
|
_.each(sourceRecords, function(sourceRec){
|
|
links.push({
|
|
id:targetRecordId+"-"+sourceRec.id,
|
|
target:targetRecordId,
|
|
source:sourceRec.id,
|
|
type:linkType
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
function addLinks(links,record){
|
|
|
|
var linkMap = {
|
|
"finishToStart":"0",
|
|
"startToStart":"1",
|
|
"finishToFinish":"2",
|
|
"startToFinish":"3"
|
|
};
|
|
|
|
_.each(_.keys(linkMap), function(key) {
|
|
if(schema[key]){
|
|
addLinkDict(links, record.id, record[schema[key]], linkMap[key]);
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function updateTask(task, rec){
|
|
|
|
task = updateData(task, rec);
|
|
|
|
if(!task.isNew){
|
|
gantt.refreshTask(task.id);
|
|
}
|
|
task.isNew = false;
|
|
|
|
return task;
|
|
}
|
|
|
|
function updateData(task, rec){
|
|
|
|
task.record = rec;
|
|
|
|
var name = firstField.targetName ? rec[firstField.targetName] : rec[firstField.name];
|
|
task.text = "";
|
|
if(name){
|
|
task.text = name;
|
|
}
|
|
_.each(fields,function(field){
|
|
var val = rec[field.name];
|
|
if(_.isObject(val) && field.targetName){
|
|
val = val[field.targetName];
|
|
}
|
|
task[field.name] = val || "";
|
|
});
|
|
|
|
var endDate = null;
|
|
if(schema.taskEnd && rec[schema.taskEnd]){
|
|
endDate = moment(rec[schema.taskEnd]);
|
|
task.end_date = endDate.toDate();
|
|
if(task.isNew){
|
|
task.end_date = endDate.format("DD-MM-YYYY HH:mm:SS");
|
|
}
|
|
}
|
|
|
|
var startDate = moment(rec[schema.taskStart]);
|
|
if(task.isNew){
|
|
task.start_date = startDate.format("DD-MM-YYYY HH:mm:SS");
|
|
}
|
|
else{
|
|
task.start_date = startDate.toDate();
|
|
}
|
|
|
|
|
|
if(schema.taskDuration && rec[schema.taskDuration]){
|
|
task.duration = rec[schema.taskDuration];
|
|
}
|
|
else if(endDate){
|
|
task.duration = gantt.calculateDuration(startDate.toDate(), endDate);
|
|
}
|
|
else{
|
|
task.duration = "1";
|
|
}
|
|
|
|
if(!endDate){
|
|
task.end_date = gantt.calculateEndDate(startDate.toDate(), task.duration);
|
|
}
|
|
|
|
if(schema.taskProgress){
|
|
task.progress = rec[schema.taskProgress]/100;
|
|
}
|
|
|
|
if(schema.taskParent){
|
|
if(rec[schema.taskParent] && rec[schema.taskParent].id != task.id){
|
|
task.parent = rec[schema.taskParent].id;
|
|
}
|
|
else{
|
|
task.parent = 0;
|
|
}
|
|
}
|
|
|
|
if(schema.taskSequence){
|
|
task.sortorder = rec[schema.taskSequence];
|
|
}
|
|
|
|
if(schema.taskUser && rec[schema.taskUser]) {
|
|
task.user_id = rec[schema.taskUser].id;
|
|
if(!byId(gantt.serverList("users"), task.user_id)) {
|
|
gantt.serverList("users").push({key:task.user_id,
|
|
label:rec[schema.taskUser][fields[schema.taskUser].targetName],
|
|
backgroundColor: get_random_color(),
|
|
textColor:"#FFF"
|
|
});
|
|
}
|
|
}
|
|
|
|
return task;
|
|
|
|
}
|
|
|
|
function get_random_color() {
|
|
function c() {
|
|
var hex = Math.floor(Math.random()*256).toString(16);
|
|
return ("0"+String(hex)).substr(-2); // pad with zero
|
|
}
|
|
return "#"+c()+c()+c();
|
|
}
|
|
|
|
|
|
scope.onMode = function(name) {
|
|
setScaleConfig(name);
|
|
mode = name;
|
|
gantt.render();
|
|
};
|
|
|
|
scope.isMode = function(name) {
|
|
return mode === name;
|
|
};
|
|
|
|
scope.onRefresh = function () {
|
|
gantt.clearAll();
|
|
fetchRecords();
|
|
};
|
|
|
|
scope.onPrint = function () {
|
|
gantt.exportToPDF({
|
|
name: "Gantt.pdf",
|
|
callback: function(result){
|
|
window.open(result.url , '_self');
|
|
}});
|
|
};
|
|
|
|
scope.$on('$destroy', function() {
|
|
gantt.clearAll();
|
|
gantt.detachAllEvents();
|
|
});
|
|
|
|
scope.showEditor = function(task, isNew) {
|
|
var record = _.extend({}, task.record);
|
|
if (!editor) {
|
|
editor = ViewService.compile('<div ui-editor-popup></div>')(scope.$new());
|
|
editor.data('$target', element);
|
|
}
|
|
|
|
var popup = editor.isolateScope();
|
|
popup.setEditable(true);
|
|
|
|
if(isNew && schema.taskParent && task.parent && !record[schema.taskParent]){
|
|
var parentTask = gantt.getTask(task.parent);
|
|
var parentRecord = parentTask.record;
|
|
if(parentRecord){
|
|
record[schema.taskParent] = parentRecord;
|
|
}
|
|
}
|
|
|
|
popup.show(record, function(result) {
|
|
task.isNew = isNew;
|
|
task = updateTask(task, result);
|
|
if(isNew){
|
|
gantt.addTask(task);
|
|
}
|
|
else {
|
|
gantt.updateTask(task.id);
|
|
}
|
|
});
|
|
|
|
if (!record || !record.id) {
|
|
popup.waitForActions(function() {
|
|
popup.$broadcast("on:new");
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
return {
|
|
link:function(scope, element, attrs, controller) {
|
|
scope._viewPromise.then(function(){
|
|
link(scope, element, attrs, controller);
|
|
});
|
|
},
|
|
replace:true,
|
|
template:
|
|
'<div>'+
|
|
'<div class="gantt-main"></div>'+
|
|
'</div>'
|
|
};
|
|
}]);
|
|
|
|
})();
|