/* =========================================================== * 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 = '
' + message + '
'; 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 = '' + formattedMessage + ''; } if (this.options.displayIcons) { if (htmlRow) { htmlRow += ' '; } htmlRow += ''; 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 : '' + projectInfo.Name + ''; var projectTooltipContent = '
' + projectName; if (projectInfo[dataItem.scenarioDatePropName]) { var formattedProjectDate = DateTimeConverter.msFormatAsUtcString(projectInfo[dataItem.scenarioDatePropName]); projectTooltipContent += projectInfo.Level === 0 ? ' (' + dataItem.scenarioDatePrefix + ' ' + formattedProjectDate + ')' : ' (' + dataItem.scenarioDatePrefix + ' ' + formattedProjectDate + ')'; } tooltipContent += projectTooltipContent; } tooltipContent = dataItem.tooltipHeader + tooltipContent; } if (tooltipContent) { htmlRow += ('
' + tooltipContent + '
'); } } } resultHtml += ('' : '>') + htmlRow + ''); } } 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));