304 lines
13 KiB
JavaScript
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;
|
|
}
|
|
}]); |