EnVisageOnline/Main/Source/EnVisage/Scripts/Angular/Controllers/ActivityCalendarControllers/supplyDemandCalendarControl...

304 lines
13 KiB
JavaScript

'use strict';
app
.controller('supplyDemandCalendarController', ['$scope', '$q', 'activityCalendarService', 'teamInfoService', 'activityCalendarUIService', 'dataSources', 'hoursResourcesConverter', function ($scope, $q, activityCalendarService, teamInfoService, activityCalendarUIService, dataSources, hoursResourcesConverter) {
var reportDataUrl = '/SupplyDemandReport/GetReport';
$scope.ViewModel = {
DisplayMode: null,
Header: null,
Rows: null,
TotalRow: null,
DataLoaded: false
};
$scope.Filter = null;
/* Event listeners */
$scope.$on('ac.rebuild-calendar', rebuildCalendarHandler);
$scope.$on('ac.options-changed', optionsChangedHandler);
/* Methods for interaction with view */
$scope.init = function (filter, displayMode) {
rebuildCalendarHandler(null, filter, displayMode);
};
$scope.toggleMonth = function (monthIndex) {
$scope.ViewModel.Header.toggleMonth(monthIndex);
};
$scope.toggleRow = function (uiRow, $event) {
hideRedundantPopovers();
if ($($event.target).parents('.menuGroup').length > 0)
return;
// to-do: we should keep collapsed state in data-model items between possible future postbacks
var dataModel = activityCalendarService.dataItemStub || {};
activityCalendarUIService.toggleRow(uiRow, dataModel);
};
/* Event handlers */
function rebuildCalendarHandler(event, filter, displayMode, forceDataReload, successCallback) {
// if filter is changed we need to invalidate cache
if ($scope.Filter && !activityCalendarService.cacheKeysEqual($scope.Filter, filter)) {
activityCalendarService.invalidateCache($scope.Filter);
}
$scope.ViewModel.DataLoaded = false;
$scope.ViewModel.DisplayMode = angular.copy(displayMode || {});
$scope.Filter = angular.copy(filter || {});
blockUI();
hoursResourcesConverter.load(forceDataReload).then(function () {
var loadCalendarTask = activityCalendarService.getActivityCalendar(reportDataUrl, filter, forceDataReload);
var cachedTemplates = activityCalendarUIService.cacheTemplates();
var allTasks = [loadCalendarTask].concat(cachedTemplates);
$q.all(allTasks)
.then(function (asyncResults) {
var calendar = asyncResults[0];
if (calendar.Teams) {
var teamIds = Object.keys(calendar.Teams);
var promise = dataSources.loadResourcesByTeamIds(teamIds)
.then(function (result) {
return asyncResults;
});
return promise;
} else {
return asyncResults;
}
})
.then(function (asyncResults) {
var calendar = asyncResults[0];
createViewModel(calendar);
initBottomPart();
toggleParts();
toggleSortBy();
toggleHoursResourcesMode();
toggleBarsValuesMode();
toggleMonths();
unblockUI();
if (typeof successCallback === 'function') {
successCallback();
}
if (angular.isObject(calendar))
$scope.ViewModel.DataLoaded = true;
})
.then(null, function () {
unblockUI();
showErrorModal();
});
}).then(null, function () {
unblockUI();
showErrorModal();
});
};
function optionsChangedHandler(event, displayMode, key, newValue) {
//console.log(key);
$scope.ViewModel.DisplayMode = displayMode || {};
switch (key) {
case 'uomMode':
toggleHoursResourcesMode();
$scope.$broadcast('changeUOMMode', newValue);
break;
case 'capBarMode':
toggleBarsValuesMode();
break;
case 'defaultView':
toggleMonths();
break;
case 'sortBy':
case 'sortOrder':
toggleSortBy();
break;
case 'showParts':
toggleParts();
toggleSortBy();
toggleHoursResourcesMode();
break;
case 'capacityView':
toggleCapacityType();
$scope.$broadcast('capacityViewChanged', newValue);
break;
default:
break;
};
};
/* Methods for creating view models */
function createViewModel(model) {
var projectExpendituresCache = {};
createHeaderViewModel(model.WeekEndings);
createRowsViewModel(model, projectExpendituresCache);
fillViewModelWithData(model, projectExpendituresCache);
projectExpendituresCache = null;
};
function createHeaderViewModel(weekEndings) {
$scope.ViewModel.Header = (new GridHeader(weekEndings || {}).create());
};
function createRowsViewModel(model, projectExpendituresCache) {
$scope.ViewModel.Rows = [];
if (!model || !model.Projects) {
return;
}
var allocationMode = ($scope.Filter.Teams || []).length ? activityCalendarUIService.allocationMode.teamAllocation : activityCalendarUIService.allocationMode.needAllocation;
var includeProjectNeed = allocationMode !== activityCalendarUIService.allocationMode.teamAllocation;
var filterCategories = allocationMode == activityCalendarUIService.allocationMode.teamAllocation;
var projects = model.Projects;
for (var projectId in projects) {
var extendedProjectModel = angular.extend({}, projects[projectId], {
AllocationMode: allocationMode
});
var projectExpenditures = activityCalendarUIService.getExpendituresWithResources4Project(extendedProjectModel, null, null, $scope.ViewModel.Header, $scope.Filter, includeProjectNeed, filterCategories, false, true);
if (projectExpenditures && Object.keys(projectExpenditures).length) {
projectExpendituresCache[projectId] = projectExpenditures;
var templates = {
projectRowTemplate: activityCalendarUIService.viewRowTemplates.projectSupplyDemandReportRowTemplate,
projectRowNumbersTemplate: activityCalendarUIService.viewRowTemplates.projectSupplyDemandReportRowNumbersTemplate,
expCatRowTemplate: activityCalendarUIService.viewRowTemplates.expCatSupplyDemandReportRowTemplate,
expCatRowNumbersTemplate: activityCalendarUIService.viewRowTemplates.expCatSupplyDemandReportRowNumbersTemplate,
};
var projectViewModel = activityCalendarUIService.createViewModel4Project(extendedProjectModel, projectExpendituresCache[projectId], $scope.Filter, false, templates);
if (projectViewModel) {
setTooltips(projectViewModel);
$scope.ViewModel.Rows.push(projectViewModel);
}
}
}
// Create total rows
createTotalRowModels();
};
function setTooltips(projectRow) {
if (!projectRow || !projectRow.Children)
return;
for (var index = 0; index < projectRow.Children.length; index++) {
var expCatRow = projectRow.Children[index];
if (expCatRow) {
expCatRow.getTooltipContent = $scope.getTooltipContent;
}
}
};
function createTotalRowModels() {
$scope.ViewModel.TotalRow = activityCalendarUIService.createViewModel4TotalRow('Total');
};
function getTotalRows() {
var rows = [];
if ($scope.ViewModel.TotalRow) {
rows.push($scope.ViewModel.TotalRow);
}
return rows;
};
function getResourceRows(resourceId) {
return activityCalendarUIService.getResourceRows($scope.ViewModel.Rows, resourceId);
};
/* Methods for filling view models with data */
function fillViewModelWithData(model, projectExpendituresCache) {
if (!$scope.ViewModel.Rows) {
return;
}
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
var project = $scope.ViewModel.Rows[i];
var expenditures = projectExpendituresCache[project.Id];
activityCalendarUIService.fillProjectRowWithData(null, project, expenditures, $scope.ViewModel.Header, $scope.Filter, false);
}
// Fill total rows with data
fillTotalRowsWithData();
};
function fillTotalRowsWithData() {
var rowsForTotal = angular.copy($scope.ViewModel.Rows) || [];
activityCalendarUIService.fillTotalRowData(rowsForTotal, $scope.ViewModel.TotalRow, $scope.ViewModel.Header);
};
/* Methods for toggling display modes */
function toggleHoursResourcesMode() {
var totalRows = getTotalRows();
activityCalendarUIService.toggleGridSource($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.IsUOMHours);
activityCalendarUIService.toggleGridSource(totalRows, $scope.ViewModel.DisplayMode.IsUOMHours);
if ($scope.ViewModel.DisplayMode.IsAvgMode()) {
activityCalendarUIService.applyAvgMode($scope.ViewModel.Rows, $scope.ViewModel.Header);
activityCalendarUIService.applyAvgMode(totalRows, $scope.ViewModel.Header);
}
};
function toggleBarsValuesMode() {
activityCalendarUIService.toggleBarsValuesMode($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.IsBarMode);
};
function toggleMonths() {
if ($scope.ViewModel.DisplayMode.IsViewModeMonth) {
$scope.ViewModel.Header.collapseMonthes();
}
else {
$scope.ViewModel.Header.expandMonthes();
}
};
function toggleParts() {
$scope.ViewModel.Rows = activityCalendarUIService.toggleParts($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.ShowParts.Value);
activityCalendarUIService.updateProjectStyles($scope.ViewModel.Header, $scope.Filter, $scope.ViewModel.Rows);
};
function toggleSortBy() {
console.log($scope.ViewModel.DisplayMode.SortBy);
var sortBy = ['Priority', 'Name'];
//$scope.ViewModel.DisplayMode.SortBy
$scope.ViewModel.Rows = activityCalendarUIService.toggleSortBy($scope.ViewModel.Rows, sortBy, $scope.ViewModel.DisplayMode.SortOrder);
};
function toggleCapacityType() {
// reset total row values
createTotalRowModels();
// recalculate total row UI data
fillTotalRowsWithData();
toggleHoursResourcesMode();
};
function initBottomPart() {
// need to pass new objects for preventing using single instances of objects inside current and other controllers
var displayMode = activityCalendarUIService.castDisplayModeIntoTeamInfoMode($scope.ViewModel.DisplayMode);
displayMode.DisplayPriorityColumn = true;
$scope.$broadcast('rebindTeamInfo', {
Header: $scope.ViewModel.Header,
DisplayMode: displayMode
});
};
/* ===== ToolTips display ==== */
$scope.getTooltipContent = function (opts) {
var tooltip = 'No data available';
var units = ' hours';
if (!$scope.DisplayMode.IsUOMHours)
units = ' resources';
if (!opts || !opts.header || !opts.projectId || !opts.expCatId)
return tooltip;
var header = opts.header;
var projectId = opts.projectId;
var expCatId = opts.expCatId;
var teamId = opts.teamId;
var teamAllocations = activityCalendarUIService.getTeamAllocations4Display($scope.Filter,
$scope.ViewModel.DisplayMode, $scope.ViewModel.Header, header, projectId, expCatId, teamId);
if (teamAllocations && (teamAllocations.length > 0)) {
tooltip = 'Allocated to Teams:';
for (var index = 0; index < teamAllocations.length; index++) {
var teamInfo = teamAllocations[index];
tooltip += ('<br/>' + teamInfo.Name + ': ' + teamInfo.Need + units);
}
}
else {
tooltip = 'No Team Allocations present';
}
return tooltip;
}
}]);