277 lines
8.5 KiB
JavaScript
277 lines
8.5 KiB
JavaScript
/* ===========================================================
|
|
* ScenarioDependencyInformer.js v1.0.0
|
|
* ===========================================================
|
|
* Copyright 2017 Prevu
|
|
* ========================================================== */
|
|
|
|
(function ($) {
|
|
|
|
"use strict"; // jshint ;_;
|
|
/* ScenarioDependencyInformer CLASS DEFINITION */
|
|
|
|
var ScenarioDependencyInformer = function (element, options) {
|
|
this.init(element, options);
|
|
};
|
|
|
|
ScenarioDependencyInformer.prototype = {
|
|
constructor: ScenarioDependencyInformer,
|
|
init: function (element, options) {
|
|
var plugin = this;
|
|
this.options = options;
|
|
this.$container = $(element);
|
|
|
|
if (!this.options.projectId && !this.options.DependencyData) {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: projectId not specified. Initialization finished');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Query data for widget
|
|
var promise = null;
|
|
if (typeof this.options.externalDataFunction === 'function') {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: query data via external function');
|
|
}
|
|
promise = this.options.externalDataFunction(this.options.projectId);
|
|
}
|
|
else {
|
|
if (this.options.dataUrl) {
|
|
promise = this.queryDataFromUrl(this.options.dataUrl, this.options.projectId);
|
|
}
|
|
else {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: No data source was specified, no data query was performed');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (promise) {
|
|
promise.then(function (data) {
|
|
// data loaded
|
|
plugin.processIncomingData(data);
|
|
},
|
|
function (data, status, errMessage) {
|
|
// loading failed
|
|
var message = "Failed to load project dependencies info";
|
|
var html = '<div style="color: red;"><i>' + message + '</i></div>';
|
|
plugin.$container.html(html);
|
|
});
|
|
}
|
|
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: initialized');
|
|
}
|
|
|
|
if (this.options.initCallback && (typeof this.options.initCallback === 'function')) {
|
|
this.options.initCallback();
|
|
}
|
|
},
|
|
show: function () {
|
|
if (!this.$container)
|
|
return;
|
|
|
|
var duration = this.options.animation ? 400 : 0;
|
|
$(this.$container).show({ duration: duration });
|
|
},
|
|
hide: function () {
|
|
if (!this.$container)
|
|
return;
|
|
|
|
var duration = this.options.animation ? 400 : 0;
|
|
$(this.$container).hide({ duration: duration });
|
|
},
|
|
queryDataFromUrl: function(url, projectId) {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: query data from server. Url: ' + url);
|
|
}
|
|
|
|
if (!url)
|
|
throw "ScenarioDependencyInformer: url for query data from server is empty";
|
|
|
|
if (!projectId)
|
|
throw "ScenarioDependencyInformer: project id to query data for, is empty";
|
|
|
|
var request = getAntiXSRFRequest(url);
|
|
request.method = 'GET';
|
|
request.data = {
|
|
id: projectId,
|
|
sessionKey: C_EMPTY_GUID,
|
|
};
|
|
|
|
var promise = $.ajax(request);
|
|
return promise;
|
|
},
|
|
processIncomingData: function (data) {
|
|
if (!data) {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: incoming data is empty');
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!$.isArray(data)) {
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: incoming data has invalid format');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Indexing incoming data by datatype
|
|
var plugin = this;
|
|
var dataIndexed = [];
|
|
|
|
for (var index = 0; index < data.length; index++) {
|
|
var dataItem = data[index];
|
|
var dataType = dataItem && (dataItem.Type !== undefined) ? dataItem.Type : undefined;
|
|
|
|
if ($.isNumeric(dataType)) {
|
|
var dataTypeTyped = Number(dataType);
|
|
var indexedDataItem = {};
|
|
indexedDataItem.data = dataItem;
|
|
|
|
switch (dataTypeTyped) {
|
|
case 0:
|
|
indexedDataItem.message = this.options.finishConstraintMessageTemplate;
|
|
indexedDataItem.dateMs = dataItem.dtStartDate;
|
|
indexedDataItem.dateText = dataItem.StartDate;
|
|
indexedDataItem.scenarioDatePropName = "StartDate";
|
|
indexedDataItem.scenarioDatePrefix = "starts at";
|
|
indexedDataItem.tooltipHeader = "Dependency for:";
|
|
dataIndexed[String(dataTypeTyped)] = indexedDataItem;
|
|
break;
|
|
case 1:
|
|
indexedDataItem.message = this.options.startConstraintMessageTemplate;
|
|
indexedDataItem.dateMs = dataItem.dtEndDate;
|
|
indexedDataItem.dateText = dataItem.EndDate;
|
|
indexedDataItem.scenarioDatePropName = "EndDate";
|
|
indexedDataItem.scenarioDatePrefix = "ends at";
|
|
indexedDataItem.tooltipHeader = "Dependent on:";
|
|
dataIndexed[String(dataTypeTyped)] = indexedDataItem;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var htmlRow;
|
|
var resultHtml = "";
|
|
|
|
for (var dataType = 1; dataType >= 0; dataType--) {
|
|
if (String(dataType) in dataIndexed) {
|
|
htmlRow = "";
|
|
var dataItem = dataIndexed[String(dataType)];
|
|
|
|
if (dataItem.message) {
|
|
var formattedMessage = dataItem.message.replace(/\{0\}/g, dataItem.dateText);
|
|
htmlRow = '<i>' + formattedMessage + '</i>';
|
|
}
|
|
|
|
if (this.options.displayIcons) {
|
|
if (htmlRow) {
|
|
htmlRow += ' ';
|
|
}
|
|
htmlRow += '<i class="fa fa-info-circle fa-fw"></i>';
|
|
|
|
if (this.options.tooltips) {
|
|
var tooltipContent = "";
|
|
|
|
if (dataItem.data.Items && $.isArray(dataItem.data.Items) && dataItem.data.Items.length) {
|
|
for (var pIndex = 0; pIndex < dataItem.data.Items.length; pIndex++) {
|
|
var projectInfo = dataItem.data.Items[pIndex];
|
|
var projectName = projectInfo.Level === 0 ? projectInfo.Name : '<i>' + projectInfo.Name + '</i>';
|
|
var projectTooltipContent = '<br>' + projectName;
|
|
|
|
if (projectInfo[dataItem.scenarioDatePropName]) {
|
|
var formattedProjectDate = DateTimeConverter.msFormatAsUtcString(projectInfo[dataItem.scenarioDatePropName]);
|
|
projectTooltipContent += projectInfo.Level === 0 ?
|
|
' (' + dataItem.scenarioDatePrefix + ' ' + formattedProjectDate + ')' :
|
|
' (<i>' + dataItem.scenarioDatePrefix + ' ' + formattedProjectDate + '</i>)';
|
|
}
|
|
|
|
tooltipContent += projectTooltipContent;
|
|
}
|
|
tooltipContent = dataItem.tooltipHeader + tooltipContent;
|
|
}
|
|
|
|
if (tooltipContent) {
|
|
htmlRow += ('<div class="tooltip-content">' + tooltipContent + '</div>');
|
|
}
|
|
}
|
|
}
|
|
resultHtml += ('<div' + (this.options.tooltips ? ' data-toggle="tooltip" data-placement="bottom">' : '>') + htmlRow + '</div>');
|
|
}
|
|
}
|
|
|
|
this.$container.html(resultHtml);
|
|
|
|
if (resultHtml && this.options.tooltips) {
|
|
var tooltipedDivs = this.$container.find('[data-toggle="tooltip"]');
|
|
$.each(tooltipedDivs, function (index, elem) {
|
|
$(elem).tooltip({
|
|
title: plugin.getTooltipContent,
|
|
html: true,
|
|
container: elem,
|
|
});
|
|
});
|
|
}
|
|
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: incoming data processed and published');
|
|
}
|
|
|
|
},
|
|
getTooltipContent: function (elem, data) {
|
|
var result = "No data available";
|
|
var tooltipContainter = $(this).find("div.tooltip-content");
|
|
|
|
if (tooltipContainter) {
|
|
var content = tooltipContainter.html();
|
|
if (content) {
|
|
result = content;
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
destroy: function () {
|
|
var e = $.Event('destroy');
|
|
this.$container.trigger(e);
|
|
|
|
if (e.isDefaultPrevented())
|
|
return;
|
|
|
|
if (this.options.debug) {
|
|
console.log('ScenarioDependencyInformer: destroyed');
|
|
}
|
|
},
|
|
};
|
|
/* ==================================================
|
|
* SCENARIO DEPENDENCY INFORMER PLUGIN DEFINITION
|
|
* ================================================== */
|
|
|
|
$.fn.scenarioDependencyInformer = function (option, args) {
|
|
return this.each(function () {
|
|
var $this = $(this),
|
|
data = $this.data('scenarioDependencyInformer'),
|
|
options = $.extend({}, $.fn.scenarioDependencyInformer.defaults, $this.data(), typeof option == 'object' && option);
|
|
|
|
if (!data) $this.data('scenarioDependencyInformer', (data = new ScenarioDependencyInformer(this, options)));
|
|
if (typeof option == 'string')
|
|
data[option].apply(data, [].concat(args));
|
|
});
|
|
};
|
|
$.fn.scenarioDependencyInformer.defaults = {
|
|
projectId: undefined,
|
|
dataUrl: undefined,
|
|
externalDataFunction: undefined,
|
|
startConstraintMessageTemplate: "Project must start after {0}",
|
|
finishConstraintMessageTemplate: "Project must end by {0}",
|
|
displayIcons: true,
|
|
tooltips: true,
|
|
animation: true,
|
|
initCallback: null,
|
|
debug: false
|
|
};
|
|
|
|
$.fn.scenarioDependencyInformer.Constructor = ScenarioDependencyInformer;
|
|
|
|
}(jQuery)); |