1070 lines
49 KiB
JavaScript
1070 lines
49 KiB
JavaScript
'use strict';
|
|
|
|
app
|
|
.controller('activityCalendarByCompanyController', ['$scope', '$q', 'activityCalendarService', 'teamInfoService', 'activityCalendarUIService', 'dataSources', 'hoursResourcesConverter', '$filter', function ($scope, $q, activityCalendarService, teamInfoService, activityCalendarUIService, dataSources, hoursResourcesConverter, $filter) {
|
|
var commonErrorMessage = 'An error occurred while processing your request. Please, try again later.';
|
|
var calendarDataUrl = '/CapacityManagement/GetActivityCalendar';
|
|
var nonProjectTimeCache = {}; // cache for non-project time data
|
|
var nonProjectTimeCategoryCache = {}; // cache for non-project time categories data
|
|
|
|
$scope.ViewModel = {
|
|
DisplayMode: null,
|
|
Header: null,
|
|
Rows: null,
|
|
TotalRow: null,
|
|
RemainingCapacityRow: null,
|
|
NonProjectTimeTotalRows: 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);
|
|
};
|
|
$scope.ToggleStatus = function ($event, projectId, scenario) {
|
|
var btn = $($event.target).closest('.popover-warning');
|
|
if (btn.length == 1) {
|
|
activityCalendarUIService.toggleStatus(btn, projectId, scenario)
|
|
.then(function (result) {
|
|
if (!!result)
|
|
rebuildCalendarHandler($event, $scope.Filter, $scope.ViewModel.DisplayMode, true);
|
|
})
|
|
.then(null, function () {
|
|
showErrorModal(null, 'An error occurred while toggling scenario status', '000009');
|
|
});
|
|
}
|
|
};
|
|
$scope.AddScenario = function ($event, projectId) {
|
|
activityCalendarUIService.openCreateScenarioWz(projectId);
|
|
};
|
|
$scope.formatPeopleResourceOption = function (result, container, query, escapeMarkup) {
|
|
return activityCalendarUIService.formatPeopleResourceOption(result.element);
|
|
};
|
|
$scope.assignResource = function (projectId, expCatRow, resourceId, teamId) {
|
|
if (!projectId || !expCatRow || !resourceId) {
|
|
return;
|
|
}
|
|
var rowToAddResource = expCatRow;
|
|
if (teamId) {
|
|
for (var teamKey in expCatRow.Children) {
|
|
if (teamId != expCatRow.Children[teamKey].Id)
|
|
continue;
|
|
rowToAddResource = expCatRow.Children[teamKey];
|
|
}
|
|
}
|
|
|
|
activityCalendarUIService.assignResource($scope.Filter, $scope.ViewModel.Header, projectId, expCatRow, resourceId, rowToAddResource);
|
|
dataChanged();
|
|
};
|
|
$scope.assignTeam = function (projectRow, expCatRow) {
|
|
if (!projectRow || !expCatRow || !expCatRow.TeamToAssignId) {
|
|
return;
|
|
}
|
|
// prepare extendModel to keep new added team info
|
|
var extendedModel = {
|
|
Expenditures2Display: {}
|
|
};
|
|
if (projectRow.Children) {
|
|
for (var ecIndex = 0; ecIndex < projectRow.Children.length; ecIndex++) {
|
|
var ecRow = projectRow.Children[ecIndex];
|
|
if (ecRow && ecRow.AvailableTeams) {
|
|
for (var tIndex = 0; tIndex < ecRow.AvailableTeams.length; tIndex++) {
|
|
if (ecRow.AvailableTeams[tIndex].Id == expCatRow.TeamToAssignId) {
|
|
extendedModel.Expenditures2Display[ecRow.Id] = ecRow.Id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// assign new team to DAL model
|
|
activityCalendarUIService.assignTeam($scope.Filter, $scope.ViewModel.Header, projectRow.Id, expCatRow.TeamToAssignId, extendedModel);
|
|
// add new team row to each EC of the project if it is available for assignment
|
|
if (projectRow.Children) {
|
|
for (var ecIndex = 0; ecIndex < projectRow.Children.length; ecIndex++) {
|
|
var ecRow = projectRow.Children[ecIndex];
|
|
if (ecRow && ecRow.AvailableTeams) {
|
|
for (var tIndex = 0; tIndex < ecRow.AvailableTeams.length; tIndex++) {
|
|
if (ecRow.AvailableTeams[tIndex].Id == expCatRow.TeamToAssignId) {
|
|
createAndFillNewEcTeamRow(projectRow, ecRow, expCatRow.TeamToAssignId);
|
|
// expand ec row
|
|
if (ecRow.Collapsed)
|
|
activityCalendarUIService.toggleRow(ecRow, {}, false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
activityCalendarUIService.refreshProjectAvailableTeams($scope.Filter, projectRow);
|
|
expCatRow.TeamToAssignId = null;
|
|
dataChanged();
|
|
};
|
|
$scope.checkResourceValue = function (projectRow, expCatRow, resRow, $index, $data, teamRow) {
|
|
if (!projectRow || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
parentRow = teamRow || expCatRow || {};
|
|
|
|
|
|
var result = activityCalendarUIService.checkResourceValue(filter, header, projectRow.Id, parentRow, resRow.Id, resRow, isUOMHours, isAvgMode, $index, $data, false);
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerResourceChanged(result);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, result);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, result);
|
|
dataChanged();
|
|
|
|
return false;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
$scope.checkTeamValueUnassigned = function (projectRow, expCatRow, teamRow, $index, $data) {
|
|
if (!projectRow || !expCatRow || !teamRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
startDate = projectRow.ActiveScenario.StartDate,
|
|
endDate = projectRow.ActiveScenario.EndDate;
|
|
|
|
var result = activityCalendarUIService.checkTeamValue(filter, header, projectRow.Id, expCatRow, teamRow.Id, teamRow, isUOMHours, isAvgMode, $index, $data);
|
|
onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, result);
|
|
return false;
|
|
};
|
|
$scope.checkResourceGrandTotalValue = function (projectRow, expCatRow, resRow, $data, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
parentRow = teamRow || expCatRow || {};
|
|
|
|
|
|
var result = activityCalendarUIService.checkResourceGrandTotalValue(filter, header, projectRow.Id, projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate,
|
|
parentRow, resRow.Id, resRow, isUOMHours, isAvgMode, $data, false);
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerResourceChanged(result);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, result);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, result);
|
|
dataChanged();
|
|
|
|
return false;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
$scope.checkTeamGrandTotalValueUnassigned = function (projectRow, expCatRow, teamRow, $data) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !teamRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
startDate = projectRow.ActiveScenario.StartDate,
|
|
endDate = projectRow.ActiveScenario.EndDate;
|
|
|
|
var result = activityCalendarUIService.checkTeamGrandTotalValue(filter, header, projectRow.Id, startDate, endDate, expCatRow, teamRow.Id, teamRow, isUOMHours, isAvgMode, $data);
|
|
onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, result);
|
|
return false;
|
|
};
|
|
$scope.takeRemaining = function (projectRow, expCatRow, resRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
parentRow = teamRow || expCatRow || {};
|
|
|
|
|
|
var result = activityCalendarUIService.takeRemainingCapacity(filter, header, projectRow.Id, projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate,
|
|
parentRow, resRow.Id, resRow, isUOMHours, isAvgMode);
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerResourceChanged(result);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, result);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, result);
|
|
dataChanged();
|
|
}
|
|
};
|
|
$scope.takeAll = function (projectRow, expCatRow, resRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
parentRow = teamRow || expCatRow || {};
|
|
|
|
|
|
var result = activityCalendarUIService.takeFullCapacity(filter, header, projectRow.Id, projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate,
|
|
parentRow, resRow.Id, resRow, isUOMHours, isAvgMode);
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerResourceChanged(result);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, result);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, result);
|
|
dataChanged();
|
|
}
|
|
};
|
|
$scope.zeroResource = function (projectRow, expCatRow, resRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
bootbox.confirm({
|
|
message: "Are you sure you want to fill this resource quantities with 0s?",
|
|
callback: function (result) {
|
|
$scope.$apply(function () {
|
|
if (result) {
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
parentRow = teamRow || expCatRow || { };
|
|
console.log('parentRow Type = ' +parentRow.RowType);
|
|
|
|
var changedCells = activityCalendarUIService.zeroResource(filter, header, projectRow.Id, projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate,
|
|
parentRow, resRow.Id, resRow, isUOMHours, isAvgMode);
|
|
if (typeof changedCells === 'object' && angular.isArray(changedCells) && changedCells.length > 0) {
|
|
triggerResourceChanged(changedCells);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, changedCells);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, changedCells);
|
|
dataChanged();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
};
|
|
$scope.removeResource = function (projectRow, expCatRow, teamRow, resRow, $index) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !resRow) {
|
|
return;
|
|
}
|
|
|
|
bootbox.confirm({
|
|
message: "Are you sure you want to remove this resource?",
|
|
callback: function (result) {
|
|
$scope.$apply(function () {
|
|
if (result) {
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
expCatId = (teamRow && teamRow.ExpenditureCategoryId) || expCatRow.Id,
|
|
parentRow = teamRow || expCatRow;
|
|
|
|
var changedCells = activityCalendarUIService.cleanAndRemoveResource(filter, header, projectRow.Id, projectRow.ActiveScenario.StartDate,
|
|
projectRow.ActiveScenario.EndDate, expCatId, parentRow, resRow.Id, resRow, isUOMHours, isAvgMode, $index);
|
|
if (typeof changedCells === 'object' && angular.isArray(changedCells) && changedCells.length > 0) {
|
|
triggerResourceChanged(changedCells);
|
|
recalculateResourceAvailability(resRow.Id);
|
|
refreshResourceStyles(resRow.Id, changedCells);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, projectRow, changedCells);
|
|
dataChanged();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
};
|
|
$scope.checkNptResourceValue = function (companyRow, nptTotalRow, nptCatRow, nptItemRow, nptResourceRow, $index, $data) {
|
|
if (!companyRow || !nptTotalRow || !nptCatRow || !nptItemRow || !nptResourceRow)
|
|
return;
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
|
|
|
|
var rollupRows = [];
|
|
rollupRows.push(nptTotalRow);
|
|
rollupRows.push(companyRow);
|
|
rollupRows.push(nptCatRow);
|
|
rollupRows.push(nptItemRow);
|
|
rollupRows.push($scope.ViewModel.TotalRow);
|
|
|
|
var result = activityCalendarUIService.checkNptResourceValue(filter, header, $scope.ViewModel.RemainingCapacityRow,
|
|
rollupRows, nptCatRow, nptItemRow, nptResourceRow, isUOMHours, isAvgMode, $index, $data);
|
|
|
|
// if result is not false it is incorrect one and we do not need to recalculate availability in this case
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerNptResourceChanged(result);
|
|
recalculateResourceAvailability(nptResourceRow.Id);
|
|
dataChanged();
|
|
return false;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
$scope.checkTeamWideNptValue = function (companyRow, nptTotalRow, nptCatRow, nptItemRow, $index, $data) {
|
|
if (!companyRow || !nptTotalRow || !nptCatRow || !nptItemRow)
|
|
return;
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
|
|
|
|
var rollupRows = [];
|
|
rollupRows.push(nptTotalRow);
|
|
rollupRows.push(companyRow);
|
|
rollupRows.push(nptCatRow);
|
|
rollupRows.push(nptItemRow);
|
|
rollupRows.push($scope.ViewModel.TotalRow);
|
|
|
|
var result = activityCalendarUIService.checkTeamWideNptValue(filter, header, $scope.ViewModel.RemainingCapacityRow,
|
|
rollupRows, nptCatRow, nptItemRow, isUOMHours, isAvgMode, $index, $data);
|
|
|
|
// if result is not false it is incorrect one and we do not need to recalculate availability in this case
|
|
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
|
|
triggerNptResourceChanged(result);
|
|
|
|
// Recalculate resource availability for all related resources
|
|
for (var i = 0; i < result.length; i++) {
|
|
recalculateResourceAvailability(result[i].ResourceId);
|
|
}
|
|
|
|
dataChanged();
|
|
return false;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
$scope.takeTeamRemainingUnassigned = function (projectRow, expCatRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !teamRow) {
|
|
return;
|
|
}
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
startDate = projectRow.ActiveScenario.StartDate,
|
|
endDate = projectRow.ActiveScenario.EndDate;
|
|
|
|
var result = activityCalendarUIService.takeTeamRemainingCapacity(filter, header, projectRow.Id, startDate, endDate,
|
|
expCatRow, teamRow, isUOMHours, isAvgMode);
|
|
onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, result);
|
|
};
|
|
$scope.takeTeamAllUnassigned = function (projectRow, expCatRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !teamRow)
|
|
return;
|
|
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
startDate = projectRow.ActiveScenario.StartDate,
|
|
endDate = projectRow.ActiveScenario.EndDate;
|
|
|
|
var result = activityCalendarUIService.takeTeamFullCapacity(filter, header, projectRow.Id, startDate, endDate,
|
|
expCatRow, teamRow, isUOMHours, isAvgMode);
|
|
onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, result);
|
|
};
|
|
$scope.zeroTeamUnassigned = function (projectRow, expCatRow, teamRow) {
|
|
if (!projectRow || !projectRow.ActiveScenario || !expCatRow || !teamRow) {
|
|
return;
|
|
}
|
|
|
|
bootbox.confirm({
|
|
message: "Are you sure you want to fill this Team allocations with 0s?",
|
|
callback: function (result) {
|
|
$scope.$apply(function () {
|
|
if (result) {
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
startDate = projectRow.ActiveScenario.StartDate,
|
|
endDate = projectRow.ActiveScenario.EndDate;
|
|
|
|
var changedCells = activityCalendarUIService.zeroTeam(filter, header, projectRow.Id, startDate,
|
|
endDate, expCatRow, teamRow, isUOMHours, isAvgMode);
|
|
onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, changedCells);
|
|
}
|
|
});
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
};
|
|
$scope.removeTeamUnassigned = function (prjRow, expCatRow, teamRow, $index) {
|
|
if (!prjRow || !prjRow.ActiveScenario || !expCatRow || !teamRow) {
|
|
return;
|
|
}
|
|
|
|
bootbox.confirm({
|
|
message: "Are you sure you want to remove this team?",
|
|
callback: function (result) {
|
|
$scope.$apply(function () {
|
|
if (result) {
|
|
var filter = $scope.Filter,
|
|
header = $scope.ViewModel.Header,
|
|
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
|
|
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
|
|
teamId = teamRow.Id,
|
|
startDate = prjRow.ActiveScenario.StartDate,
|
|
endDate = prjRow.ActiveScenario.EndDate;
|
|
|
|
var changedCellsByExpCats = activityCalendarUIService.cleanAndRemoveTeam(filter, header, prjRow, teamId, startDate,
|
|
endDate, isUOMHours, isAvgMode);
|
|
|
|
if ((typeof changedCellsByExpCats === 'object') && (Object.keys(changedCellsByExpCats).length > 0)) {
|
|
for (var expCatId in changedCellsByExpCats) {
|
|
var currentExpCatRow = changedCellsByExpCats[expCatId].ExpCatRow;
|
|
var changedCells = changedCellsByExpCats[expCatId].ChangedCells;
|
|
|
|
onChangeTeamDataUnassigned(filter, header, prjRow, currentExpCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, changedCells);
|
|
}
|
|
}
|
|
|
|
activityCalendarUIService.refreshProjectAvailableTeams($scope.Filter, prjRow);
|
|
}
|
|
});
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
};
|
|
$scope.watchKeyInput = function (t) {
|
|
activityCalendarUIService.watchKeyInput(t);
|
|
};
|
|
$scope.onTxtBlur = function (t) {
|
|
activityCalendarUIService.onTxtBlur(t);
|
|
};
|
|
|
|
/* 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(calendarDataUrl, filter, forceDataReload);
|
|
var nptCategories = dataSources.getNonProjectTimeCategories();
|
|
var loadCompaniesTask = dataSources.loadCompanies();
|
|
var cachedTemplates = activityCalendarUIService.cacheTemplates();
|
|
var dateRangeTask = dataSources.loadAvailableDateRange();
|
|
var allTasks = [loadCalendarTask, nptCategories, loadCompaniesTask, dateRangeTask].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];
|
|
nonProjectTimeCategoryCache = asyncResults[1];
|
|
|
|
createViewModel(calendar);
|
|
initBottomPart();
|
|
toggleParts();
|
|
toggleSortBy();
|
|
toggleHoursResourcesMode();
|
|
toggleBarsValuesMode();
|
|
toggleMonths();
|
|
$scope.$emit('ac.workflowactionsloaded');
|
|
unblockUI();
|
|
|
|
if (typeof successCallback === 'function') {
|
|
successCallback(calendar);
|
|
}
|
|
|
|
if (angular.isObject(calendar))
|
|
$scope.ViewModel.DataLoaded = true;
|
|
})
|
|
.then(null, function () {
|
|
unblockUI();
|
|
showErrorModal('Oops!', commonErrorMessage);
|
|
});
|
|
}).then(null, function () {
|
|
unblockUI();
|
|
showErrorModal('Oops!', commonErrorMessage);
|
|
});
|
|
};
|
|
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;
|
|
};
|
|
};
|
|
function dataChanged() {
|
|
$scope.$emit('ac.calendarDataChanged');
|
|
};
|
|
function onChangeTeamDataUnassigned(filter, header, projectRow, expCatRow, teamRow, startDate, endDate, isUOMHours, isAvgMode, changedCells) {
|
|
if (typeof changedCells === 'object' && angular.isArray(changedCells) && changedCells.length > 0) {
|
|
// Find out, if some categories where added to teams at bottom part
|
|
var needRecreateRows = activityCalendarUIService.categoryRowsWereAdded(changedCells);
|
|
|
|
if (needRecreateRows)
|
|
// Categories where added, we need to redraw all rows in bottom part
|
|
refreshBottomPart();
|
|
else
|
|
triggerTeamChanged(changedCells);
|
|
|
|
activityCalendarUIService.updateTotalRows(changedCells, teamRow, expCatRow, projectRow.Id, $scope.ViewModel.NoTeamRow,
|
|
$scope.ViewModel.Rows, $scope.ViewModel.Header, $scope.Filter, $scope.ViewModel.DisplayMode);
|
|
activityCalendarUIService.refreshProjectStyles($scope.ViewModel.NoTeamRow.Children, $scope.ViewModel.Header, $scope.Filter, projectRow, changedCells);
|
|
|
|
dataChanged();
|
|
}
|
|
};
|
|
|
|
/* Methods for preparing data */
|
|
function getDataModel(projects, noTeamProjects, filteredByView) {
|
|
if (!projects) {
|
|
return null;
|
|
}
|
|
|
|
var filteredByTeamsOrViews = activityCalendarUIService.isFilteredByTeams($scope.Filter);
|
|
var allocationMode = $scope.Filter.EntityType == activityCalendarUIService.filterEntityType.company ? activityCalendarUIService.allocationMode.needAllocation :
|
|
activityCalendarUIService.allocationMode.teamAllocation;
|
|
var result = {};
|
|
|
|
for (var projectId in projects) {
|
|
var project = projects[projectId];
|
|
if (!(project.CompanyId in result)) {
|
|
var company = dataSources.getCompanyById(project.CompanyId) || { Id: project.CompanyId, Name: 'Company is unknown' };
|
|
result[project.CompanyId] = {
|
|
Id: company.Id,
|
|
Name: company.Name,
|
|
AllocationMode: allocationMode,
|
|
Projects: {}
|
|
};
|
|
}
|
|
|
|
var extendedProjectModel = angular.extend({}, projects[projectId], {
|
|
AllocationMode: allocationMode
|
|
});
|
|
var projectExpenditures = activityCalendarUIService.getExpendituresWithResources4Project(extendedProjectModel, null, null, $scope.ViewModel.Header, $scope.Filter, true, filteredByTeamsOrViews, filteredByView);
|
|
if (projectExpenditures && Object.keys(projectExpenditures).length) {
|
|
result[extendedProjectModel.CompanyId].Projects[projectId] = {
|
|
Project: extendedProjectModel,
|
|
Expenditures: projectExpenditures
|
|
};
|
|
}
|
|
|
|
if (noTeamProjects) {
|
|
// put project to No Team section if there are any unassigned project need in this project
|
|
var noTeamProject = angular.extend({}, extendedProjectModel,
|
|
{ AllocationMode: activityCalendarUIService.allocationMode.remainingNeedAllocation });
|
|
// load data for project expenditures
|
|
var projectNoTeamsExpenditures = activityCalendarUIService.getExpenditures4Project(noTeamProject, null, $scope.Filter.ProjectRoles || [],
|
|
$scope.ViewModel.Header, $scope.Filter, true, false);
|
|
var ecKeys = Object.keys(projectNoTeamsExpenditures);
|
|
for (var i = 0; i < ecKeys.length; i++) {
|
|
if (projectNoTeamsExpenditures[ecKeys[i]].AllowResourceAssignment)
|
|
delete projectNoTeamsExpenditures[ecKeys[i]];
|
|
}
|
|
// remove rows where nothing to assign or to display
|
|
var projectNoTeamsExpendituresNonEmpty =
|
|
activityCalendarUIService.removeEmptyUnassignedExpenditures(projectId, projectNoTeamsExpenditures, $scope.Filter);
|
|
if (projectNoTeamsExpendituresNonEmpty && (Object.keys(projectNoTeamsExpendituresNonEmpty).length > 0)) {
|
|
noTeamProjects[projectId] = {
|
|
Project: noTeamProject,
|
|
Expenditures: projectNoTeamsExpendituresNonEmpty
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add companies without projects to display NPT
|
|
var teams = teamInfoService.getAll();
|
|
if (teams) {
|
|
for (var teamId in teams) {
|
|
var companyId = teams[teamId].CompanyId;
|
|
|
|
if (companyId && !(companyId in result)) {
|
|
var company = dataSources.getCompanyById(companyId) || { Id: companyId, Name: 'Company is unknown' };
|
|
result[companyId] = {
|
|
Id: company.Id,
|
|
Name: company.Name,
|
|
Projects: {}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/* Methods for creating view models */
|
|
function createViewModel(model) {
|
|
var projectExpenditures = {}; // cache for aggregated ECs by project for "group by companies" mode
|
|
var noTeamProjects = {};
|
|
createHeaderViewModel(model.WeekEndings);
|
|
createRowsViewModel(model, projectExpenditures, noTeamProjects);
|
|
fillViewModelWithData(model, projectExpenditures, noTeamProjects);
|
|
projectExpenditures = null;
|
|
noTeamProjects = null;
|
|
};
|
|
function createHeaderViewModel(weekEndings) {
|
|
$scope.ViewModel.Header = (new GridHeader(weekEndings || {}).create());
|
|
};
|
|
function createRowsViewModel(model, projectExpenditures, noTeamProjects) {
|
|
$scope.ViewModel.Rows = [];
|
|
$scope.ViewModel.NoTeamRow = null;
|
|
$scope.ViewModel.NonProjectTimeTotalRows = [];
|
|
|
|
if (!model || !model.Projects) {
|
|
return;
|
|
}
|
|
|
|
var filteredByView = $scope.Filter.EntityType == activityCalendarUIService.filterEntityType.view;
|
|
var businessUnitModels = getDataModel(model.Projects, noTeamProjects, filteredByView);
|
|
|
|
for (var businessUnitId in businessUnitModels) {
|
|
projectExpenditures[businessUnitId] = businessUnitModels[businessUnitId];
|
|
}
|
|
|
|
nonProjectTimeCache = activityCalendarUIService.getNonProjectTimeDataModel(nonProjectTimeCategoryCache, $scope.ViewModel.DisplayMode.GroupBy.Value);
|
|
|
|
// Set Team-wide npts read-only for current view, because the displayed partially
|
|
activityCalendarUIService.setTeamWideNptItemsReadOnly(nonProjectTimeCache);
|
|
|
|
if (projectExpenditures && Object.keys(projectExpenditures).length) {
|
|
// sort companies by name
|
|
var sortedCompanies = $filter('sortObjectsBy')(projectExpenditures, 'Name', false);
|
|
for (var i = 0; i < sortedCompanies.length; i++) {
|
|
var companyData = sortedCompanies[i];
|
|
var companyViewModel = activityCalendarUIService.createViewModel4Company(companyData, $scope.Filter);
|
|
if (companyViewModel) {
|
|
setTooltips(companyViewModel);
|
|
var companyNptData = (nonProjectTimeCache && (companyData.Id in nonProjectTimeCache)) ?
|
|
nonProjectTimeCache[companyData.Id] : null;
|
|
|
|
var companyNptModel = activityCalendarUIService.createViewModel4NptTotalRow('Non-Project Time', companyNptData);
|
|
companyViewModel.NonProjectTime = companyNptModel;
|
|
$scope.ViewModel.NonProjectTimeTotalRows.push(companyNptModel);
|
|
|
|
$scope.ViewModel.Rows.push(companyViewModel);
|
|
}
|
|
}
|
|
}
|
|
if (noTeamProjects && Object.keys(noTeamProjects).length) {
|
|
$scope.ViewModel.NoTeamRow = activityCalendarUIService.createViewModel4TotalRow('No Team');
|
|
$scope.ViewModel.NoTeamRow.AllocationMode = activityCalendarUIService.allocationMode.remainingNeedAllocation;
|
|
$scope.ViewModel.NoTeamRow.Children = activityCalendarUIService.createViewModel4Projects(noTeamProjects);
|
|
|
|
for (var pIndex = 0; pIndex < $scope.ViewModel.NoTeamRow.Children.length; pIndex++) {
|
|
var projectRow = $scope.ViewModel.NoTeamRow.Children[pIndex];
|
|
projectRow.getTooltipContent = $scope.getTooltipProjectUnassignedContent;
|
|
|
|
if (projectRow.Children) {
|
|
for (var ecIndex = 0; ecIndex < projectRow.Children.length; ecIndex++) {
|
|
var ecRow = projectRow.Children[ecIndex];
|
|
if (ecRow) {
|
|
ecRow.getTooltipContent = $scope.getTooltipEcUnassignedContent;
|
|
ecRow.AvailableTeams = activityCalendarUIService.getAvailableTeams(projectRow.Id, ecRow.Id);
|
|
activityCalendarUIService.setNoTeamRowTemplates(ecRow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Create total rows
|
|
createTotalRowModels();
|
|
};
|
|
function setTooltips(companyRow) {
|
|
if (!companyRow || !companyRow.Children)
|
|
return;
|
|
|
|
for (var pIndex = 0; pIndex < companyRow.Children.length; pIndex++) {
|
|
var projectRow = companyRow.Children[pIndex];
|
|
|
|
if (projectRow && projectRow.Children) {
|
|
for (var ecIndex = 0; ecIndex < projectRow.Children.length; ecIndex++) {
|
|
var expCatRow = projectRow.Children[ecIndex];
|
|
|
|
if (expCatRow) {
|
|
expCatRow.getTooltipContent = $scope.getTooltipContent;
|
|
if (expCatRow.Children && expCatRow.Children.length) {
|
|
for (var teamKey in expCatRow.Children) { // set tooltips for child team rows
|
|
var teamRow = expCatRow.Children[teamKey];
|
|
if (teamRow.RowType != 'Team') // if child is not a team (e.g. resource) then do not set tooltips
|
|
break;
|
|
if (teamRow) {
|
|
teamRow.getTooltipContent = $scope.getTooltipContent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
function createTotalRowModels() {
|
|
$scope.ViewModel.TotalRow = activityCalendarUIService.createViewModel4TotalRow('Total');
|
|
$scope.ViewModel.RemainingCapacityRow = activityCalendarUIService.createViewModel4TotalRow('Remaining Capacity');
|
|
};
|
|
function getTotalRows() {
|
|
var rows = [];
|
|
|
|
if ($scope.ViewModel.TotalRow) {
|
|
rows.push($scope.ViewModel.TotalRow);
|
|
}
|
|
if ($scope.ViewModel.RemainingCapacityRow) {
|
|
rows.push($scope.ViewModel.RemainingCapacityRow);
|
|
}
|
|
return rows;
|
|
};
|
|
function getResourceRows(resourceId) {
|
|
var result = activityCalendarUIService.getResourceRows($scope.ViewModel.Rows, resourceId);
|
|
return result;
|
|
};
|
|
|
|
/* Root methods for creating view models and filling them with data */
|
|
function fillViewModelWithData(model, projectExpenditures, noTeamProjects) {
|
|
if (!$scope.ViewModel.Rows) {
|
|
return;
|
|
}
|
|
|
|
var filteredByView = $scope.Filter.EntityType == activityCalendarUIService.filterEntityType.view;
|
|
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
|
|
var companyRow = $scope.ViewModel.Rows[i];
|
|
var projectExpenditures = projectExpenditures[companyRow.Id] || {};
|
|
|
|
for (var j = 0; j < companyRow.Children.length; j++) {
|
|
var project = companyRow.Children[j];
|
|
var projectData = (projectExpenditures.Projects || {})[project.Id] || {};
|
|
activityCalendarUIService.fillProjectRowWithData(companyRow, project, projectData.Expenditures, $scope.ViewModel.Header, $scope.Filter, filteredByView);
|
|
}
|
|
|
|
if (companyRow.NonProjectTime) {
|
|
var companyNptData = (companyRow.Id in nonProjectTimeCache) ? nonProjectTimeCache[companyRow.Id] : null;
|
|
activityCalendarUIService.fillTotalNptRowData(companyRow.NonProjectTime, companyNptData, $scope.ViewModel.Header, [companyRow]);
|
|
}
|
|
}
|
|
|
|
// Clear NPT caches. Caches not need more
|
|
nonProjectTimeCache = {};
|
|
nonProjectTimeCategoryCache = {};
|
|
|
|
// Fill No Team section
|
|
if ($scope.ViewModel.NoTeamRow && $scope.ViewModel.NoTeamRow.Children && $scope.ViewModel.NoTeamRow.Children.length) {
|
|
var noTeamProject = noTeamProjects || {};
|
|
|
|
for (var j = 0; j < $scope.ViewModel.NoTeamRow.Children.length; j++) {
|
|
var project = $scope.ViewModel.NoTeamRow.Children[j];
|
|
var projectData = (noTeamProject || {})[project.Id] || {};
|
|
|
|
activityCalendarUIService.fillProjectRowWithData(null, project, projectData.Expenditures, $scope.ViewModel.Header, $scope.Filter);
|
|
if (project.Children) {
|
|
for (var ecIndex = 0; ecIndex < project.Children.length; ecIndex++) {
|
|
var ecRow = project.Children[ecIndex];
|
|
ecRow.RemainingCapacityValues = angular.extend([], ecRow.RemainingNeedHoursValues);
|
|
}
|
|
}
|
|
// add additional ec-team rows for recently added teams
|
|
if (projectData && projectData.Project && projectData.Project.Teams) {
|
|
angular.forEach(projectData.Project.Teams, function (pTeamCache, teamKey) {
|
|
// we should care only about pending (newly assigned)/saved pending (assigned multiple times) teams
|
|
var type = pTeamCache.Type || activityCalendarService.TeamType.Saved;
|
|
if (type !== activityCalendarService.TeamType.Saved && pTeamCache.Expenditures2Display && project.Children) {
|
|
for (var ecIndex = 0; ecIndex < project.Children.length; ecIndex++) {
|
|
var ecRow = project.Children[ecIndex];
|
|
if (ecRow.Id in pTeamCache.Expenditures2Display) {
|
|
createAndFillNewEcTeamRow(project, ecRow, teamKey);
|
|
// expand project row
|
|
if (project.Collapsed)
|
|
activityCalendarUIService.toggleRow(project, {}, false);
|
|
// expand ec row
|
|
if (ecRow.Collapsed)
|
|
activityCalendarUIService.toggleRow(ecRow, {}, false);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
activityCalendarUIService.refreshProjectAvailableTeams($scope.Filter, project);
|
|
}
|
|
activityCalendarUIService.fillTotalRowData($scope.ViewModel.NoTeamRow.Children, $scope.ViewModel.NoTeamRow, $scope.ViewModel.Header);
|
|
}
|
|
|
|
// Fill total rows with data
|
|
fillTotalRowsWithData();
|
|
};
|
|
function fillTotalRowsWithData() {
|
|
var startDate = new Date().getTime();
|
|
var rowsForTotal = angular.copy($scope.ViewModel.Rows) || [];
|
|
|
|
if ($scope.ViewModel.NonProjectTimeTotalRows && ($scope.ViewModel.NonProjectTimeTotalRows.length > 0)) {
|
|
rowsForTotal = rowsForTotal.concat(angular.copy($scope.ViewModel.NonProjectTimeTotalRows));
|
|
}
|
|
if ($scope.ViewModel.NoTeamRow && $scope.Filter.EntityType !== activityCalendarUIService.filterEntityType.company) {
|
|
rowsForTotal = rowsForTotal.concat(angular.copy($scope.ViewModel.NoTeamRow));
|
|
}
|
|
|
|
activityCalendarUIService.fillTotalRowData(rowsForTotal, $scope.ViewModel.TotalRow, $scope.ViewModel.Header);
|
|
activityCalendarUIService.fillRemainingCapacityRowData($scope.ViewModel.TotalRow, $scope.ViewModel.RemainingCapacityRow, $scope.ViewModel.Header, $scope.ViewModel.DisplayMode.IsCapacityModeActuals.Value);
|
|
var endDate = new Date().getTime();
|
|
console.log('filling total rows with data: ' + (endDate - startDate) + ' ms');
|
|
};
|
|
function createAndFillNewEcTeamRow(projectRow, expCatRow, teamId) {
|
|
var teamInfo = teamInfoService.getById(teamId);
|
|
activityCalendarUIService.createAndFillNewEcTeamRow(projectRow, expCatRow, teamId, teamInfo,
|
|
$scope.ViewModel.Header, $scope.ViewModel.DisplayMode, $scope.Filter);
|
|
};
|
|
|
|
/* Methods for toggling display modes */
|
|
function toggleHoursResourcesMode() {
|
|
var totalRows = getTotalRows();
|
|
activityCalendarUIService.toggleGridSource($scope.ViewModel.NonProjectTimeTotalRows, $scope.ViewModel.DisplayMode.IsUOMHours);
|
|
activityCalendarUIService.toggleGridSource($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.IsUOMHours);
|
|
activityCalendarUIService.toggleGridSource(totalRows, $scope.ViewModel.DisplayMode.IsUOMHours);
|
|
if ($scope.ViewModel.NoTeamRow) {
|
|
activityCalendarUIService.toggleGridSource([$scope.ViewModel.NoTeamRow], $scope.ViewModel.DisplayMode.IsUOMHours);
|
|
}
|
|
|
|
if ($scope.ViewModel.DisplayMode.IsAvgMode()) {
|
|
activityCalendarUIService.applyAvgMode($scope.ViewModel.NonProjectTimeTotalRows, $scope.ViewModel.Header);
|
|
activityCalendarUIService.applyAvgMode($scope.ViewModel.Rows, $scope.ViewModel.Header);
|
|
activityCalendarUIService.applyAvgMode(totalRows, $scope.ViewModel.Header);
|
|
if ($scope.ViewModel.NoTeamRow) {
|
|
activityCalendarUIService.applyAvgMode([$scope.ViewModel.NoTeamRow], $scope.ViewModel.Header);
|
|
}
|
|
}
|
|
};
|
|
function toggleBarsValuesMode() {
|
|
if (!$scope.ViewModel.Rows || !$scope.ViewModel.Rows.length) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
|
|
var projects = $scope.ViewModel.Rows[i].Children;
|
|
if (projects) {
|
|
activityCalendarUIService.toggleBarsValuesMode(projects, $scope.ViewModel.DisplayMode.IsBarMode);
|
|
}
|
|
}
|
|
if ($scope.ViewModel.NoTeamRow && $scope.ViewModel.NoTeamRow.Children) {
|
|
activityCalendarUIService.toggleBarsValuesMode($scope.ViewModel.NoTeamRow.Children, $scope.ViewModel.DisplayMode.IsBarMode);
|
|
}
|
|
};
|
|
function toggleMonths() {
|
|
if ($scope.ViewModel.DisplayMode.IsViewModeMonth) {
|
|
$scope.ViewModel.Header.collapseMonthes();
|
|
}
|
|
else {
|
|
$scope.ViewModel.Header.expandMonthes();
|
|
}
|
|
};
|
|
function toggleParts() {
|
|
if (!$scope.ViewModel || !$scope.ViewModel.Rows)
|
|
return;
|
|
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
|
|
var companyRow = $scope.ViewModel.Rows[i];
|
|
if (companyRow.Children && companyRow.Children.length > 0) {
|
|
companyRow.Children = activityCalendarUIService.toggleParts(companyRow.Children, $scope.ViewModel.DisplayMode.ShowParts.Value);
|
|
activityCalendarUIService.updateProjectStyles($scope.ViewModel.Header, $scope.Filter, companyRow.Children);
|
|
}
|
|
}
|
|
if ($scope.ViewModel.NoTeamRow && $scope.ViewModel.NoTeamRow.Children && $scope.ViewModel.NoTeamRow.Children.length) {
|
|
$scope.ViewModel.NoTeamRow.Children = activityCalendarUIService.toggleParts($scope.ViewModel.NoTeamRow.Children, $scope.ViewModel.DisplayMode.ShowParts.Value);
|
|
activityCalendarUIService.updateProjectStyles($scope.ViewModel.Header, $scope.Filter, $scope.ViewModel.NoTeamRow.Children);
|
|
}
|
|
};
|
|
function toggleSortBy() {
|
|
if (!$scope.ViewModel || !$scope.ViewModel.Rows)
|
|
return;
|
|
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
|
|
var companyRow = $scope.ViewModel.Rows[i];
|
|
if (companyRow.Children && companyRow.Children.length > 0) {
|
|
companyRow.Children = activityCalendarUIService.toggleSortBy(companyRow.Children, $scope.ViewModel.DisplayMode.SortBy, $scope.ViewModel.DisplayMode.SortOrder);
|
|
}
|
|
}
|
|
if ($scope.ViewModel.NoTeamRow && $scope.ViewModel.NoTeamRow.Children && $scope.ViewModel.NoTeamRow.Children.length) {
|
|
$scope.ViewModel.NoTeamRow.Children = activityCalendarUIService.toggleSortBy($scope.ViewModel.NoTeamRow.Children, $scope.ViewModel.DisplayMode.SortBy, $scope.ViewModel.DisplayMode.SortOrder);
|
|
}
|
|
};
|
|
function toggleCapacityType() {
|
|
// reset total row values
|
|
createTotalRowModels();
|
|
// recalculate total row UI data
|
|
fillTotalRowsWithData();
|
|
toggleHoursResourcesMode();
|
|
};
|
|
function recalculateResourceAvailability(resourceId) {
|
|
if (!resourceId || !$scope.ViewModel.Rows) {
|
|
return;
|
|
}
|
|
|
|
for (var rowIndex = 0; rowIndex < $scope.ViewModel.Rows.length; rowIndex++) {
|
|
var companyRow = $scope.ViewModel.Rows[rowIndex];
|
|
if (companyRow && companyRow.Children) {
|
|
activityCalendarUIService.recalculateResourceAvailability($scope.Filter, $scope.ViewModel.Header, companyRow.Children, resourceId);
|
|
}
|
|
}
|
|
};
|
|
function initBottomPart() {
|
|
// need to pass new objects for preventing using single instances of objects inside current and other controllers
|
|
$scope.$broadcast('rebindTeamInfo', {
|
|
Header: $scope.ViewModel.Header,
|
|
DisplayMode: activityCalendarUIService.castDisplayModeIntoTeamInfoMode($scope.ViewModel.DisplayMode),
|
|
});
|
|
};
|
|
function refreshBottomPart() {
|
|
$scope.$broadcast('teaminfo.recreateRows');
|
|
};
|
|
function triggerResourceChanged(data) {
|
|
if (typeof data !== 'object' || !angular.isArray(data)) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
$scope.$broadcast('resourceValueChanged', data[i]);
|
|
}
|
|
};
|
|
function triggerTeamChanged(data) {
|
|
if (typeof data !== 'object' || !angular.isArray(data)) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
$scope.$broadcast('teamValueChanged', data[i]);
|
|
}
|
|
};
|
|
function triggerNptResourceChanged(data) {
|
|
if (typeof data !== 'object' || !angular.isArray(data)) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
$scope.$broadcast('resourceNonProjectTimeChanged', data[i]);
|
|
}
|
|
};
|
|
function refreshResourceStyles(resourceId, data) {
|
|
if (!resourceId || typeof data !== 'object' || !angular.isArray(data)) {
|
|
return;
|
|
}
|
|
|
|
var resourceRows = getResourceRows(resourceId);
|
|
if (!resourceRows || !resourceRows.length) {
|
|
return;
|
|
}
|
|
|
|
activityCalendarUIService.updateResourceStyles($scope.ViewModel.Header, resourceId, resourceRows, data);
|
|
};
|
|
|
|
/* ===== 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;
|
|
};
|
|
$scope.getTooltipProjectUnassignedContent = function (opts) {
|
|
return activityCalendarUIService.getTooltipProjectUnassignedContent(opts, $scope.ViewModel.DisplayMode, $scope.Filter, $scope.ViewModel.Header, $scope.ViewModel.NoTeamRow.Children);
|
|
};
|
|
$scope.getTooltipEcUnassignedContent = function (opts) {
|
|
return activityCalendarUIService.getTooltipEcUnassignedContent(opts, $scope.ViewModel.DisplayMode, $scope.Filter, $scope.ViewModel.Header, $scope.ViewModel.NoTeamRow.Children);
|
|
};
|
|
}]); |