965 lines
38 KiB
Plaintext
965 lines
38 KiB
Plaintext
@using EnVisage.Code
|
|
@using EnVisage.Models
|
|
@model ForecastDashboardOptionsModel
|
|
@{
|
|
ViewBag.Title = "Dashboard";
|
|
var allScenarioGroups = Utils.GetScenarioGroup().Where(item => !item.Text.Equals("Default"));
|
|
}
|
|
|
|
<!-- Get jQuery from Google CDN -->
|
|
<!--[if !IE]> -->
|
|
<script type="text/javascript"> window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.js">' + "<" + "/script>"); </script>
|
|
<!--[endif]-->
|
|
<!--[if lte IE 9]>
|
|
<script type="text/javascript"> window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">'+"<"+"/script>"); </script>
|
|
<![endif]-->
|
|
@*//TODO: use bundle. add and deploy minified fiels for this bundle*@
|
|
@*@Scripts.Render("~/bundles/kendo-grid")*@
|
|
@Html.RenderScript(Url.Content("~/Scripts/Kendo/kendo.all.js"))
|
|
@Html.RenderScript(Url.Content("~/Scripts/Kendo/kendo.aspnetmvc.js"))
|
|
|
|
@section Scripts
|
|
{
|
|
@Html.RenderScript("~/Scripts/amCharts/amCharts.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/pie.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/serial.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/xy.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/themes/light.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/plugins/responsive/responsive.js")
|
|
@Html.RenderScript("~/Scripts/amCharts/custom.js")
|
|
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.app.init.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.storage.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.app.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.stacked.js")
|
|
@*@Html.RenderScript("~/Scripts/Dashboard/pv.chart.donut.js")*@
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.bubble.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.bar1.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.bar2.js")
|
|
@Html.RenderScript("~/Scripts/Dashboard/pv.chart.bar3.js")
|
|
@Html.RenderScript("~/Scripts/bootstrap-modalmanager.js")
|
|
@Html.RenderScript("~/Scripts/bootstrap-modal.js")
|
|
@Html.RenderScript("~/Scripts/forecastDashboardScripts.js")
|
|
@Html.RenderScript("~/Scripts/magnifyChart.js")
|
|
@Html.RenderScript("~/Scripts/Plugins/Optimuse.js")
|
|
@Html.RenderScript("~/Scripts/Plugins/DonutChart.js")
|
|
|
|
<script>
|
|
|
|
var _filterIdsCollection = ["s2id_ProjectTypes", "s2id_ProjectStatuses", "s2id_filterTeam", "s2id_StrategicGoals", "s2id_filterTag"];
|
|
|
|
|
|
function dashboardPrint(beforePrintBool) {
|
|
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
|
|
var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
|
|
|
|
var donut = $("#chartDonut1").data("donutChart");
|
|
if(!isChrome && !isSafari){
|
|
donut.innerDonut.div.style.width = beforePrintBool ? "300px" : "100%";
|
|
}
|
|
donut.innerDonut.validateNow();
|
|
|
|
if(!isChrome && !isSafari){
|
|
donut.outerDonut.div.style.width = beforePrintBool ? "300px" : "100%";
|
|
}
|
|
donut.outerDonut.validateNow();
|
|
|
|
var chartStacked = findChart("chartStacked1");
|
|
if(!isChrome && !isSafari){
|
|
chartStacked.div.style.width = beforePrintBool ? "300px" : "100%";
|
|
}
|
|
chartStacked.validateNow();
|
|
|
|
var chartBubble = findChart("chartBubble1");
|
|
if(!isChrome && !isSafari){
|
|
chartBubble.div.style.width = beforePrintBool ? "600px" : "100%";
|
|
}
|
|
chartBubble.validateNow();
|
|
|
|
visibleFilters(_filterIdsCollection, beforePrintBool);
|
|
}
|
|
|
|
|
|
function visibleFilters(filterIdsCollection, beforePrintBool) {
|
|
for (var i = 0; i < filterIdsCollection.length; i++) {
|
|
if ($("#" + filterIdsCollection[i]).select2('val').length == 0) {
|
|
if (beforePrintBool) {
|
|
$("#" + filterIdsCollection[i]).hide();
|
|
$("#" + filterIdsCollection[i]).prev("label").hide();
|
|
} else {
|
|
$("#" + filterIdsCollection[i]).show();
|
|
$("#" + filterIdsCollection[i]).prev("label").show();
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
function beforePrint () {
|
|
console.log('before print');
|
|
dashboardPrint(true);
|
|
}
|
|
function afterPrint() {
|
|
console.log('after print');
|
|
dashboardPrint(false);
|
|
}
|
|
window.onbeforeprint = beforePrint;
|
|
window.onafterprint = afterPrint;
|
|
|
|
var printHandler = function(mql) {
|
|
if(mql.matches) {
|
|
beforePrint();
|
|
} else {
|
|
afterPrint();
|
|
}
|
|
};
|
|
|
|
var mql = window.matchMedia('print');
|
|
mql.addListener(printHandler);
|
|
|
|
|
|
|
|
|
|
$("div#main-wrapper").attr("data-section", "fullPageDashboard");
|
|
|
|
_dataSectionName = loadForecastDashboardPreferences();
|
|
if (_dataSectionName && (_dataSectionName.length > 0)) {
|
|
restorePreferences(_dataSectionName, _pagePreferences);
|
|
}
|
|
});
|
|
|
|
$(document).on("click", "#donut-total", function (e) {
|
|
e.preventDefault();
|
|
if (donutData != null) {
|
|
renderDonut(donutData);
|
|
//for (var i = 0; i < projectsFilterArray.length; i++) {
|
|
// removeArrayFromFilter('s2id_ProjectTypes', projectsFilterArray[i]);
|
|
//}
|
|
$('#s2id_ProjectTypes').select2('val', []);
|
|
projectsFilterArray = [];
|
|
|
|
//for (var i = 0; i < goalsFilterArray.length; i++) {
|
|
// removeArrayFromFilter('s2id_StrategicGoals', goalsFilterArray[i]);
|
|
//}
|
|
$('#s2id_StrategicGoals').select2('val', []);
|
|
goalsFilterArray = [];
|
|
}
|
|
applyForecastDashboardFilter();
|
|
});
|
|
</script>
|
|
}
|
|
|
|
@section Stylesheets
|
|
{
|
|
@Html.RenderStyle(Url.Content("~/Content/stylesheets/kendo/web/kendo.common-bootstrap.css"))
|
|
@Html.RenderStyle(Url.Content("~/Content/stylesheets/kendo/web/kendo.bootstrap.css"))
|
|
@Html.RenderStyle(Url.Content("~/Content/stylesheets/xeditable.css"))
|
|
@Html.RenderStyle(Url.Content("~/Content/stylesheets/magnifyChart.css"))
|
|
@Html.RenderStyle(Url.Content("~/Content/stylesheets/amCharts/pv.amCharts.css"))
|
|
@Html.RenderStyle("~/Content/stylesheets/bootstrap-modal-bs3patch.css")
|
|
@Html.RenderStyle("~/Content/stylesheets/bootstrap-modal.css")
|
|
}
|
|
|
|
<style>
|
|
.pv-menu {
|
|
text-align: right;
|
|
}
|
|
|
|
.pv-menu .btn-group button {
|
|
background: transparent;
|
|
border: none;
|
|
font-size: 24px;
|
|
}
|
|
|
|
#cardTotalNumberOfProjects .switcher {
|
|
width: auto !important;
|
|
}
|
|
|
|
.filter-panel .panel-body {
|
|
padding-top: 5px !important;
|
|
padding-bottom: 5px !important;
|
|
}
|
|
|
|
.k-grid-norecords-template {
|
|
width: auto !important;
|
|
}
|
|
|
|
#barChartsContainer .loadRotator {
|
|
position: absolute;
|
|
margin: auto;
|
|
left: 0;
|
|
top: 75px;
|
|
bottom: 0;
|
|
right: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 10;
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
#barChartsContainer .loadRotator span {
|
|
top: 50%;
|
|
left: 100px;
|
|
position: absolute;
|
|
}
|
|
|
|
.donutChartDiv {
|
|
width: 100%;
|
|
height: 300px;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
|
|
table.donut-legend {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
.donut-legend-item {
|
|
font-size: 12px;
|
|
width: 50%;
|
|
padding-bottom: 2px;
|
|
padding-right: 7px;
|
|
padding-left: 10px;
|
|
/*cursor: pointer;*/
|
|
}
|
|
|
|
.donut-legend-indicator {
|
|
width: 10px;
|
|
height: 12px;
|
|
background-color: red;
|
|
float: left;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.donut-legend-item-label {
|
|
margin-left: 3px;
|
|
}
|
|
|
|
.amcharts-balloon-div {
|
|
z-index: 100 !important;
|
|
}
|
|
</style>
|
|
|
|
@section pagemenu
|
|
{
|
|
@Html.Partial("_pageMenu")
|
|
}
|
|
@Html.Partial("_filterPanel", Model)
|
|
|
|
<div class="pv-noscroll table-light table-responsive dashboard">
|
|
|
|
<div class="row pv-row">
|
|
<div class="pv-back-arrow sprite" onclick="widgetToRestore();"></div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-height-first-row dashboard-widget-non-static-width-big" id="cardStacked1">
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardStacked.cshtml"); }
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-height-first-row dashboard-widget-static-width" id="cardOpt1">
|
|
@*<div class="pv-menu k-content">
|
|
<div class="btn-group pull-right">
|
|
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<i class="fa fa-ellipsis-h"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<input type="checkbox" data-key="optimuse-isUOMHours" name="optimuse-isUOMHours" id="optimuse-isUOMHours" class="switcher px"/>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>*@
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-height dashboard-widget-non-static-width-midle" id="cardDonut1">
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardDonut2.cshtml"); }
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-height dashboard-widget-non-static-width-midle" id="cardSummary1">
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardSummary.cshtml"); }
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-static-width" id="cardBar1">
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardBar.cshtml"); }
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-height dashboard-widget-non-static-width-big minimized" id="cardBubble1">
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardBubble.cshtml"); }
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-static-width pv-menu-grid" id="cardTotalNumberOfProjects" data-fullscreen-only="true" style="display: none;">
|
|
@Html.Partial("_forecastGridWidget")
|
|
</div>
|
|
|
|
<div class="panel col-md-4 pv-card dashboard-widget-static-width" id="cardOptimuse" data-fullscreen-only="true" style="display: none; height:100%;">
|
|
<div class="pv-mock-opt" style="margin-bottom: -55px;" id="magnify-actual-full-screen"><div style="padding-left: 20px;">Actual</div></div>
|
|
<div style="height: 300px;" class="pv-chart" id="chart-actual-full-screen"></div>
|
|
<br />
|
|
<div class="pv-mock-opt" style="margin-bottom: -55px;" id="magnify-planned-full-screen"><div style="padding-left: 20px;">Planned</div></div>
|
|
<div style="height: 300px;" class="pv-chart" id="chart-planned-full-screen"></div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
@{ Html.RenderPartial("~/Views/Shared/amCharts/_cardDonut2_InitScripts.cshtml"); }
|
|
|
|
<script>
|
|
var _dataSectionName;
|
|
var _pagePreferences = [];
|
|
var _scenDetailsUrl = '@Url.Action("Details", "Scenarios", new { @id = "_rplcmnt_", @backUrl = "/", @backName = "dashboard" })';
|
|
var _allScenarioGroups = @Html.Raw(Json.Encode(allScenarioGroups.ToArray()));
|
|
var liHeight = 30;
|
|
|
|
init.push(function () {
|
|
pv.chart.menu();
|
|
$(".fcboard-criteria-select2").select2();
|
|
createDatePickers();
|
|
initSwitchers();
|
|
loadOptimuseData();
|
|
|
|
$(window).scroll(function () {
|
|
$('.menuGroup').removeClass('open');
|
|
if (!!currentGridName){
|
|
hideRedundantPopovers($('#' + currentGridName), null);
|
|
}
|
|
});
|
|
|
|
$('.table-striped').scroll(function () {
|
|
$('.menuGroup').removeClass('open');
|
|
if (!!currentGridName){
|
|
hideRedundantPopovers($('#' + currentGridName), null);
|
|
}
|
|
});
|
|
$(document).click(function (event) {
|
|
$('.menuGroup').removeClass('open');
|
|
if (!$(event.target).is('[data-toggled="popover"]')){
|
|
if (!!currentGridName){
|
|
hideRedundantPopovers($('#' + currentGridName), null);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
function initSwitchers() {
|
|
$('#optimuse-isUOMHours').switcher({
|
|
on_state_content: '# Hours',
|
|
off_state_content: '# Resources'
|
|
});
|
|
$('#optimuse-isUOMHours').on('click', function () {
|
|
$('#cardOpt1').optimuse('showPreloader');
|
|
$('#cardOpt1').optimuse('changeUOMMode', $(this).is(':checked'));
|
|
$('#cardOpt1').optimuse('hidePreloader');
|
|
$('#cardOpt1').optimuse('mouveBarTitles');
|
|
saveForecastDashboardPreferences();
|
|
});
|
|
}
|
|
|
|
function showChartPreLoader(chartId) {
|
|
$("#" + chartId).html("<div class='loadRotator'>\
|
|
<span>\
|
|
<img class='valign-middle' src='@Url.Content("~/Content/images/loadFA.gif")' /> loading...\
|
|
</span>\
|
|
</div>");
|
|
}
|
|
|
|
function loadOptimuseData(filterData) {
|
|
var isUOMHours = $('#uomModeForecast').is(':checked');
|
|
|
|
filterData = filterData || getFilterDataObject();
|
|
filterData["IsLaborMode"] = true;
|
|
filterData["ChartType"] = dashboardChartType.projectsByStatus | dashboardChartType.optimuse;
|
|
|
|
showChartPreLoader("chartStacked1");
|
|
$('#cardOpt1').optimuse({ isUOMHours: isUOMHours, data: null });
|
|
$('#cardOpt1').optimuse('showPreloader');
|
|
|
|
$.post('@Url.Action("GetGraphData", "ForecastDashboard")', filterData, function (data, textStatus, jqXHR) {
|
|
projectsByStatusSetData(data["ProjectsByStatus"]);
|
|
projectsByStatusShowChartData();
|
|
|
|
$('#cardOpt1').optimuse('setData', data["Optimuse"]);
|
|
$('#cardOpt1').optimuse('hidePreloader');
|
|
$('#cardOpt1').optimuse('mouveBarTitles');
|
|
|
|
var percentOverAllocation = $('#cardOpt1').optimuse('getOverAllocationPercent') || 0;
|
|
var percentUnderAllocation = $('#cardOpt1').optimuse('getUnderAllocationPercent') || 0;
|
|
|
|
$('#percentOverAllocation').children('a').text(percentOverAllocation + '%').show();
|
|
$('#percentOverAllocation').children("img").remove();
|
|
|
|
$('#percentUnderAllocation').children('a').text(percentUnderAllocation + '%').show();
|
|
$('#percentUnderAllocation').children("img").remove();
|
|
|
|
var fullScreenTab = pv.storage.getSession('pv.card.id');
|
|
if (fullScreenTab === 'cardOptimuse' && $('#' + fullScreenTab).is(':visible')) {
|
|
showResourceUsageGraphs();
|
|
}
|
|
});
|
|
};
|
|
|
|
function getColorFromPalette(idx) {
|
|
var palette = PixelAdmin.settings.consts.COLORS;
|
|
if (palette.length < 1)
|
|
return null;
|
|
if (palette.length == 1)
|
|
return palette[0];
|
|
return palette[idx % (palette.length - 1)];
|
|
}
|
|
|
|
function saveForecastDashboardPreferences() {
|
|
var section = getDataSection($('#criteria-container'));
|
|
var prefs = collectPreferences(section);
|
|
saveUserPagePreferences(prefs, section);
|
|
}
|
|
|
|
function loadForecastDashboardPreferences() {
|
|
var section = getDataSection($('#criteria-container'));
|
|
_pagePreferences = loadUserPagePreferences(section);
|
|
return section;
|
|
}
|
|
|
|
function saveGridState(gridName) {
|
|
var grid = getGrid(gridName),
|
|
dataSource = grid.dataSource,
|
|
options = grid.getOptions();
|
|
|
|
//var fieldsToDisplay = grid.fieldsToDisplay;
|
|
//var gridColumns = grid.columns.filter(function(col, index) {
|
|
// var matchedFields = fieldsToDisplay.filter(function (field) {
|
|
// return col.field == field;
|
|
// });
|
|
// return matchedFields.length > 0;
|
|
//});
|
|
|
|
var state = {
|
|
columns: $.map(grid.columns, function (col, index) {
|
|
return {
|
|
"field": col.field,
|
|
"hidden": col.hidden,
|
|
"width": col.width
|
|
};
|
|
}),
|
|
pageSize: dataSource.pageSize(),
|
|
sort: dataSource.sort(),
|
|
group: $.map(dataSource.group() || [], function (group, index) {
|
|
return {
|
|
dir: group.dir,
|
|
field: group.field
|
|
};
|
|
})
|
|
};
|
|
|
|
var prefs = [{
|
|
Key: "Grid_" + gridName,
|
|
Value: kendo.stringify(state)
|
|
}];
|
|
prefs.push({
|
|
Key: "PerformanceMode",
|
|
Value: kendo.stringify($("#gridPerformanceMode").prop("checked"))
|
|
});
|
|
|
|
saveUserPagePreferences(prefs, gridName);
|
|
}
|
|
|
|
function getGridState(gridName) {
|
|
var grid = getGrid(gridName);
|
|
|
|
var prefs = loadUserPagePreferences(gridName);
|
|
if (!prefs || !prefs.length) {
|
|
return null;
|
|
}
|
|
var gridState = getGridPreferncesItem("Grid_" + gridName, prefs);
|
|
var performanceMode = getGridPreferncesItem("PerformanceMode", prefs);
|
|
gridState.performanceMode = (!performanceMode) || performanceMode;
|
|
|
|
return gridState;
|
|
}
|
|
|
|
function getGridPreferncesItem(key, prefs) {
|
|
try {
|
|
var gridPreferences = prefs.filter(function (item, index) {
|
|
return item.Key == key;
|
|
});
|
|
if (gridPreferences.length) {
|
|
return JSON.parse(gridPreferences[0].Value);
|
|
}
|
|
}
|
|
catch(e) {
|
|
console.log('Error reading grid prefernce: ' + key);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
function getFilterParams(options) {
|
|
var filter = getFilterDataObject();
|
|
filter["FilterGroupByTeam"] = options && options.group && $.grep(options.group, function(e){return e.field == 'TeamName'}).length > 0;
|
|
|
|
//TODO: other way to extend filter options for specific grid
|
|
if(options) {
|
|
if(currentGridName == "NetImpact") filter["HasProjectNetImpact"] = true;
|
|
if(currentGridName == "TotalProjectedRevenue") filter["HasProjectedRevenue"] = true;
|
|
if(currentGridName == "TotalProjectedSavings") filter["HasCostSavings"] = true;
|
|
if(currentGridName == "TotalProjectCost") filter["HasProjectCost"] = true;
|
|
}
|
|
return { forecastFilter: filter };
|
|
}
|
|
|
|
function getGrid(gridName) {
|
|
return $("#" + gridName).data("kendoGrid");
|
|
}
|
|
|
|
function ToggleStatus(scenarioId, control) {
|
|
if (scenarioId == null || scenarioId == "")
|
|
return "";
|
|
var url = "@Url.Action("CheckIfActive", "ForecastDashboard")";
|
|
var request = {
|
|
'scenarioId': scenarioId
|
|
};
|
|
$.get(url, request, function (data) {
|
|
if (data == null || data == "") {
|
|
ToggleStatusConfirmed(scenarioId, control);
|
|
return '';
|
|
} else {
|
|
bootbox.confirm({
|
|
message: "There is an active scenario for this project already. Are you sure you want to activate this scenario instead of active one?",
|
|
callback: function (result) {
|
|
if (result) {
|
|
ToggleStatusConfirmed(scenarioId, control);
|
|
}
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function ToggleStatusConfirmed(scenarioId, control) {
|
|
if (scenarioId == null || scenarioId == "")
|
|
return "";
|
|
var url = "@Url.Action("ToggleStatus", "ForecastDashboard")";
|
|
var request = {
|
|
'scenarioId': scenarioId
|
|
};
|
|
$.get(url, request, function (data) {
|
|
if (typeof LoadGraphData === 'function')
|
|
LoadGraphData();
|
|
if (typeof LoadPieData === 'function')
|
|
LoadPieData();
|
|
if(currentGridName) {
|
|
getGrid(currentGridName).dataSource.read();
|
|
}
|
|
});
|
|
return '';
|
|
}
|
|
|
|
function onMenuItemClick(e, element) {
|
|
if ($(element).hasClass('dropdown-menu-form')) {
|
|
e.stopPropagation();
|
|
}
|
|
if (e.target.className != 'hide' && e.target.type == 'checkbox') {
|
|
var li = $(e.target).parent()[0];
|
|
var scenarioId = li.getAttribute('data-scenarioid');
|
|
var groupId = li.getAttribute('data-groupid');
|
|
CopyToGroup(scenarioId, groupId, $(li));
|
|
}
|
|
}
|
|
|
|
function CopyToGroup(scenarioId, groupId, element) {
|
|
$(element).children('input[type="checkbox"]').addClass('hide');
|
|
$(element).children('span.glyphicon').removeClass('hide');
|
|
var isChecked = $(element).children('input[type="hidden"]').val() == 'checked';
|
|
var url = '';
|
|
if (!isChecked)
|
|
url = "@Url.Action("CopyScenarioToGroup", "ForecastDashboard")";
|
|
else
|
|
url = "@Url.Action("ExtractFromGroup", "ForecastDashboard")";
|
|
var request = {
|
|
'scenarioId': scenarioId,
|
|
'groupId': groupId
|
|
};
|
|
$.post(url, request, function (data) {
|
|
var result = data;
|
|
if (data.Status == 'Ok') {
|
|
$(element).children('input[type="hidden"]').val(isChecked ? "unchecked" : "checked");
|
|
} else if (data.Status == 'Error') { // Show error message
|
|
showErrorModal('An error occurred while try to change scenario group.', data.ErrorMsg);
|
|
console.log(data.ErrorDetails);
|
|
}
|
|
$(element).children('span.glyphicon').addClass('hide');
|
|
$(element).children('input[type="checkbox"]').removeClass('hide');
|
|
});
|
|
}
|
|
|
|
function dropDownInsideClick(event) {
|
|
if (!event)
|
|
event = window.event;
|
|
|
|
var container = null, button = null;
|
|
if ($(event.target).hasClass('dropdown-menu'))
|
|
container = $(event.target);
|
|
else {
|
|
button = $(event.target);
|
|
container = button.closest('.dropdown-menu');
|
|
}
|
|
hideRedundantPopovers(container, button);
|
|
|
|
if (event.stopPropagation)
|
|
event.stopPropagation();
|
|
else
|
|
window.event.cancelBubble = true;
|
|
}
|
|
|
|
function dropDownFixPositionCalendar(button, dropdown) {
|
|
setDropdownProps(button, dropdown, liHeight);
|
|
if (!!currentGridName){
|
|
hideRedundantPopovers($('#' + currentGridName), null);
|
|
}
|
|
}
|
|
|
|
function scenarioNameTemplate(dataItem) {
|
|
//var link = "<a href=\"" + _scenDetailsUrl.replace("_rplcmnt_", dataItem.Id) + "\">" + dataItem.Name + "</a>";
|
|
var strA = '<div class="scenario-name" data-value="' + dataItem.Name + '"><a id="aN__rplcmnt_" onclick="return CheckLock(this.id, \'Scenario\', \'_rplcmnt_\')" class="popover-warning popover-dark" href="' + _scenDetailsUrl + '">' + dataItem.Name + '</a></div>';
|
|
if (dataItem.InactiveCount > 0) {
|
|
strA += '<div class="dropdown menuGroup " style="float:right;">' +
|
|
'<button type="button" title="Menu" style="margin-bottom:0px !important;" class="btn btn-xs dropdown-toggle" data-toggle="dropdown" onclick=\'dropDownFixPositionCalendar($(this), $(this).parent().find(".dropdown-menu"));\'><i class="fa fa-caret-down"></i></button>' +
|
|
'<ul id="ddm_' + dataItem.Id + '" class="dropdown-menu dropdown-menu-form dropdown-menu-right dropdown-menu-scroll-auto lioverflowh" style="text-align:left;padding:4px 0px!important;width:220px;overflow-x: hidden;" onclick="dropDownInsideClick(event);">';
|
|
$.map(dataItem.InactiveScenarios, function (value, key) {
|
|
if (key.length > 30)
|
|
strA += '<li><div style="-ms-text-overflow: ellipsis; -o-text-overflow: ellipsis; text-overflow: ellipsis; overflow: hidden; max-width: 150px; float: left; padding-left: 15px;"><span title="' + value + '">' + value + '</span></div>' +
|
|
'<div style="float: right;padding-right: 15px;"><a data-toggle="popover" title="Activate" onclick="ToggleStatus(\'' + key + '\', this)" class="btn btn-xs btn-primary popover-warning popover-dark" ><i class="fa fa-check-circle-o not-active"></i></a></div></li>';
|
|
});
|
|
strA += '</ul></div>';
|
|
}
|
|
return strA.replace(/_rplcmnt_/g, dataItem.Id);
|
|
}
|
|
|
|
function scenarioStatusTemplate(dataItem) {
|
|
var cellhtml = "";
|
|
var mode = "main";
|
|
if (dataItem.ScenarioStatus != null) {
|
|
var options = "";
|
|
if (mode == "main") {
|
|
for (i = 0; i < _allScenarioGroups.length; i++) {
|
|
var scenarioGroupId = _allScenarioGroups[i].Value;
|
|
var scenarioGroupName = _allScenarioGroups[i].Text;
|
|
var isFound = false;
|
|
for (j = 0; j < dataItem.Groups.length; j++) {
|
|
if (scenarioGroupId == dataItem.Groups[j].substr(dataItem.Groups[j].lastIndexOf(">") + 1)) {
|
|
isFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
options += "<li data-scenarioId='" + dataItem.Id + "' data-groupId='" + scenarioGroupId + "'>" +
|
|
"<input type='checkbox' style='margin-right: 5px;' id='" + dataItem.Id + '_' + scenarioGroupId + "' ";
|
|
options += isFound ? "checked" : "";
|
|
options += "/><input type='hidden' value='";
|
|
options += isFound ? "checked" : "unchecked";
|
|
options += "'/><span class='glyphicon glyphicon-refresh glyphicon-refresh-animate hide'></span><label for='" + dataItem.Id + '_' + scenarioGroupId + "'>" + scenarioGroupName + "</label></li>";
|
|
}
|
|
|
|
if (options.length > 0) {
|
|
options = "<div class=\"btn-group dropdown scenarioGroupDropdown\" id=\"copyto_" + dataItem.Id + "\">" +
|
|
"<button type='button' class='btn btn-xs dropdown-toggle dropdown-fix-pos' data-toggle='dropdown'>Groups <i class='fa fa-caret-down'></i></button>" +
|
|
"<ul class='dropdown-menu dropdown-menu-form dropdown-menu-right' role='menu' onclick='onMenuItemClick(event, $(this))'>" + options + "</ul>" +
|
|
"</div>";
|
|
}
|
|
}
|
|
|
|
cellhtml = ((dataItem.ScenarioStatus == 1) ? "<a class=\"btn btn-xs btn-warning popover-warning popover-dark\" id=\"" + dataItem.Id + "\" onclick=\"if(CheckLock(this.id, 'Scenario', '" + dataItem.Id + "')) {ToggleStatus('" + dataItem.Id + "', this);}\" title=\"Deactivate\" data-toggle=\"popover\" data-placement=\"left\"><i class=\"fa fa-times-circle-o\"></i></a>" : "<a class=\"btn btn-xs btn-primary popover-warning popover-dark\" id=\"" + dataItem.Id + "\" onclick=\"if(CheckLock(this.id, 'Scenario', '" + dataItem.Id + "')) {ToggleStatus('" + dataItem.Id + "', this);}\" title=\"Activate\" data-toggle=\"popover\" data-placement=\"left\"><i class=\"fa fa-check-circle-o\"></i></a>");
|
|
cellhtml += " " + options;
|
|
}
|
|
|
|
return cellhtml;
|
|
}
|
|
|
|
function getProbabilityStr(model) {
|
|
if (!model.Probability) {
|
|
return "0%";
|
|
}
|
|
var percent = model.Probability * 100;
|
|
if (percent > 0 && percent <= 25)
|
|
return Math.round(percent) + "% (Low)";
|
|
if (percent > 25 && percent <= 75)
|
|
return Math.round(percent) + "% (Medium)";
|
|
if (percent > 75 && percent <= 99)
|
|
return Math.round(percent) + "% (High)";
|
|
if (percent == 100)
|
|
return Math.round(percent) + "% (Expected)";
|
|
|
|
return model.Probability;
|
|
}
|
|
|
|
function formatCosts(costs) {
|
|
return ((!costs) ? "" : '$' + costs.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
|
|
}
|
|
|
|
function getCGSplit(data) {
|
|
return ((!data.CGSplit) ? "0%" : data.CGSplit * 100 + ' %') + " / " + ((!data.EFXSplit) ? "0%" : data.EFXSplit * 100 + ' %');
|
|
}
|
|
|
|
function getExpectedGrossMargin(data) {
|
|
return ((data.UseLMMargin) ? Math.round(data.ExpectedGrossMargin_LM * 1000) / 10 + ' % (L&M)' : Math.round(data.ExpectedGrossMargin * 1000) / 10 + ' %');
|
|
}
|
|
|
|
function getExpectedGrossMarginGroupAvg(data) {
|
|
return ((data.UseLMMargin) ? Math.round(data.ExpectedGrossMargin_LM * 1000) / 10 + ' % (L&M)' : Math.round(data.ExpectedGrossMargin * 1000) / 10 + ' %');
|
|
}
|
|
|
|
function getGroupSummaryText(text, gridName, columnName) {
|
|
// SA. This method returns text for displaying in Group summary field cell.
|
|
// Returns <text>, if field <columnName> is the first column in the grid, otherwise returns empty string
|
|
var result = "";
|
|
var grid = $("#" + gridName).data("kendoGrid");
|
|
|
|
if (columnName && grid && grid.columns) {
|
|
var visibleIndex = -1;
|
|
|
|
for (var index = 0; index < grid.columns.length; index++) {
|
|
if (!grid.columns[index].hidden)
|
|
visibleIndex++;
|
|
|
|
if ((grid.columns[index].field == columnName) && (visibleIndex == 0))
|
|
result = '<span title="' + htmlEncode(text) + '">' + text + '</span>';
|
|
|
|
if (visibleIndex >= 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function getPercentSummaryValue(val) {
|
|
var valueCorrected = val !== null ? val : 0;
|
|
var formattedValue = kendo.format('{0:p0}', valueCorrected);
|
|
return '<span title="' + htmlEncode(formattedValue) + '">' + formattedValue + '</span>'
|
|
}
|
|
|
|
function formatPercentValue(val) {
|
|
if ($.isNumeric(val))
|
|
return kendo.format('{0:p0}', val);
|
|
else
|
|
return '';
|
|
}
|
|
|
|
function getCurrencySummaryValue(val) {
|
|
var valueCorrected = val !== null ? val : 0;
|
|
var formattedValue = kendo.format('{0:c}', valueCorrected);
|
|
return '<span title="' + htmlEncode(formattedValue) + '" data-value="' + val + '">' + formattedValue + '</span>'
|
|
}
|
|
|
|
function getDateSummaryValue(val) {
|
|
var formattedValue = kendo.toString(kendo.parseDate(val) || '', 'd');
|
|
//we are using formattedValue because val is date in JSON format: /Date(1234500000)/
|
|
return '<span title="' + htmlEncode(formattedValue) + '" data-value="' + formattedValue + '">' + formattedValue + '</span>'
|
|
}
|
|
|
|
function getHoursSummaryValue(val) {
|
|
var valueCorrected = val !== null ? val : 0;
|
|
var formattedValue = kendo.format('{0:n2}', valueCorrected);
|
|
return '<span title="' + htmlEncode(formattedValue) + '" data-value="' + val + '">' + formattedValue + '</span>'
|
|
}
|
|
|
|
function getIntegerSummaryValue(val) {
|
|
var valueCorrected = val !== null ? val : 0;
|
|
var formattedValue = kendo.toString(valueCorrected, 'n0');
|
|
return '<span title="' + htmlEncode(formattedValue) + '" data-value="' + val + '">' + formattedValue + '</span>'
|
|
}
|
|
|
|
function formatMargin(margin) {
|
|
return ((!margin) ? "0%" : Math.round(margin * 1000) / 10 + ' %');
|
|
}
|
|
|
|
function onGridDataBound(e) {
|
|
var data = this.dataSource.view(),
|
|
gridName = e.sender.element.attr("id");
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
var dataItem = data[i];
|
|
if (dataItem.items) {
|
|
for(var col = 0; col < dataItem.items.length; col++) {
|
|
var row = dataItem.items[col];
|
|
var tr = $("#" + gridName).find("[data-uid='" + row.uid + "']");
|
|
if (row.PerformanceColor) {
|
|
tr.addClass(row.PerformanceColor);
|
|
}
|
|
}
|
|
} else {
|
|
var tr = $("#" + gridName).find("[data-uid='" + dataItem.uid + "']");
|
|
if (dataItem.PerformanceColor) {
|
|
tr.addClass(dataItem.PerformanceColor);
|
|
}
|
|
}
|
|
}
|
|
setTimeout(function () {
|
|
//get the indicator header
|
|
var groupIndicator = $('.k-group-indicator');
|
|
var groupIndicatorHeader = groupIndicator.parent();
|
|
if (!groupIndicatorHeader) {
|
|
return;
|
|
}
|
|
var colTeamName = $.grep(groupIndicator, function (element) {
|
|
return $(element).data("field") == "TeamName";
|
|
})[0];
|
|
|
|
if (colTeamName) {
|
|
$(colTeamName).find(".k-group-delete").hide();
|
|
//check if it is draggable eneabled
|
|
var kendoDraggableObj = $(colTeamName).parent().data('kendoDraggable');
|
|
if (kendoDraggableObj) kendoDraggableObj.destroy();
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
function loadForecastGrid() {
|
|
$(".projectsSummaryItem").html($("#loading-template").html());
|
|
if(currentGridName) {
|
|
getGrid(currentGridName).dataSource.page(1);
|
|
}
|
|
}
|
|
|
|
function loadProjectsSummary() {
|
|
$.post("@Url.Action("GetProjectsSummary", "ForecastGrid")", getFilterParams())
|
|
.done(function (data) {
|
|
$("#txtTotalNumberOfProjects").children("a").text(data.numberOfProjects).show();
|
|
$("#txtTotalNumberOfProjects").children("img").remove();
|
|
|
|
$("#txtProjectWeeks").children("a").text(data.projectWeeks.toLocaleString(0)).show();
|
|
$("#txtProjectWeeks").children("img").remove();
|
|
|
|
$("#txtTotalProjectedRevenue").children("a").text(kendo.format("{0:c}", data.totalRevenue)).show();
|
|
$("#txtTotalProjectedRevenue").children("img").remove();
|
|
|
|
$("#txtTotalNetImpact").children("a").text(kendo.format("{0:c}", data.totalNetImpact)).show();
|
|
$("#txtTotalNetImpact").children("img").remove();
|
|
|
|
$("#txtTotalProjectedSavings").children("a").text(kendo.format("{0:c}", data.totalCostSavings)).show();
|
|
$("#txtTotalProjectedSavings").children("img").remove();
|
|
|
|
$("#txtTotalProjectCost").children("a").text(kendo.format("{0:c}", data.totalBUCost)).show();
|
|
$("#txtTotalProjectCost").children("img").remove();
|
|
|
|
$("#totalResourceAvailability").children("a").text(kendo.format("{0}", data.totalResourceAvailability) + "%").show();
|
|
$("#totalResourceAvailability").children("img").remove();
|
|
});
|
|
}
|
|
|
|
function widgetToRestore()
|
|
{
|
|
$('#cardBubble1').addClass('minimized');
|
|
pv.chart.menu.restoreWin();
|
|
}
|
|
|
|
function widgetToFullScreen()
|
|
{
|
|
$('#cardBubble1').removeClass('minimized');
|
|
}
|
|
|
|
function getVisibleColumns() {
|
|
var grid = getGrid(currentGridName);
|
|
var result = grid.columns.filter(function(col, index) {
|
|
return !col.hidden;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
function getUngroupedData(exportData) {
|
|
var grid = getGrid(currentGridName),
|
|
result = [];
|
|
if(grid.dataSource.group().length == 0) {
|
|
return exportData;
|
|
}
|
|
$.each(exportData, function(index, dataItem){
|
|
if(dataItem.field && dataItem.items && !dataItem.hasSubgroups) { //Grouped mode.
|
|
$.each(dataItem.items, function(childIndex, child){
|
|
result.push(child)
|
|
});
|
|
} else if(dataItem.hasSubgroups) {
|
|
//debugger;
|
|
var subItems = getUngroupedData(dataItem.items);
|
|
$.each(subItems, function(childIndex, child){
|
|
result.push(child)
|
|
});
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
function onExcelExport(e) {
|
|
var grid = getGrid(currentGridName),
|
|
rows = e.workbook.sheets[0].rows,
|
|
columns = getVisibleColumns(),
|
|
dataRowIndex = 0,
|
|
data = getUngroupedData(e.data);
|
|
|
|
var groupCount = grid.dataSource.group().length;
|
|
for (var ri = 0; ri < rows.length; ri++) {
|
|
var row = rows[ri];
|
|
if (row.type == "data") {
|
|
for (var ci = groupCount; ci < row.cells.length; ci++) {
|
|
var cell = row.cells[ci];
|
|
if(columns[ci - groupCount].template) {
|
|
var template = kendo.template(columns[ci - groupCount].template);
|
|
var cellContent = template(data[dataRowIndex]);
|
|
var $firstChild = $($.parseHTML(cellContent));
|
|
|
|
var value = $firstChild.data("value");
|
|
if(value) {
|
|
cell.value = value;
|
|
} else {
|
|
cell.value = $firstChild.text();
|
|
}
|
|
}
|
|
}
|
|
dataRowIndex++;
|
|
}
|
|
|
|
if (row.type == "group-footer" || row.type == "footer") {
|
|
for (var ci = groupCount; ci < row.cells.length; ci++) {
|
|
var cell = row.cells[ci];
|
|
if (cell.value) {
|
|
//var footerTemplate;
|
|
//if(row.type == "group-footer") {
|
|
// columnTemplate = columns[ci - groupCount].groupFooterTemplate;
|
|
//} else if(row.type == "footer") {
|
|
// columnTemplate = columns[ci - groupCount].footerTemplate;
|
|
//}
|
|
//var template = kendo.template(footerTemplate);
|
|
|
|
// TODO: apply (group)FooterTemplate. Get dataItem for footer or groupFooter and pass it to template();
|
|
|
|
var $firstChild = $($.parseHTML(cell.value));
|
|
var value = $firstChild.data("value");
|
|
if(value) {
|
|
cell.value = value;
|
|
} else {
|
|
cell.value = $firstChild.text();
|
|
}
|
|
continue;
|
|
|
|
|
|
var res = cell.value.substring(0, 5);
|
|
|
|
if ((res==='Count') || (res==='Total' ) || (res!=='<span' )){
|
|
cell.value = cell.value;
|
|
} else {
|
|
cell.value = $(cell.value).text();
|
|
// Set the alignment
|
|
cell.hAlign = "right";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script> |