EnVisageOnline/Main/Source/EnVisage/Views/ForecastDashboard/_forecastDashboard.cshtml

1056 lines
47 KiB
Plaintext

@using EnVisage.Code
@using EnVisage.Models
@model EnVisage.Models.ForecastDashboardOptionsModel
@{
bool displayedInTeamDashboard = Model.SourcePageModel.Equals(typeof(TeamboardModel).Name);
bool displayedInViewDashboard = Model.SourcePageModel.Equals(typeof(ViewBoardModel).Name);
}
<div class="@(displayedInTeamDashboard || displayedInViewDashboard ? "" : "panel") form-horizontal" id="criteria-container">
<form class="form-horizontal">
<input type="hidden" id="scenarioId" name="scenarioId" />
<input type="hidden" id="groupId" name="groupId" />
<input type="hidden" id="pieChartColor" name="pieChartColor" />
<div class="@(displayedInTeamDashboard ? "" : "panel-body")">
<div class="@(displayedInTeamDashboard || displayedInViewDashboard ? "row padding-sm" : "row")"
style="@(displayedInTeamDashboard || displayedInViewDashboard ? "padding-bottom:0px!important;" : "")">
<div class="@(displayedInTeamDashboard ? "col-sm-12 col-md-6" : "col-lg-3 col-md-4 col-sm-5")">
<div class="form-group no-margin-hr">
<label class="control-label">Start/End Date</label>
<div style="overflow: hidden;">
<div class="input-daterange input-group" id="bs-datepicker-rangeChart">
<input class="form-control valid" data-key="foreecastFilterStartDate" id="filterStartDateChart" name="filterStartDateChart" type="text" value="@DateTime.Today.AddMonths(-1).ToString("MM/dd/yyyy")">
<div class="input-group-addon">to</div>
<input class="form-control" data-key="foreecastFilterEndDate" id="filterEndDateChart" name="filterEndDateChart" type="text" value="@DateTime.Today.AddMonths(11).ToString("MM/dd/yyyy")">
</div>
</div>
</div>
</div>
<div class="@(displayedInTeamDashboard ? "col-sm-12 col-md-6" : "col-lg-2 col-md-3 col-sm-5")">
<div class="form-group no-margin-hr select2-primary">
<label class="control-label">Project Types</label>
@Html.DropDownList("filterClassification", Utils.GetProjectClassificationDropdown(includeEmpty: false),
new
{
@id = "filterClassification",
@class = "form-control fcboard-criteria-select2",
@data_key = "forecastFilterClassification",
@multiple = "multiple"
})
</div>
</div>
<div class="@(displayedInTeamDashboard ? "col-sm-12 col-md-3" : "col-lg-2 col-md-3 col-sm-4")">
<div class="form-group no-margin-hr select2-primary">
<label class="control-label">Project Statuses</label>
@Html.DropDownList("filterStatus", Utils.GetProjectStatusDropdown(includeEmpty: false),
new
{
@id = "filterStatus",
@class = "form-control fcboard-criteria-select2",
@data_key = "forecastFilterStatus",
@multiple = "multiple"
})
</div>
</div>
<div class="col-lg-2 col-md-3 col-sm-4" style="@((Request.Path == "/") ? "" : "display:none")">
<div class="form-group no-margin-hr select2-primary">
<label class="control-label">Teams/Views</label>
@Html.DropDownList("filterTeam", Utils.GetViewsTeamsAndCompanies(User.Identity.GetID(), false),
new
{
@id = "filterTeam",
@class = "form-control fcboard-criteria-select2",
@data_key = "forecastFilterTeam",
@multiple = "multiple"
})
</div>
</div>
<div class="@(displayedInTeamDashboard ? "col-sm-12 col-md-6" : "col-lg-2 col-md-3 col-sm-5")">
<div class="form-group no-margin-hr select2-primary">
<label class="control-label">Strategic Goals</label>
@Html.DropDownList("filterGoal", Utils.GetStrategicGoalsDropdown(false),
new
{
@id = "filterGoal",
@class = "form-control fcboard-criteria-select2",
@data_key = "forecastFilterGoal",
@multiple = "multiple"
})
</div>
</div>
<div class="@(displayedInTeamDashboard ? "col-sm-1 col-md-1" : "col-lg-1 col-md-1 col-sm-1")"
style="padding-top:25px;">
<a class="btn btn-primary" onclick="applyForecastDashboardFilter(false);" id="filterForecastDataBtn">Filter</a>
</div>
</div>
</div>
@Html.HiddenFor(t => t.AdditionalFilterParams)
</form>
</div>
<div id="grid"></div>
<script type="text/javascript">
var _dataForChart;
var _pagePreferences = [];
var _allScenarioGroups = [];
var _menu;
var _dataSectionName;
var _scenDetailsUrl = '@Url.Action("Details", "Scenarios", new { @id = "_rplcmnt_", @backUrl = "/", @backName = "dashboard" })';
var _projectUrl = '@Url.Action("Edit", "Project", new { @id = "_rplcmnt_", @backUrl = "/", @backName = "dashboard" })';
var _loadingGifUrl = '@Url.Content("~/Content/images/load.gif")';
var _additionalFiltersId = '@Html.IdFor(t => t.AdditionalFilterParams)';
var _hideTeamGroupping = (document.location.pathname == '@(Url.Action("Board", "Team"))'); // Hide groupping for Teams Dashboard. Check the page by Url
var _forecastPageState = null;
var allCols = [];
@foreach (var item in Utils.GetScenarioGroup().Where(item => !item.Text.Equals("Default")))
{
@:_allScenarioGroups.push("@item.Value" + ":" + "@item.Text");
}
function ToggleStatus(btn, projectId, scenarioId, startDateMs, endDateMs) {
$(btn).scenarioStatusToggle({
scenario: {
scenarioId: scenarioId,
projectId: projectId,
startDate: startDateMs ? DateTimeConverter.msFormatAsUtcString(startDateMs) : null,
endDate: endDateMs ? DateTimeConverter.msFormatAsUtcString(endDateMs) : null,
},
minStartDate: '@Constants.MIN_SELECTABLE_DATE',
maxEndDate: '@Constants.MAX_SELECTABLE_DATE',
runType: 'OnDemand',
success: function (args) {
if (typeof LoadGraphData === 'function')
LoadGraphData();
if (typeof LoadPieData === 'function')
LoadPieData();
$("#grid").data("kendoGrid").dataSource.read();
},
error: function (args) {
showErrorModal();
},
});
$(btn).scenarioStatusToggle('toggleStatus');
}
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 = '/ForecastDashboard/CopyScenarioToGroup';
else
url = '/ForecastDashboard/ExtractFromGroup';
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 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 formatFDDate(jsonDate) {
if (jsonDate == null || jsonDate == "")
return "";
var dt = new Date(parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10));
return (dt.getMonth() < 9 ? '0' : '') + (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
}
function switchFDGraph() {
changeUomModeForecastSwitcherState($('#expendituresMode').prop('checked'));
if (typeof DrawGraph === 'function')
DrawGraph();
}
function dropDownFixPosition(button, dropdown) {
var dropDownLeft = button.offset().left - window.pageXOffset - dropdown.width() + button.outerWidth();
var dropDownTop = button.offset().top + button.outerHeight() - window.pageYOffset;
dropdown.css('position', 'fixed');
dropdown.css('top', dropDownTop + "px");
dropdown.css('left', dropDownLeft + "px");
}
function ToggleChart() {
if ($('#graph-container').css('display') == 'none') {
$('#graph-container').css('display', 'block');
if (typeof DrawGraph === 'function')
DrawGraph();
if (typeof DrawPie === 'function')
DrawPie();
} else
$('#graph-container').css('display', 'none');
}
function ToggleCriteria() {
if ($('#criteria-container').css('display') == 'none')
$('#criteria-container').show();
else
$('#criteria-container').hide();
}
function switchExpenditureMode() {
if (!$('#expendituresMode').prop('checked')) {
$('#uomModeForecast').switcher('enable');
$('#uomModeForecast').switcher('on');
}
changeUomModeForecastSwitcherState($('#expendituresMode').prop('checked'));
if (typeof LoadGraphData === 'function')
LoadGraphData();
if (typeof LoadPieData === 'function')
LoadPieData();
}
function switchGroupByTeamMode() {
onPreferencesItemClick();
$('#grid').data().kendoGrid.destroy();
$('#grid').empty();
initKendoGrid();
}
function switchPerformanceMode() {
setPerformanceMode();
if ($('#performanceMode').prop('checked')) {
if (typeof LoadPerformanceData === 'function') {
LoadPerformanceData();
}
}
}
function setPerformanceMode() {
if ($('#performanceMode').prop('checked')) {
$('#performanceChartMode').switcher('enable');
$("#grid").data("kendoGrid").table.addClass("show-performance")
$("#grid").data("kendoGrid").lockedTable.addClass("show-performance")
$('#stacked-container').css('display', 'block');
}
else {
$('#performanceChartMode').switcher('disable');
$("#grid").data("kendoGrid").table.removeClass("show-performance")
$("#grid").data("kendoGrid").lockedTable.removeClass("show-performance")
$('#stacked-container').css('display', 'none');
}
}
function switchPerformanceChartMode() {
if (typeof LoadPerformanceData === 'function')
LoadPerformanceData();
}
function changeUomModeForecastSwitcherState(laborMode) {
if ($('#chFDGraphMode').prop('checked') && laborMode)
$('#uomModeForecast').switcher('enable');
else
$('#uomModeForecast').switcher('disable');
}
function applyForecastDashboardFilter(skipChart) {
$("#filter_processing").show();
saveForecastDashboardPreferences();
filterForecastData(skipChart);
}
function filterForecastData(skipChart) {
if (!skipChart && typeof LoadGraphData === 'function')
LoadGraphData();
if (typeof LoadPieData === 'function')
LoadPieData();
$("#grid").data("kendoGrid").dataSource.read();
}
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);
hideRedundantPopovers($('#grid'), null);
}
var liHeight = 30;
function scenarioNameTemplate(dataItem) {
//var link = "<a href=\"" + _scenDetailsUrl.replace("_rplcmnt_", dataItem.Id) + "\">" + dataItem.Name + "</a>";
var strA = '<div class="scenario-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.InactiveScenarios && dataItem.InactiveScenarios.length) {
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);">';
for (var inactiveIndex = 0; inactiveIndex < dataItem.InactiveScenarios.length; inactiveIndex++) {
var scenario = dataItem.InactiveScenarios[inactiveIndex];
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="' + scenario.Name + '">' + scenario.Name + '</span></div>' +
'<div style="float: right;padding-right: 15px;"><a data-toggle="popover" title="Activate" onclick="ToggleStatus(this, \'' + (dataItem.PartId || dataItem.ProjectId) + '\', \'' + scenario.Id + '\', ' + scenario.StartDate + ', ' + scenario.EndDate + ')" 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 initColumns() {
allCols["Id"] = { field: "Id", title: "Id", hidden: true };
allCols["ProjectName"] = {
field: "ProjectName", title: "Project Name",
groupFooterTemplate: "Team Summary", footerTemplate: "Summary",
locked: true, lockable: true, width: 200, template: function (dataItem) {
// TODO: maybe we should redirect to part edit page if project is children one? now it always redirects on main project edit
return "<a href=\"" + _projectUrl.replace("_rplcmnt_", dataItem.ProjectId) + "\">" + dataItem.ProjectName + "</a>";
}
};
allCols["Name"] = {
field: "Name", title: "Scenario Name", template: scenarioNameTemplate, width: 250
};
allCols["ClientName"] = {
field: "ClientName", title: "Client", width: 200, template: function (dataItem) {
return dataItem.ClientName;
}
};
// Uncomment lines below to make column CompanyName visible in the grid
//allCols["CompanyName"] = {
// field: "CompanyName", title: "Company", width: 200, template: function (dataItem) {
// return dataItem.CompanyName;
// }
//};
allCols["StartDate"] = {
field: "StartDate", title: "Start Date", type: "date", format: "{0:M/d/yyyy}", aggregates: ["min"],
footerTemplate: "#= kendo.toString(kendo.parseDate(min), 'd') #", groupFooterTemplate: "#= kendo.toString(kendo.parseDate(min), 'd') #",
width: 80
};
allCols["EndDate"] = {
field: "EndDate", title: "End Date", type: "date", format: "{0:M/d/yyyy}", aggregates: ["max"],
footerTemplate: "#= kendo.toString(kendo.parseDate(max), 'd') #", groupFooterTemplate: "#= kendo.toString(kendo.parseDate(max), 'd') #",
width: 80
};
allCols["ProjectedRevenue"] = {
field: "ProjectedRevenue", title: "Projected Revenue", width: 100, template: function (dataItem) {
return (!dataItem.ProjectedRevenue) ? "" : '$' + dataItem.ProjectedRevenue.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
}
};
allCols["ExpectedGrossMargin"] = {
field: "ExpectedGrossMargin", title: "Expected Margin", width: 100, template: function (full) {
return ((full.UseLMMargin) ? Math.round(full.ExpectedGrossMargin_LM * 1000) / 10 + ' % (L&M)' : Math.round(full.ExpectedGrossMargin * 1000) / 10 + ' %');
}
};
allCols["CalculatedGrossMargin"] = {
field: "CalculatedGrossMargin", title: "Calculated Gross", width: 100, template: function (full) {
return ((!full.CalculatedGrossMargin) ? "0%" : Math.round(full.CalculatedGrossMargin * 1000) / 10 + ' %');
}
};
allCols["CalculatedGrossMargin_LM"] = {
field: "CalculatedGrossMargin_LM", title: "L&M Margin", width: 100, template: function (full) {
return ((!full.CalculatedGrossMargin_LM) ? "0%" : Math.round(full.CalculatedGrossMargin_LM * 1000) / 10 + ' %');
}
};
allCols["CGSplit"] = {
field: "CGSplit", title: "Labor / Materials", width: 100, template: function (full) {
return ((!full.CGSplit) ? "0%" : full.CGSplit * 100 + ' %') + " / " + ((!full.EFXSplit) ? "0%" : full.EFXSplit * 100 + ' %');
}
};
allCols["ProjectDeadline"] = {
field: "ProjectDeadline", title: "Project Deadline", width: 100, template: function (full) {
return ((!full.ProjectDeadline) ? "N/A" : formatFDDate(full.ProjectDeadline));
}
};
allCols["ProjectType"] = { field: "ProjectType", title: "Project Type", width: 100 };
allCols["Probability"] = {
field: "Probability", title: "Probability", width: 100, template: function (full) {
var txt = '';
if (full.Probability * 100 > 0 && full.Probability * 100 <= 25)
txt = " (Low)";
if (full.Probability * 100 > 25 && full.Probability * 100 <= 75)
txt = " (Medium)";
if (full.Probability * 100 > 75 && full.Probability * 100 <= 99)
txt = " (High)";
if (full.Probability * 100 == 100)
txt = " (Expected)";
return ((!full.Probability) ? "0%" : Math.round(full.Probability * 100) + ' %' + txt);
}
};
allCols["Priority"] = { field: "Priority", title: "Priority", width: 100 };
allCols["TDDirectCosts"] = {
field: "TDDirectCosts", title: "Top Down Direct Costs", aggregates: ["sum"],
footerTemplate: "$#= kendo.toString(sum, 'n') #", groupFooterTemplate: "$#= kendo.toString(sum, 'n') #",
width: 100, template: function (full) {
return ((!full.TDDirectCosts) ? "" : '$' + full.TDDirectCosts.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
}
};
allCols["TDDirectCosts_LM"] = {
field: "TDDirectCosts_LM", title: "Top Down Direct Costs L&M", aggregates: ["sum"],
footerTemplate: "$#= kendo.toString(sum, 'n') #", groupFooterTemplate: "$#= kendo.toString(sum, 'n') #",
width: 100, template: function (full) {
return ((!full.TDDirectCosts_LM) ? "" : '$' + full.TDDirectCosts_LM.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
}
};
allCols["BUDirectCosts"] = {
field: "BUDirectCosts", title: "Bottom Up Direct Costs", aggregates: ["sum"],
footerTemplate: "$#= kendo.toString(sum, 'n') #", groupFooterTemplate: "$#= kendo.toString(sum, 'n') #",
width: 100, template: function (full) {
return ((!full.BUDirectCosts) ? "" : '$' + full.BUDirectCosts.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
}
};
allCols["BUDirectCosts_LM"] = {
field: "BUDirectCosts_LM", title: "Bottom Up Direct Costs L&M", aggregates: ["sum"],
footerTemplate: "$#= kendo.toString(sum, 'n') #", groupFooterTemplate: "$#= kendo.toString(sum, 'n') #",
width: 100, template: function (full) {
return ((!full.BUDirectCosts_LM) ? "" : '$' + full.BUDirectCosts_LM.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
}
};
allCols["CostSavings"] = {
field: "CostSavings", title: "Cost Savings", aggregates: ["sum"],
footerTemplate: "$#= kendo.toString(sum, 'n') #", groupFooterTemplate: "$#= kendo.toString(sum, 'n') #",
width: 100, template: function (full) {
return ((!full.CostSavings) ? "" : '$' + full.CostSavings.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
}
};
allCols["CostSavingsDuration"] = { field: "CostSavingsDuration", title: "Cost Savings Duration", width: 100 };
allCols["ROIDate"] = {
field: "ROIDate", title: "ROI Date", width: 100, template: function (full) {
return ((!full.ROIDate) ? "N/A" : formatFDDate(full.ROIDate));
}
};
allCols["HardSoftSavings"] = { field: "HardSoftSavings", title: "Hard/Soft Savings", width: 100 };
allCols["ScenarioStatus"] = {
field: "ScenarioStatus", title: "Options", width: 110, attributes: { style: "overflow:visible;" }, template: function (full) {
var cellhtml = "";
if (full.ScenarioStatus != null) {
var options = "";
for (i = 0; i < _allScenarioGroups.length; i++) {
var arr = _allScenarioGroups[i].split(":");
var isFound = false;
for (j = 0; j < full.Groups.length; j++) {
if (arr[0] == full.Groups[j].substr(full.Groups[j].lastIndexOf(">") + 1)) {
isFound = true;
break;
}
}
options += "<li data-scenarioId='" + full.Id + "' data-groupId='" + arr[0] + "'>" +
"<input type='checkbox' style='margin-right: 5px;' id='" + full.Id + '_' + arr[0] + "' ";
if (isFound)
options += "checked";
options += "/><input type='hidden' value='";
if (isFound)
options += "checked";
else
options += "unchecked";
options += "'/><span class='glyphicon glyphicon-refresh glyphicon-refresh-animate hide'></span><label for='" + full.Id + '_' + arr[0] + "'>" + arr[1] + "</label></li>";
}
if (options.length > 0) {
options = "<div class=\"btn-group dropdown scenarioGroupDropdown\" id=\"copyto_" + full.Id + "\">" +
"<button type='button' class='btn btn-xs dropdown-toggle dropdown-fix-pos' data-toggle='dropdown'>Groups&nbsp;<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>";
}
var scenarioStartDate = full.StartDate ? DateTimeConverter.stringToMs(full.StartDate) : null;
var scenarioEndDate = full.EndDate ? DateTimeConverter.stringToMs(full.EndDate) : null;
cellhtml = "<a class=\"btn btn-xs btn-warning popover-warning popover-dark\" id=\"" + full.Id + "\" onclick=\"ToggleStatus(this, '" + (full.PartId || full.ProjectId) + "', '" + full.Id + "', " + scenarioStartDate + ", " + scenarioEndDate + ");\" title=\"Deactivate\" data-toggle=\"popover\" data-placement=\"left\"><i class=\"fa fa-times-circle-o\"></i></a>";
cellhtml += "&nbsp;" + options;
}
return cellhtml;
}
};
allCols["TeamName"] = {
field: "TeamName", title: "Team Name", width: 100, template: function (full) {
return (full.TeamName);
}
, hidden: $('#groupByTeamMode').prop('checked')
};
allCols["PerformanceColor"] = { field: "PerformanceColor", title: "Performance Color", width: 100, hidden: true };
allCols["ProjectStatus"] = { field: "ProjectStatus", title: "Project Status", width: 100 };
allCols["StrategicGoals"] = { field: "StrategicGoals", title: "Strategic Goal", width: 100 };
}
function initKendoGrid() {
var section = getDataSection($('#grid'));
var _pagePreferences = loadUserPagePreferences(section);
//build sorted columns
initColumns();
var gridState = getGridState();
var savedColumns = gridState ? gridState.columns : null;
var sortedColumns = [];
var processedColumns = {};
if (savedColumns && savedColumns.length) {
var columns = $.extend(true, [], allCols);
$(savedColumns).each(function (i, columnState) {
if (columnState.hidden)
columns[columnState.field].hidden = columnState.hidden;
if (columnState.width)
columns[columnState.field].width = columnState.width;
sortedColumns.push(columns[columnState.field]);
processedColumns[columnState.field] = true;
});
// Add to grid columns list columns, which are not mentioned in preferences, but exist in the grid
for (var col in allCols) {
if (!(col in processedColumns)) {
sortedColumns.push(allCols[col]);
}
}
} else {
for (var col in allCols) {
sortedColumns.push(allCols[col]);
}
}
var sort = gridState ? gridState.sort : [];
var datasource = {
serverSorting: false,
serverFiltering: true,
serverPaging: true,
serverGrouping: true,
serverAggregates: true,
transport: {
read: {
url: "/ForecastDashboard/GetTable/",
dataType: "Json",
type: "POST",
dataType: "Json",
data: function () {
var grid = $("#grid").data("kendoGrid");
var parameterMap = grid.dataSource.transport.parameterMap;
var data = parameterMap({
sort: grid.dataSource.sort(),
group: grid.dataSource.group(),
aggregate: grid.dataSource.aggregate(),
page: grid.dataSource.page(),
pageSize: grid.dataSource.pageSize(),
sort: grid.dataSource.sort()
});
var filter = getFilterData();
return { request: data, filter: filter };
}
}
},
change: function (e) {
$("#filter_processing").hide();
},
schema: {
data: "Data",
total: "Total",
groups: "Groups",
aggregates: "Aggregates"
},
sort: sort,
aggregate: getAggregates()
};
if ($('#groupByTeamMode').prop('checked')) {
datasource.group = [{
field: "TeamName",
aggregates: getAggregates()
}];
}
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Dashboard Export.xlsx"
},
resizable: true,
sortable: true,
pageable: {
pageSize: 25,
pageSizes: [25, 50, 100]
},
dataSource: datasource,
columns: sortedColumns,
reorderable: true,
groupable: false,
dataBound: onGridDataBound,
columnResize: saveForecastDashboardPreferences,
columnReorder: function (e) {
//TODO: prevent locked column(s) from reordering
//console.log('Reordered ' + e.column.field + ' to ' + e.newIndex + ' from ' + e.oldIndex);
setTimeout(function () {
saveForecastDashboardPreferences();
}, 5);
}
});
switchPerformanceMode();
var menuForColumns = _menu.find("#forecastGridColumns").children("ul");
if (menuForColumns) {
var htmlToAppend = "";
for (var col in allCols) {
var column = allCols[col];
if (!getColumnVisible(null, col)) {
//column hidden permanently
continue;
}
var visible = getColumnVisible(savedColumns, col);
var text = column.title;
if (text != "Project Name") {//&& text != "Team Name"
if (text == "")
text = "Options";
htmlToAppend += '<li class="padding-xs-hr"><div class="checkbox"><nobr><label><input type="checkbox" data-key="forecastCol_' + column.field + '" ' + (visible ? 'checked' : '') + ' class="columnVisibilityTrigger px" data-column="' + column.field + '"> <span class="lbl">' + text + '</span></label></nobr></div></li>';
}
};
menuForColumns.html(htmlToAppend);
}
_menu.find("input:checkbox").change(function () {
var checked = $(this).is(":checked");
var field = $(this).attr("data-column");
var grid = $("#grid").data("kendoGrid");
if (checked) {
grid.showColumn(field);
}
else {
grid.hideColumn(field);
}
onPreferencesItemClick($(this));
//also hide columns of expanded main rows
$(".inactv-" + $(this).attr('data-column')).css("display", checked ? "" : "none");
});
$('.k-grid-toolbar').hide();
}
function getAggregates() {
var aggregates = [
{ field: "BUDirectCosts", aggregate: "sum" },
{ field: "BUDirectCosts_LM", aggregate: "sum" },
{ field: "CostSavings", aggregate: "sum" },
{ field: "EndDate", aggregate: "max" },
{ field: "Id", aggregate: "count" },
{ field: "StartDate", aggregate: "min" },
{ field: "TDDirectCosts", aggregate: "sum" },
{ field: "TDDirectCosts_LM", aggregate: "sum" }
];
return aggregates;
}
function onGridDataBound(e) {
var data = this.dataSource.view();
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 = $("#grid").find("[data-uid='" + row.uid + "']");
if (row.PerformanceColor) {
tr.addClass(row.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);
saveForecastDashboardPreferences();
$(".k-grid-content-locked").height("");
}
function getColumnVisible(savedColumns, field) {
if (savedColumns && savedColumns.length) {
var columns = allCols;
for (var i = 0; i < savedColumns.length; i++) {
if (savedColumns[i].field == field) {
return !(savedColumns[i].hidden || false);
}
}
} else {
for (var col in allCols) {
if (col == field) {
return !(allCols[col].hidden || false);
}
}
}
return true;
}
function getFilterData() {
var additionalFilters = $('#' + _additionalFiltersId).val();
var teams = getSelectedTeamsOrViews("Teams");
var views = getSelectedTeamsOrViews("Views");
var filterGroupByTeam = _hideTeamGroupping ? false : $('#groupByTeamMode').prop('checked');
var additionalParams = additionalFilters ? JSON.parse(additionalFilters) : {};
var projectStatuses = $('#filterStatus').val() ? $('#filterStatus').val() : [];
var projectTypes = $('#filterClassification').val() ? $('#filterClassification').val() : [];
var strategicGoals = $('#filterGoal').val() ? $('#filterGoal').val() : [];
var result = {
"StartDate": $('#filterStartDateChart').val(),
"EndDate": $('#filterEndDateChart').val(),
"Type": $('#filterType').val(),
"StrategicGoals": $('#filterGoals').val(),
"Teams": teams,
"Views": views,
"ProjectTypes": projectTypes,
"ProjectStatuses": projectStatuses,
"StrategicGoals": strategicGoals,
"FilterGroups": $('#group').val(),
"FilterGroupByTeam": filterGroupByTeam,
"AdditionalParams": additionalParams
};
return result;
}
function createDatePickers() {
var options2 = {
orientation: $('body').hasClass('right-to-left') ? "auto right" : 'auto auto',
startDate: '@Constants.MIN_SELECTABLE_DATE',
endDate: '@Constants.MAX_SELECTABLE_DATE'
};
$('#bs-datepicker-rangeChart').datepicker(options2).on('changeDate', function (evt) {
var _tmpValue = $('#filterStartDateChart').val();
var _sDate = new Date(_tmpValue);
$('#filterEndDateChart').data('datepicker').setStartDate(_sDate);
_tmpValue = $('#filterEndDateChart').val();
var _eDate = new Date(_tmpValue);
if (_sDate > _eDate)
$('#filterEndDateChart').data('datepicker').setDate(_sDate);
});
var startDate = $('#filterStartDateChart');
var endDate = $('#filterEndDateChart');
var _tmpValue = startDate.val();
var _sDate = new Date(_tmpValue);
endDate.data('datepicker').setStartDate(_sDate);
startDate.addClass('form-control');
endDate.addClass('form-control');
startDate.removeClass('text-box');
endDate.removeClass('text-box');
startDate.removeClass('single-line');
endDate.removeClass('single-line');
}
function isColumnVisible(colNameToCheck) {
return true;
// If no prefs exist, by default column is visible
var result = true;
var key = "forecastCol_" + colNameToCheck;
if (_pagePreferences && (_pagePreferences.length > 0)) {
for (var index = 0; index < _pagePreferences.length; index++)
if (_pagePreferences[index].Key == key) {
// Column visibility info exists in the loaded prefs
result = _pagePreferences[index].Value;
break;
}
}
return result;
}
function isMSIE() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number
return true;
return false;
}
function onPreferencesItemClick(menuItem) {
saveForecastDashboardPreferences();
}
function saveForecastDashboardPreferences() {
var section = getDataSection($('#grid'));
var prefs = collectPreferences(section);
saveGridState(prefs);
saveUserPagePreferences(prefs, section);
}
function saveGridState(prefs) {
var grid = $("#grid").data("kendoGrid");
var dataSource = grid.dataSource;
var state = {
columns: grid.columns,
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort(),
filter: dataSource.filter(),
group: dataSource.group()
};
prefs.push({
Key: "forecastGridState",
Value: kendo.stringify(state)
});
}
function getGridState() {
if (!_pagePreferences || !_pagePreferences.length) {
return null;
}
var state = null;
for (var index = 0; index < _pagePreferences.length; index++)
if (_pagePreferences[index].Key == "forecastGridState") {
//console.log(_pagePreferences[index].Value);
try {
state = JSON.parse(_pagePreferences[index].Value);
}
catch (e) {
console.log('Error loading grid settings.');
}
break;
}
return state;
}
function getColumns() {
return getGridState().columns;
}
function loadForecastDashboardPreferences() {
var section = getDataSection($('#grid'));
_pagePreferences = loadUserPagePreferences(section);
return section;
}
function initMenuItems() {
if (_menu.find("label:contains('Show Criteria')").length < 1) {
_menu.append('<li class="padding-xs-hr"><a style="cursor:pointer;padding: 5px 6px;margin-bottom:7px;@(displayedInTeamDashboard || displayedInViewDashboard? "" : "display:none;")" onclick="javascript:$(\'.k-grid-excel\').click();"><i class="dropdown-icon fa fa-file-o" style="margin-right:4px;"></i> Export to Excel</a></li>');
if (typeof LoadGraphData === 'function')
_menu.append('<li class="padding-xs-hr" style="@(displayedInTeamDashboard || displayedInViewDashboard? "display:none;" : "")" ><div class="checkbox"><label><input type="checkbox" data-key="showChart" id="chkShowChart" checked class="columnVisibilityTrigger px" onclick="ToggleChart()"/> <span class="lbl">Show Status Chart</span></label></div></li>');
_menu.append('<li class="padding-xs-hr"><div class="checkbox"><label><input type="checkbox" data-key="showCriteria" id="chkShowCriteria" checked class="columnVisibilityTrigger px" onclick="ToggleCriteria()"/> <span class="lbl">Show Filters</span></label></div></li>');
if (typeof LoadGraphData === 'function') {
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Status Chart as</span><input type="checkbox" data-key="chartMode" checked onclick="switchFDGraph()" name="chMode" id="chFDGraphMode" class="switcher" /></label></li>');
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Quantity as</span><input type="checkbox" data-key="uomMode" name="uomModeForecast" id="uomModeForecast" class="switcher px" onclick="DrawGraph()"/></label></li>');
}
_menu.append('<li class="padding-xs-hr" style="@(displayedInViewDashboard ? "display:none;" : "")"><label><span class="switcherLbl">Expenditures</span><input type="checkbox" data-key="expendituresMode" checked name="expendituresMode" id="expendituresMode" class="switcher px" onclick="switchExpenditureMode()"/></label></li>');
_menu.append('<li class="divider"></li>');
if (typeof LoadPieData === 'function') {
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Project Type Chart as</span><input type="checkbox" data-key="pieMode" checked name="pieModeForecast" id="pieModeForecast" class="switcher px" onclick="DrawPie()"/></label></li>');
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Filter Status Chart</span><input type="checkbox" data-key="pieReloadMode" checked name="pieReload" id="pieReload" class="switcher px"/></label></li>');
_menu.append('<li class="divider"></li>');
}
if (typeof LoadPerformanceData === 'function') {
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Performance Graph by</span><input type="checkbox" data-key="performanceChartMode" name="performanceChartMode" id="performanceChartMode" class="switcher px" onclick="switchPerformanceChartMode()"/></label></li>');
_menu.append('<li class="divider"></li>');
}
if (!_hideTeamGroupping)
_menu.append('<li class="padding-xs-hr"><label><span class="switcherLbl">Group by Team</span><input type="checkbox" data-key="groupByTeamMode" checked name="groupByTeamMode" id="groupByTeamMode" class="switcher px" onclick="switchGroupByTeamMode()"/></label></li>');
_menu.append('<li class="padding-xs-hr" style="@(displayedInViewDashboard ? "display:none;" : "")"><label><span class="switcherLbl">Performance</span><input type="checkbox" data-key="performanceMode" checked name="performanceMode" id="performanceMode" class="switcher px" onclick="switchPerformanceMode()"/></label></li>');
_menu.append('<li class="padding-xs-hr dropdown-submenu pull-left" id="forecastGridColumns"><a tabindex="-1" href="javascript:;">Grid Options</a><ul class="dropdown-menu pull-left"></ul></li>');
}
}
function initForecastDashboard() {
_dataSectionName = loadForecastDashboardPreferences();
if (_menu == null)
_menu = $("#@Model.MenuId");
initMenuItems();
_menu.click(function (event) {
event.stopPropagation();
});
_forecastPageState = $('#criteria-container').pageState({
pageKey: (document.location.pathname + ' - forecast'),
});
if (_dataSectionName && (_dataSectionName.length > 0)) {
restorePreferences(_dataSectionName, _pagePreferences);
}
createDatePickers();
$('#uomModeForecast').switcher({
on_state_content: '# Hours',
off_state_content: '# Resources'
});
$('#uomModeForecast').parent().css("width", "93px");
$('#chFDGraphMode').switcher({
on_state_content: 'Quantity',
off_state_content: 'Cost'
});
$('#chFDGraphMode').parent().css("width", "90px");
$('#expendituresMode').switcher({
on_state_content: 'Labor',
off_state_content: 'Non-labor'
});
$('#expendituresMode').parent().css("width", "82px");
if (!_hideTeamGroupping) {
$('#groupByTeamMode').switcher({
on_state_content: 'On',
off_state_content: 'Off'
});
$('#groupByTeamMode').parent().css("width", "82px");
}
if ($('#chkShowChart').prop('checked'))
$('#graph-container').show();
else
$('#graph-container').hide();
if ($('#chkShowCriteria').prop('checked'))
$('#criteria-container').show();
else
$('#criteria-container').hide();
if (typeof LoadPieData === 'function') {
$('#pieModeForecast').switcher({
on_state_content: 'Cost',
off_state_content: 'Time'
});
$('#pieModeForecast').parent().css("width", "82px");
$('#pieReload').switcher({
on_state_content: 'Yes',
off_state_content: 'No'
});
$('#pieModeForecast').click(function () {
LoadPieData();
});
$('#pieReload').parent().css("width", "82px");
}
$('#performanceMode').switcher({
on_state_content: 'On',
off_state_content: 'Off'
});
$('#performanceMode').parent().css("width", "82px");
$('#performanceChartMode').switcher({
on_state_content: 'Cost',
off_state_content: 'Type'
});
$('#performanceChartMode').parent().css("width", "82px");
initKendoGrid();
changeUomModeForecastSwitcherState($('#expendituresMode').prop('checked'));
setPerformanceMode();
if (typeof LoadGraphData === 'function')
LoadGraphData();
if (typeof LoadPieData === 'function')
LoadPieData();
$(window).scroll(function () {
$('.menuGroup').removeClass('open');
hideRedundantPopovers($('#grid'), null);
});
$('.table-striped').scroll(function () {
$('.menuGroup').removeClass('open');
hideRedundantPopovers($('#grid'), null);
});
$(document).click(function (event) {
$('.menuGroup').removeClass('open');
if (!$(event.target).is('[data-toggled="popover"]'))
hideRedundantPopovers($('#grid'), null);
});
}
init.push(function () {
initForecastDashboard();
$(".fcboard-criteria-select2").select2();
});
</script>