1044 lines
66 KiB
Plaintext
1044 lines
66 KiB
Plaintext
@using EnVisage.Code
|
||
@using EnVisage.Models
|
||
@using Microsoft.AspNet.Identity
|
||
@model Object
|
||
@{
|
||
var user = (new EnVisage.Code.Cache.UsersCache()).Value.FirstOrDefault(x => x.Id == new Guid(User.Identity.GetID()));
|
||
var menuId = (Model is CapacityDetailsOptionsModel ? ((CapacityDetailsOptionsModel)Model).MenuId : "visibilitydropdown_calendar");
|
||
CapacityPageInitOption initDataObject = new CapacityPageInitOption()
|
||
{
|
||
ShowUpper = true,
|
||
ShowLower = false,
|
||
IsUOMHours = user != null && !user.PreferredResourceAllocation,
|
||
PreferredTotalsDisplaying = user != null && user.PreferredTotalsDisplaying,
|
||
IsBarMode = false,
|
||
IsViewModeMonth = true,
|
||
IsCapacityModeActuals = false,
|
||
GroupByTeam = false,
|
||
ShowCapacity = 1,
|
||
StartDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).ToString("MM/dd/yyyy"),
|
||
EndDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).AddMonths(6).ToString("MM/dd/yyyy"),
|
||
MenuId = menuId,
|
||
ModelType = Model != null ? Model.GetType().ToString() : string.Empty,
|
||
PagePreferences = user.GetPreferences(Request.Url.AbsolutePath, "capacityManagementView"),
|
||
DataSection = "capacityManagementView",
|
||
};
|
||
|
||
if (Model is CapacityDetailsModel)
|
||
{
|
||
initDataObject.CompanyId = ((CapacityDetailsModel)Model).CompanyId;
|
||
initDataObject.ViewId = ((CapacityDetailsModel)Model).ViewId;
|
||
initDataObject.TeamId = ((CapacityDetailsModel)Model).TeamId;
|
||
initDataObject.ResourceId = ((CapacityDetailsModel)Model).ResourceId;
|
||
initDataObject.FilterOptions = ((CapacityDetailsModel)Model).OptionsForFilters;
|
||
initDataObject.PageTitle = "calendar"; // SA. Backurl page name - to return to this page
|
||
}
|
||
|
||
if (Model is ViewBoardModel)
|
||
{
|
||
initDataObject.ViewId = ((ViewBoardModel)Model).SelectedViewId;
|
||
initDataObject.PageTitle = "dashboard"; // SA. Backurl page name - to return to this page
|
||
}
|
||
|
||
if (Model is TeamboardModel)
|
||
{
|
||
initDataObject.TeamId = ((TeamboardModel)Model).SelectedTeamId;
|
||
initDataObject.PageTitle = "dashboard"; // SA. Backurl page name - to return to this page
|
||
}
|
||
|
||
if (Model is PeopleResourceModel)
|
||
{
|
||
initDataObject.ResourceId = ((PeopleResourceModel)Model).Id;
|
||
initDataObject.PageTitle = "dashboard"; // SA. Backurl page name - to return to this page
|
||
}
|
||
|
||
var json = Newtonsoft.Json.JsonConvert.SerializeObject(initDataObject);
|
||
}
|
||
<div id="erorMsgPlaceholder"></div>
|
||
<script type="text/javascript">
|
||
var _menuCM;
|
||
var _pageCMPreferences = [];
|
||
var angularScope;
|
||
var liHeight = 30;
|
||
var _saveScenarioDataChanged = false;
|
||
function onSSDataChanged() {
|
||
_saveScenarioDataChanged = true;
|
||
}
|
||
function resetSSDataChanged() {
|
||
_saveScenarioDataChanged = false;
|
||
}
|
||
function isSSDataChanged() {
|
||
return _saveScenarioDataChanged;
|
||
}
|
||
|
||
function initSwitchers() {
|
||
$('#showTopMode').switcher({
|
||
on_state_content: 'On',
|
||
off_state_content: 'Off'
|
||
});
|
||
$('#showButtomMode').switcher({
|
||
on_state_content: 'On',
|
||
off_state_content: 'Off'
|
||
});
|
||
$('#sortOrder').switcher({
|
||
on_state_content: 'Asc',
|
||
off_state_content: 'Desc'
|
||
});
|
||
|
||
if (!$('#showButtomMode').prop('checked'))
|
||
$("#showTopMode").switcher('disable');
|
||
|
||
if (!$('#showTopMode').prop('checked'))
|
||
$("#showButtomMode").switcher('disable');
|
||
|
||
$("#saveScenarioModal").find('#is-active-scenario').switcher({
|
||
on_state_content: 'Active',
|
||
off_state_content: 'Inactive'
|
||
}).parent().css('width', '100px');
|
||
|
||
@if (!(Model is TeamboardModel))
|
||
{
|
||
<text>
|
||
$('#groupByTeam').switcher({
|
||
on_state_content: 'On',
|
||
off_state_content: 'Off'
|
||
});
|
||
</text>
|
||
}
|
||
$('#uomMode').switcher({
|
||
on_state_content: '# Hours',
|
||
off_state_content: '# Resources'
|
||
});
|
||
$('#uomMode').parent().css("width", "93px");
|
||
$('#capBarMode').switcher({
|
||
on_state_content: 'Colors',
|
||
off_state_content: 'Values'
|
||
});
|
||
$('#capBarMode').parent().css("width", "73px");
|
||
|
||
$('#defaultView').switcher({
|
||
on_state_content: 'Month',
|
||
off_state_content: 'Week'
|
||
});
|
||
$('#defaultView').parent().css("width", "93px");
|
||
|
||
// SA. ENV-886
|
||
@if (Model is PeopleResourceModel)
|
||
{
|
||
<text>
|
||
$('#capacityView').prop('checked', true);
|
||
</text>
|
||
}
|
||
|
||
$('#capacityView').switcher({
|
||
on_state_content: 'Actual',
|
||
off_state_content: 'Planned'
|
||
});
|
||
$('#capacityView').parent().css("width", "93px");
|
||
|
||
// SA. ENV-886
|
||
@if (Model is PeopleResourceModel)
|
||
{
|
||
<text>
|
||
$('#capacityView').switcher('disable');
|
||
</text>
|
||
}
|
||
|
||
}
|
||
|
||
init.push(function () {
|
||
var options = {
|
||
format: 'mm/dd/yyyy',
|
||
autoclose: true,
|
||
orientation: $('body').hasClass('right-to-left') ? "auto right" : 'auto auto',
|
||
startDate: '@Constants.MIN_SELECTABLE_DATE',
|
||
endDate: '@Constants.MAX_SELECTABLE_DATE'
|
||
};
|
||
|
||
$('#bs-datepicker-range').datepicker(options).on('changeDate', function (evt) {
|
||
onCMPreferencesItemClick($('#@menuId'));
|
||
if (evt.target.id == 'filterStartDate') {
|
||
var sDate = undefined;
|
||
var tmpValue = $('#filterStartDate').val();
|
||
var endDateValue = $('#filterEndDate').val();
|
||
|
||
if (tmpValue && (tmpValue.length > 0))
|
||
sDate = new Date(tmpValue);
|
||
|
||
if (!endDateValue || (endDateValue.length > 0)) {
|
||
$('#bs-datepicker-range').data('datepicker').pickers[1].prepopulate(sDate);
|
||
}
|
||
|
||
$('#filterEndDate').data('datepicker').setStartDate(sDate);
|
||
}
|
||
});
|
||
|
||
$('#saveScenarioModal').find('input[type=checkbox],input[type=text],select,textarea').on("change", function () {
|
||
if (typeof onSSDataChanged === 'function')
|
||
onSSDataChanged();
|
||
});
|
||
|
||
$(document).on('hide.bs.modal', '#saveScenarioModal', function (e) {
|
||
if ($(e.target).attr('id') != 'saveScenarioModal') {
|
||
$("#saveScenarioModal").focus();
|
||
return true; // close modal form
|
||
}
|
||
if (typeof isSSDataChanged === 'function')
|
||
if (isSSDataChanged()) {
|
||
if (confirm("Scenario Save form contains unsaved changes, do you really want to close the form?")) {
|
||
if (typeof resetSSDataChanged === 'function') {
|
||
resetSSDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
$("#saveScenarioModal").focus();
|
||
return false; // DO NOT close modal form
|
||
}
|
||
$("#saveScenarioModal").focus();
|
||
return true; // close modal form
|
||
}).on('show.bs.modal', '#saveScenarioModal', function (e) {
|
||
if (typeof resetSSDataChanged === 'function') {
|
||
resetSSDataChanged();
|
||
}
|
||
}).on('calendar.scenario-saved', function () {
|
||
if (typeof resetSSDataChanged === 'function') {
|
||
resetSSDataChanged();
|
||
}
|
||
$("#saveScenarioModal").modal('hide');
|
||
});
|
||
|
||
$(window).scroll(function () {
|
||
$('.menuGroup').removeClass('open');
|
||
hideRedundantPopovers($('#dataTable2_CFB'), null);
|
||
});
|
||
|
||
$('.table-light').scroll(function () {
|
||
$('.menuGroup').removeClass('open');
|
||
hideRedundantPopovers($('#dataTable2_CFB'), null);
|
||
});
|
||
$(document).click(function (event) {
|
||
if (!$(event.target).is('[data-toggled="popover"]'))
|
||
hideRedundantPopovers($('#dataTable2_CFB'), null);
|
||
});
|
||
|
||
$('.for-select2,#save-type').select2({
|
||
minimumResultsForSearch: -1
|
||
});
|
||
$('[name=selFilterElement]').select2();
|
||
$('.for-select2 a').css('line-height', '30px');
|
||
|
||
|
||
initSwitchers();
|
||
|
||
angularScope = angular.element(document.getElementById('controller1')).scope();
|
||
$(document).on('hide.bs.modal', '#createScenario', function (e) {
|
||
// skip modal hide event from datepickers
|
||
if ($(e.target).attr('id') != 'createScenario')
|
||
return true; // close modal form
|
||
// check that form has been changed
|
||
if (typeof isScenarioDataChanged === 'function')
|
||
// if form has been changed
|
||
if (isScenarioDataChanged()) {
|
||
// ask user for confirmation of form close
|
||
if (confirm('@EnVisage.Code.Constants.CONFIRM_CREATE_SCENARIO')) {
|
||
// reset change indicator
|
||
if (typeof resetScenarioDataChanged === 'function') {
|
||
resetScenarioDataChanged();
|
||
}
|
||
return true; // close modal form
|
||
};
|
||
return false; // DO NOT close modal form
|
||
}
|
||
return true; // close modal form
|
||
});
|
||
|
||
|
||
$('#filterForm').validate();
|
||
$('#filterForm').valid();
|
||
});
|
||
function onCMPreferencesItemClick(menu) {
|
||
saveCapacityManagementPreferences();
|
||
}
|
||
|
||
function dropDownFixPositionCalendar(button, dropdown) {
|
||
|
||
setDropdownProps(button, dropdown, liHeight);
|
||
|
||
|
||
hideRedundantPopovers($('#dataTable2_CFB'), null);
|
||
}
|
||
|
||
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 changeCapacityView(val) {
|
||
angularScope.$apply(function () {
|
||
angularScope.changeCapacity(val.value);
|
||
});
|
||
}
|
||
|
||
function changeSortColumn(val) {
|
||
angular.element(document.getElementById('controller1')).scope().changeSortBy(val.value);
|
||
}
|
||
|
||
function switchSortOrder(val) {
|
||
angular.element(document.getElementById('controller1')).scope().switchSortOrder();
|
||
}
|
||
|
||
function switchUOMMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchUOMMode();
|
||
}
|
||
|
||
function switchBarMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchBarMode();
|
||
}
|
||
|
||
function switchViewMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchViewMode();
|
||
}
|
||
|
||
function switchGroupByTeam() {
|
||
angular.element(document.getElementById('controller1')).scope().switchGroupByTeam();
|
||
}
|
||
|
||
function switchCapacityViewMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchCapacityVew();
|
||
}
|
||
|
||
// SA. ENV-799. Begin
|
||
function switchToCompanyFilterMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchCompanyFilterMode();
|
||
}
|
||
|
||
function switchToViewFilterMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchViewFilterMode();
|
||
}
|
||
|
||
function switchToTeamFilterMode() {
|
||
angular.element(document.getElementById('controller1')).scope().switchTeamFilterMode();
|
||
}
|
||
// SA. ENV-799. End
|
||
|
||
function switchShow(upper) {
|
||
angularScope.hideCalendarPart(upper);
|
||
}
|
||
|
||
// SA. ENV-815
|
||
function saveCapacityManagementPreferences() {
|
||
var section = getDataSection($("#menuCalendarOptions"));
|
||
var prefs = collectPreferences(section);
|
||
|
||
prefs.push({
|
||
Key: "filteredCompany",
|
||
Value: angular.element(document.getElementById('controller1')).scope().CalendarFilterMode.SelectedItemId
|
||
});
|
||
|
||
saveUserPagePreferences(prefs, section);
|
||
}
|
||
|
||
// SA. ENV-815
|
||
function loadCapacityManagementPreferences() {
|
||
var section = getDataSection($("#menuCalendarOptions"));
|
||
_pageCMPreferences = loadUserPagePreferences(section);
|
||
return section;
|
||
}
|
||
|
||
function loadScenario(projectId) {
|
||
var url = "?Id=" + projectId;
|
||
$('#reloadForm').load('@Url.Action("LoadScenario", "Scenarios")' + url, function () {
|
||
if (typeof initScenario === 'function')
|
||
initScenario();
|
||
$('#createScenario').modal('show');
|
||
});
|
||
}
|
||
|
||
</script>
|
||
|
||
<style type="text/css">
|
||
.validation-error {
|
||
color: red;
|
||
}
|
||
|
||
#table thead {
|
||
border-collapse: separate;
|
||
border-spacing: 0;
|
||
}
|
||
|
||
#table thead tr th {
|
||
-moz-background-clip: padding-box;
|
||
-webkit-background-clip: padding-box;
|
||
background-clip: padding-box;
|
||
border-top: 1.1px solid;
|
||
border-right: 1.1px solid;
|
||
}
|
||
|
||
.editable-input {
|
||
width: 140px;
|
||
}
|
||
</style>
|
||
|
||
<!-- / Large modal -->
|
||
<div id="controller1" ng-controller="capacityManagementController" ng-init="init(@json)" ng-cloak>
|
||
<div id="menuCalendarOptions" ng-show="false">
|
||
<ul>
|
||
@if (!(Model is PeopleResourceModel))
|
||
{
|
||
<text>
|
||
<li class="padding-xs-hr">
|
||
<span class="switcherLbl">Resource Totals as </span>
|
||
<select id="selectOptions" data-key="showOption" class="form-control for-select2" style="padding: 3px"
|
||
onchange="changeCapacityView(this)">
|
||
<option value="1">Allocated/Capacity</option>
|
||
<option value="2">Need/Capacity</option>
|
||
<option value="3">Allocated/Need</option>
|
||
<option value="4">Remaining/Capacity</option>
|
||
</select>
|
||
</li>
|
||
</text>
|
||
}
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Mode</span><input type="checkbox" data-key="uomMode" name="uomMode" id="uomMode" class="switcher px" onclick="switchUOMMode()" /></label>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Projects Displayed as</span><input type="checkbox" data-key="capBarMode" name="capBarMode" id="capBarMode" class="switcher px" onclick="switchBarMode()" /></label>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Default View</span><input type="checkbox" data-key="defaultView" name="defaultView" id="defaultView" class="switcher px" onclick="switchViewMode()" /></label>
|
||
</li>
|
||
@if (!(Model is TeamboardModel) && !(Model is PeopleResourceModel))
|
||
{
|
||
<text>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Group by Team</span><input type="checkbox" data-key="groupByTeam" name="groupByTeam" id="groupByTeam" class="switcher px" onclick="switchGroupByTeam()" /></label>
|
||
</li>
|
||
</text>
|
||
}
|
||
@if (!(Model is PeopleResourceModel))
|
||
{
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Use Capacity</span><input type="checkbox" data-key="capacityView" name="capacityView" id="capacityView" class="switcher px" onclick="switchCapacityViewMode()" /></label>
|
||
</li>
|
||
}
|
||
<li class="divider"></li>
|
||
<li class="padding-xs-hr" style="padding-bottom:3px;">
|
||
<nobr>
|
||
<span class="switcherLbl" style="padding-top:3px;">Sort By </span>
|
||
<select id="sortBy" data-key="sortBy" class="form-control for-select2" style="width: 100px;"
|
||
onchange="changeSortColumn(this)">
|
||
<option value="Name">Name</option>
|
||
<option value="Type">Type</option>
|
||
<option value="Date">Date</option>
|
||
<option value="Priority">Priority</option>
|
||
</select>
|
||
</nobr>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Sort Order</span><input type="checkbox" data-key="sortOrder" name="sortOrder" id="sortOrder" class="switcher px" onclick="switchSortOrder()" /></label>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Show Projects</span><input type="checkbox" data-key="showChart" name="showTopMode" id="showTopMode" class="switcher px" checked onclick="switchShow(true)" /></label>
|
||
</li>
|
||
@if (!(Model is PeopleResourceModel))
|
||
{
|
||
<text>
|
||
<li class="padding-xs-hr">
|
||
<label><span class="switcherLbl">Show Resources</span><input type="checkbox" data-key="showCriteria" name="showButtomMode" id="showButtomMode" class="switcher px" onclick="switchShow(false)" /></label>
|
||
</li>
|
||
</text>
|
||
}
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="form-inline panel-body">
|
||
<div class="row">
|
||
<form class="form-horizontal" name="filterForm" id="filterForm">
|
||
@if (!(Model is TeamboardModel) && !(Model is ViewBoardModel) && !(Model is PeopleResourceModel))
|
||
{
|
||
<div class="col-sm-8 col-md-5 col-lg-4">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label">Show Activity Calendar for:</label>
|
||
<div class="radio-group-sigle-line">
|
||
<input type="radio" ng-model="CalendarFilterMode.IsCompany" name="calendarFilterModeCompany" data-ng-value="true" ng-change="switchCompanyFilterMode()" class="form-control" data-key="filterCompanyList" /><span class="radio-label">Company</span><div class="radio-gap"></div>
|
||
<input type="radio" ng-model="CalendarFilterMode.IsView" name="calendarFilterModeView" data-ng-value="true" ng-change="switchViewFilterMode()" class="form-control" data-key="filterViewList" /><span class="radio-label">View</span><div class="radio-gap"></div>
|
||
<input type="radio" ng-model="CalendarFilterMode.IsTeam" name="calendarFilterModeTeam" data-ng-value="true" ng-change="switchTeamFilterMode()" class="form-control" data-key="filterTeamList" /><span class="radio-label">Team</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-8 col-md-5 col-lg-4">
|
||
<div class="form-group no-margin-hr" style="width:100%">
|
||
<label class="control-label" id="filterEntityTitle">{{ CalendarFilterMode.FilteredEntityTitle }}</label><br />
|
||
<select ng-model="CalendarFilterMode.SelectedItemId" name="selFilterElement"
|
||
ng-options="s.Value as s.Text for s in displayedOptions track by s.Value"
|
||
ng-change="SelectedFilterElementChanged()"
|
||
option-class-expr="CSSClass" selected-source-changed>
|
||
<option value="">--Select option--</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
}
|
||
<div class="col-sm-8 col-md-5 col-lg-4">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label">Start<span class="enddatespan">/End</span> Date</label>
|
||
<div style="overflow: hidden;">
|
||
|
||
<div class="input-daterange input-group" id="bs-datepicker-range">
|
||
<input class="form-control" data-val="true" data-val-date="The field Start Date must be a date." data-val-required="The Start Date field is required."
|
||
data-key="capacityFilterStartDate" ng-model="calendarFilters.StartDate" id="filterStartDate" name="filterStartDate" type="text" />
|
||
<div class="input-group-addon">to</div>
|
||
<input class="form-control enddate" data-val="true" data-val-date="The field End Date must be a date." data-val-dategreaterthanorequal="End Date should not be less than Start Date"
|
||
data-val-dategreaterthanorequal-otherpropertyname="filterStartDate" data-val-required="The End Date field is required." data-key="capacityFilterEndDate" ng-model="calendarFilters.EndDate" id="filterEndDate" name="filterEndDate" type="text">
|
||
</div>
|
||
<span class="field-validation-valid" data-valmsg-for="filterStartDate" data-valmsg-replace="true"></span>
|
||
<span class="field-validation-valid" data-valmsg-for="filterEndDate" data-valmsg-replace="true"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-6">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label"> </label><br />
|
||
<button class="btn btn-default" id="btnReloadCapacityCalendar" ng-click="loadCalendarData()"><i class="fa fa-refresh"></i> Reload</button>
|
||
<button class="btn btn-primary" ng-disabled="!anyUpdated()" data-target="#saveScenarioModal" data-toggle="modal"><i class="fa fa-save"></i> Save Changes</button>
|
||
<span id="loader" class="h3">
|
||
<img class="valign-middle" src="@Url.Content("~/Content/images/loadFA.gif")" />
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<div class="ac-control">
|
||
<!--Project Cell-->
|
||
<div id="dataTable2:scroller:fxcol" class="ac-left-col">
|
||
<div class="freezeTable1 ac-left-col-header" id="dataTable2:scroller:fxCH">
|
||
<table class="table1 table-light" ng-if="data != null && data.Calendar.length > 0" id="dataTable2_CFH">
|
||
<thead>
|
||
<tr>
|
||
<th class="firstcol">
|
||
<div>Project</div>
|
||
</th>
|
||
<th class="firstcol">
|
||
<div>Total</div>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
</table>
|
||
</div>
|
||
<!--Left Column-->
|
||
<div class="freezeTable1 ac-left-col-content height-container" id="dataTable2:scroller:fxCB">
|
||
<table class="table table1" id="dataTable2_CFB">
|
||
<tbody ng-repeat="row in data.Calendar track by $index">
|
||
<!-- Team row (for GroupByTeams mode) -->
|
||
<tr style="border-top: 0px !important;border-left: 0px !important;" ng-if="row.RowType == RowType.Team && !row.IsUpperHidden">
|
||
<td style="width: 300px; height: 28px;
|
||
border-top: 0px !important;
|
||
border-left: 0px !important;
|
||
border-right: 1px solid #dbdbdb !important;"
|
||
class="headcol1 headcol-week">
|
||
<div class="shortNameGroup">
|
||
<strong title="{{ row.Name || 'empty' }}">
|
||
{{ row.Name || 'empty' }}
|
||
</strong>
|
||
</div>
|
||
</td>
|
||
<td style="width:100px; padding-bottom: 0px !important; border-left: none !important; border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap; overflow: hidden; height:19px;">
|
||
<strong ng-if="row.RowType == RowType.Team"> {{ (row.GrandTotalQuantity || 0 | number:2) }}</strong>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: 0px !important;" ng-if="row.RowType != RowType.Team" ng-show="!row.IsParentCollapsed &&
|
||
(((row.ProjectId == null && row.ScenarioId == null && row.ExpCatId != null) && !row.IsLowerHidden) ||
|
||
(row.ProjectId != null && !row.IsUpperHidden) || row.RowType == RowType.Capacity || (row.IsTotals && !row.IsUpperHidden))"
|
||
ng-class="{'remaining-capacity-row':row.RowType == RowType.Capacity}">
|
||
<!--Project, ExpendetureCategories row-->
|
||
<td style="border-left: 0px !important;border-right: 1px solid #dbdbdb !important;" class="headcol1 headcol-week expCat" ng-class="{'capacity-row-title':row.RowType == RowType.BottomCategory}"
|
||
ng-click="onParentNodeClick(row, $event);"
|
||
ng-if="!row.IsTotals && ((row.ProjectId != null) || (row.ProjectId == null && row.ScenarioId == null && row.ExpCatId != null))">
|
||
<div id="div_dd_{{$index}}" ng-if="row.RowType == RowType.Project && (row.InactiveScenarios != null && row.InactiveScenarios.length > 0 || row.ScenarioId != null)" class="btn-group menuGroup pull-right">
|
||
<a class="dropdown-toggle" data-toggle="dropdown" onclick='dropDownFixPositionCalendar($(this), $(this).parent().find(".dropdown-menu"));'>
|
||
<i class="fa fa-chevron-circle-down menu-arrow"></i>
|
||
</a>
|
||
<ul id="ul_dd_{{$index}}" class="dropdown-menu dropdown-menu-form dropdown-menu-right dropdown-menu-scroll-auto" style="width: 472px; clear: both; z-index: 499;" onclick="dropDownInsideClick(event);">
|
||
<li ng-if="row.ScenarioId != null">
|
||
<div style="float: left;">
|
||
Edit Project
|
||
</div>
|
||
<div style="float: right;">
|
||
<a ng-show="row.ParentProjectId != null" class="btn btn-xs btn-primary popover-warning popover-dark pull-right" style="width: 27px;" title="Edit Project" href="@Url.Action("Edit", "Project")/{{ row.PartId.length > 0 ? row.ParentProjectId + '?partId=' + row.PartId : row.ParentProjectId}}" data-placement="left" data-toggle="popover">
|
||
<i class="fa fa-edit"></i>
|
||
</a>
|
||
</div>
|
||
</li>
|
||
<li ng-if="row.ScenarioId != null">
|
||
<div style="-ms-text-overflow: ellipsis; -o-text-overflow: ellipsis; text-overflow: ellipsis; overflow: hidden; max-width: 172px; float: left;">
|
||
<a id="a-cl-{{row.ScenarioId}}-{{row.TeamId}}" ng-click="CheckLock($event, 'Scenario', row.ScenarioId, '@Url.Action("Details", "Scenarios")')" class="popover-warning popover-dark" data-toggle="popover" title="{{row.ActiveScenarioName || 'empty'}}">{{ row.ActiveScenarioName || 'empty' }}</a>
|
||
</div>
|
||
<div style="float: right;">
|
||
<a id="a-ts-{{row.ScenarioId}}-{{row.TeamId}}" class="btn btn-xs btn-warning popover-warning popover-dark" ng-click="ToggleStatus($event, 'Scenario', row.ScenarioId)" title="Deactivate" data-toggle="popover" style="width: 27px;"><i class="fa fa-times-circle-o"></i></a>
|
||
<a id="a-copy-{{row.ScenarioId}}-{{row.TeamId}}" ng-click="CopyScenario($event, row.ScenarioId)" data-toggle="popover" class="btn btn-xs popover-warning popover-dark" title="Copy" style="width: 27px;"><i class="fa fa-copy"></i></a>
|
||
<a id="a_add_{{$index}}-{{row.TeamId}}" ng-click="AddScenario($event, row.ProjectId)" data-toggle="popover" class="btn btn-xs btn-success popover-warning popover-dark" title="Add Scenario" style="width: 27px;"><i class="fa fa-plus"></i></a>
|
||
</div>
|
||
</li>
|
||
<li class="divider" ng-if="(row.RowType == RowType.Project && row.InactiveScenarios.length > 0)"></li>
|
||
<li ng-repeat="scenario in row.InactiveScenarios">
|
||
<div style="-ms-text-overflow: ellipsis; -o-text-overflow: ellipsis; text-overflow: ellipsis; overflow: hidden; max-width: 200px; float: left;">
|
||
<a id="a-cl-{{scenario.Id}}-{{row.TeamId}}" ng-click="CheckLock($event, 'Scenario', scenario.Id, '@Url.Action("Details", "Scenarios")')" class="popover-warning popover-dark" data-toggle="popover" title="{{scenario.Name || 'empty'}}">{{ scenario.Name || 'empty' }}</a>
|
||
</div>
|
||
<div style="float: right;">
|
||
<a id="a-ts-{{scenario.Id}}-{{row.TeamId}}" ng-click="ToggleStatus($event, 'Scenario', scenario.Id)" class="btn btn-xs btn-primary popover-warning popover-dark" title="Activate" data-toggle="popover"><i class="fa fa-check-circle-o"></i></a>
|
||
<a id="a-cs-{{scenario.Id}}-{{row.TeamId}}" ng-click="CopyScenario($event, scenario.Id)" data-toggle="popover" class="btn btn-xs popover-warning popover-dark" title="Copy"><i class="fa fa-copy"></i></a>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<a id="id_exp{{row.ExpCatId}}" href="javascript:;" ng-show="!row.EmptyScenario" title="{{ row.Name || 'empty' }}"
|
||
ng-class="{'capacity-row-title-content':row.RowType == RowType.BottomCategory}">
|
||
<i class="fa" ng-class="row.CollapsedClass" style="margin-right: 5px;" title="Expand"></i>
|
||
<div style="display:inline-block;vertical-align: bottom;" class="shortName">{{ row.Name || 'empty' }}</div>
|
||
</a>
|
||
<div class="shortName2" ng-show="row.EmptyScenario" title="{{ row.Name || 'empty' }}">{{ row.Name || 'empty' }}</div>
|
||
</td>
|
||
<!-- Capacity, Totals, CurrentlyAssigned row-->
|
||
<td style="width:300px;border-left: 0px !important;border-right: 1px solid #dbdbdb !important;" class="headcol1 headcol-week" ng-if="row.IsTotals">
|
||
<strong ng-if="row.RowType == RowType.Total || row.RowType == RowType.Capacity || row.RowType == RowType.CurrentlyAssigned" title="{{ row.Name || 'empty' }}">
|
||
{{ row.Name || 'empty' }}
|
||
</strong>
|
||
<span ng-if="row.RowType != RowType.Total && row.RowType != RowType.Capacity && row.RowType != RowType.CurrentlyAssigned" title="{{ row.Name || 'empty' }}">
|
||
{{ row.Name || 'empty' }}
|
||
</span>
|
||
</td>
|
||
|
||
<td style="width:100px;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;"
|
||
ng-if="!row.IsTotals && (row.ExpCatId != null || (row.ProjectId != null && row.ScenarioId != null))">
|
||
{{ (!row.AllowResourceAssignment && calendarFilters.ShowCapacity == 4 && row.RowType == RowType.BottomCategory) ? '-' : (row.GrandTotalQuantity || 0 | number:2) }}
|
||
</div>
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;"
|
||
ng-if="row.IsTotals">
|
||
<strong ng-if="row.IsTotals && row.RowType != RowType.Capacity"> {{ (row.GrandTotalQuantity || 0 | number:2) }}</strong>
|
||
<strong ng-if="row.IsTotals && row.RowType == RowType.Capacity">
|
||
{{(CalcRemainingCapacityTotal(row.GrandTotalQuantity) || 0 | number:2)}}
|
||
</strong>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<!--NonProjectTime rows-->
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="row.RowType == RowType.NonProjectTimeTotal && !row.IsUpperHidden">
|
||
<td style="width:300px; border-left: 0px !important; border-right: 1px solid #dbdbdb !important;"
|
||
class="headcol1 headcol-week" ng-click="toggleNonProjectTotalRow(row)">
|
||
<a href="javascript:;" title="{{ row.Name || 'empty' }}">
|
||
<i class="fa" ng-class="row.CollapsedClass" style="margin-right: 5px;" title="Expand"></i>
|
||
<div style="display:inline-block;vertical-align: bottom;" class="shortName">{{ row.Name || 'empty' }}</div>
|
||
</a>
|
||
</td>
|
||
<td style="width:100px;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;">
|
||
{{ (row.GrandTotalQuantity || 0 | number:2) }}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="(row.RowType == RowType.NonProjectTimeTotal || npCategory.RowType == RowType.NonProjectTimeCategory || npCategory.RowType == RowType.NonProjectTime) && !row.IsUpperHidden"
|
||
ng-show="!row.IsCollapsed && (npCategory.RowType != RowType.NonProjectTime || !npCategory.IsParentCollapsed)"
|
||
ng-repeat-start="npCategory in row.Categories">
|
||
<!--style="width:300px; border-left: 0px !important; border-right: 1px solid #dbdbdb !important;" class="headcol1 headcol-week"-->
|
||
<td style="border-left: 0px !important;border-right: 1px solid #dbdbdb !important;" class="headcol1 headcol-week expCat" ng-click="toggleNonProjectTotalRow(npCategory)">
|
||
<a ng-style="{'margin-left': npCategory.RowType == RowType.NonProjectTime ? '30px': '15px'}" id="id_cat{{npCategory.Id}}" href="javascript:;"
|
||
title="{{ npCategory.Name || 'empty' }}">
|
||
<i class="fa" ng-if="!(npCategory.RowType == RowType.NonProjectTime && npCategory.IsTeamMode)" ng-class="npCategory.CollapsedClass" style="margin-right: 5px;" title="Expand"></i>
|
||
<div style="display:inline-block;vertical-align: bottom;" class="shortName">{{ npCategory.Name || 'empty' }}</div>
|
||
</a>
|
||
<div style="margin-left:15px;" class="shortName2"
|
||
ng-show="npCategory.RowType == RowType.NonProjectTime && (npCategory.Resources == null || npCategory.Resources.length == 0)" title="{{ npCategory.Name || 'empty' }}">{{ npCategory.Name || 'empty' }}</div>
|
||
</td>
|
||
<td style="width:100px;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;">
|
||
{{ (npCategory.GrandTotalQuantity || 0 | number:2) }}
|
||
</div>
|
||
@* ENV-1810. Requested to disable editing of NPT totals
|
||
<a ng-if="!npCategory.GrandTotalReadOnly" href="#" editable-text="npCategory.GrandTotalQuantity" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkNonProjectTimeValue($data, npCategory.Id, npCategory.ParentId, null, -1)"
|
||
e-required>
|
||
{{ (npCategory.GrandTotalQuantity || 0 | number:2) }}
|
||
</a>*@
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="row.RowType == RowType.NonProjectTimeTotal && npCategory.RowType == RowType.NonProjectTime && !row.IsUpperHidden"
|
||
ng-show="!row.IsCollapsed && !npCategory.IsParentCollapsed && !npCategory.IsCollapsed"
|
||
ng-repeat="res in npCategory.Resources">
|
||
<td style="height:31px;width:300px; border-left: 0px !important; border-right: 1px solid #dbdbdb !important;" class="headcol1 headcol-week">
|
||
<span style="padding-left: 33px;">
|
||
{{ res.Name || 'empty' }}
|
||
</span>
|
||
</td>
|
||
<td style="width:100px;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;">
|
||
@* ENV-1810. Requested to disable editing of NPT totals
|
||
<a ng-if="!res.GrandTotalReadOnly" href="#" editable-text="res.GrandTotalQuantity" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkNonProjectTimeValue($data, npCategory.Id, res.NonProjectTimeCategoryId, res.Id, -1)"
|
||
e-required>
|
||
{{ (res.GrandTotalQuantity || 0 | number:2) }}
|
||
</a>*@
|
||
<span>{{ (res.GrandTotalQuantity || 0 | number:2) }}</span>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr ng-repeat-end ng-if="false"></tr>
|
||
<!--Resources assigned to scenario from top part of the grid -->
|
||
<tr style="border-left: none !important;" ng-repeat="res in row.Resources" ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed"
|
||
ng-if="!row.IsUpperHidden && row.RowType != RowType.Team && row.ScenarioId != null && row.ExpCatId != null" class="resRow">
|
||
<td class="headcol1" style="width:300px !important; overflow: hidden;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div class="restbl">
|
||
<div>
|
||
<div style="padding-left:15px;" class="shortName" title="{{ res.Name }}">{{res.Name}}</div>
|
||
<div>
|
||
@* it is OK to use ng-if for buttons visibility according to scenario type, because this property can be changed only on server side and we render model as is *@
|
||
<button ng-if="!row.IsActiveScenarioBottomUp && row.AllowResourceAssignment" style="padding-bottom: 3px !important;" title="Fill remaining" class="btn btn-info btn-xs" ng-disabled="res.ReadOnly || isTakeAllDisabled(row, res)" ng-click="takeRemaining(row.ScenarioId, res.Id, row.ExpCatId, row.TeamId)"><i class="fa fa-asterisk"></i></button>
|
||
<button ng-if="!row.IsActiveScenarioBottomUp && row.AllowResourceAssignment" style="padding-bottom: 3px !important;" title="Take full available capacity" class="btn btn-primary btn-xs" ng-disabled="res.ReadOnly" ng-click="takeAll(row.ScenarioId, res.Id, row.ExpCatId, row.TeamId)"><i class="fa fa-plus"></i></button>
|
||
<button style="padding-bottom: 3px !important;" title="Zero this resource" class="btn btn-success btn-xs" ng-disabled="res.ReadOnly" ng-click="zeroResource(row.ScenarioId, res.Id, row.ExpCatId, row.TeamId)"><i class="fa fa-minus"></i></button>
|
||
<button style="padding-bottom: 3px !important;" title="Remove this resource" class="btn btn-danger btn-xs" ng-disabled="res.ReadOnly" ng-click="removeResource(row.ScenarioId, res.Id, row.ExpCatId, row.TeamId)"><i class="fa fa-times"></i></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
<td style="width:100px !important; padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:80px !important; white-space: nowrap;overflow: hidden;height:19px;">
|
||
<a ng-if="!res.GrandTotalReadOnly" href="#" editable-text="res.GrandTotalQuantity" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkResourceValue($data, row.ScenarioId, row.ExpCatId, res.Id, row.TeamId, -1)"
|
||
e-required>
|
||
{{ (res.GrandTotalQuantity || 0 | number:2) }}
|
||
</a>
|
||
<span ng-if="res.GrandTotalReadOnly">{{ (res.GrandTotalQuantity || 0 | number:2) }}</span>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<!--Resources assigned to expenditure category from bottom part of the grid -->
|
||
<tr style="border-left: none !important;" ng-repeat="res in row.Resources " ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed"
|
||
ng-if="!row.IsLowerHidden && row.RowType != RowType.Team && row.ScenarioId == null && row.ExpCatId != null">
|
||
<td class="headcol1 capacity-row-title">
|
||
<div style="padding-left: 15px;" class="capacity-row-title-content" title="{{ res.Name }}">
|
||
{{res.Name}}
|
||
</div>
|
||
</td>
|
||
<td style="width:100px;padding-bottom: 0px !important;border-left: none !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div style="width:90px !important; white-space: nowrap;overflow: hidden;height:19px;">
|
||
{{ (res.GrandTotalQuantity || 0 | number:2) }}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: none !important;" ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed && !!row.AvailableResources" class="resRow assign-row"
|
||
ng-if="!row.IsUpperHidden && row.RowType != RowType.Team && row.ScenarioId != null && row.ExpCatId != null">
|
||
<td colspan="2" class="headcol1 assign" style="width:400px !important; border-left: none !important;padding-bottom: 1px !important;border-right: 1px solid #dbdbdb !important;">
|
||
<div class="col-sm-8">
|
||
@*<select ng-model="row.ResourceToAssignId" style="min-width: 100px;" id="assign-resource-select-{{row.TeamId}}-{{row.ProjectId}}-{{row.ExpCatId}}">
|
||
<option></option>
|
||
<option ng-repeat="(resourceId, resource) in row.AvailableResources track by $index" value="{{resource.id}}">{{resource.name}}</option>
|
||
</select>*@
|
||
<select ng-select2 ng-model="row.ResourceToAssignId" style="font-size: 9pt; min-width: 100px;" allowClear="true" dropdownAutoWidth="true"
|
||
placeholder="Select a person" minimumResultsForSearch="5" select2-format-result="formatPeopleResourceOption">
|
||
<option></option>
|
||
<option ng-repeat="(resourceId, resource) in row.AvailableResources track by $index" value="{{resource.id}}">{{resource.name}}</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-sm-2">
|
||
<button class="btn btn-success" ng-disabled="!row.ResourceToAssignId" ng-click="assignResource(row, $event)">Assign</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<!--Header-->
|
||
<div id="dataTable2:scroller:fx:OuterDiv" class="header-container width-container">
|
||
<div class="freezeTable1" id="dataTable2:scroller:fx" style="margin-left: -400px">
|
||
<table class="table ac-table-header table-light" ng-if="data != null && data.Calendar.length > 0" id="dataTable2_header">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:400px" class="firstcol">Project</th>
|
||
<!-- year header -->
|
||
<th class="nextcol" ng-repeat="header in (data.YearHeaders)" colspan="{{ header.SpanCount }}">
|
||
{{ header.Title }}
|
||
</th>
|
||
</tr>
|
||
<tr>
|
||
<th class="headcol" style="visibility: hidden;"></th>
|
||
<th data-ng-attr-style="{{(header.Collapsed ? 'width:70px;' : '')}}"
|
||
ng-repeat="header in (data.Headers | filter : {IsMonth:true}) track by $index"
|
||
class="nextcol headcol-month" ng-click="onMonthHeaderClick(header)" colspan="{{header.Collapsed ? 1 : header.Weeks.length}}">
|
||
<i class="fa" ng-class="header.CollapsedClass" style="margin-right: 5px;"></i>
|
||
{{header.Title.substr(0,3)}}
|
||
</th>
|
||
</tr>
|
||
<tr>
|
||
<!--Months in year -->
|
||
<th class="headcol headcol-week" style="visibility: hidden;"></th>
|
||
<th ng-data="weekCol" data-ng-attr-style="{{(header.Collapsed ? '' : 'width:70px;')}}"
|
||
ng-repeat="header in (data.Headers) track by $index" ng-if="header.Initialized"
|
||
ng-show="header.Show" colspan="{{header.Collapsed ? 1 : header.Weeks.length}}">
|
||
{{ header.IsMonth ? '' : header.Title}}
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="dataTable2:scroller" scroll-header
|
||
class="table-light table-responsive very-big-table freezeTable freezeTable1 main-table-container height-container width-container">
|
||
<table class="table table-striped table-bordered main-table" id="capacity-table" ng-if="data != null && data.Calendar.length > 0">
|
||
<!-- Projects -->
|
||
<tbody ng-repeat="row in data.Calendar">
|
||
<!-- Team data row (for GroupByTeams mode) -->
|
||
<tr class="team-row" ng-if="row.RowType == RowType.Team && !row.IsUpperHidden">
|
||
|
||
<td ng-if="calendarFilters.IsBarMode" class="no-border"
|
||
ng-repeat="col in (data.Headers | filter : {Show:true})" style="border-right: none!important;"></td>
|
||
<td ng-repeat="col in (row.QuantityValues) track by $index" ng-show="data.Headers[$index].Show"
|
||
ng-if="!calendarFilters.IsBarMode && data.Headers[$index].Initialized">
|
||
<strong ng-if="!row.ReadOnly[$index]">{{ (col || 0 | number:2)}}</strong>
|
||
</td>
|
||
|
||
|
||
</tr>
|
||
<tr ng-if="row.RowType != RowType.Team" ng-show="!row.IsParentCollapsed &&
|
||
(((row.ProjectId == null && row.ScenarioId == null && row.ExpCatId != null) && !row.IsLowerHidden) ||
|
||
(row.ProjectId != null && !row.IsUpperHidden) || row.RowType == RowType.Capacity || (row.IsTotals && !row.IsUpperHidden))"
|
||
ng-class="{'remaining-capacity-row':row.RowType == RowType.Capacity}">
|
||
<!--values-->
|
||
<td ng-class="row.CSSClass[$index]" data-ng-attr-style="{{(row.BarStyle[$index] && row.BarStyle[$index] || '') }}"
|
||
ng-repeat="col in (row.QuantityValues) track by $index" ng-show="data.Headers[$index].Show"
|
||
ng-if="data.Headers[$index].Initialized">
|
||
<strong ng-if="!row.ReadOnly[$index] && row.IsTotals && (row.RowType == RowType.Total)">
|
||
{{ (col || 0 | number:2)}}
|
||
</strong>
|
||
<strong ng-if="!row.ReadOnly[$index] && row.IsTotals && (row.RowType == RowType.Capacity)">
|
||
{{(CalcRemainingCapacity(col, $index)|| 0 | number:2)}}
|
||
</strong>
|
||
<strong ng-if="!row.ReadOnly[$index] && row.IsTotals && ( row.RowType == RowType.CurrentlyAssigned)">
|
||
{{(col || 0 | number:2)}}
|
||
</strong>
|
||
<span ng-if="(!calendarFilters.IsBarMode || row.RowType != RowType.Project) && !row.ReadOnly[$index] && (row.ProjectId != null || (row.IsTotals && row.RowType != RowType.Total && row.RowType != RowType.Capacity && row.RowType != RowType.CurrentlyAssigned))">
|
||
{{ (col || 0 | number:2)}}
|
||
</span>
|
||
<div ng-if="row.ProjectId == null && row.ExpCatId != null && calendarFilters.ShowCapacity == 1" class="exp-cat-total">
|
||
<div class="top-side">{{ (row.QuantityTotalAllocatedValue[$index] || 0 | number:2) }}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ row.AllowResourceAssignment ? (row.QuantityTotalResValue[$index] || 0 | number:2) : '-' }}</div>
|
||
</div>
|
||
<div ng-if="row.ProjectId == null && row.ExpCatId != null && calendarFilters.ShowCapacity == 2" class="exp-cat-total">
|
||
<div class="top-side">{{ (row.QuantityValues[$index] || 0 | number:2) }}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ row.AllowResourceAssignment ? (row.QuantityTotalResValue[$index] || 0 | number:2) : '-' }}</div>
|
||
</div>
|
||
<div ng-if="row.ProjectId == null && row.ExpCatId != null && calendarFilters.ShowCapacity == 3" class="exp-cat-total">
|
||
<div class="top-side">{{ (row.QuantityTotalAllocatedValue[$index] || 0 | number:2)}}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ (row.QuantityValues[$index] || 0 | number:2)}}</div>
|
||
</div>
|
||
<div ng-if="row.ProjectId == null && row.ExpCatId != null && calendarFilters.ShowCapacity == 4" class="exp-cat-total">
|
||
<div class="top-side">{{ row.AllowResourceAssignment ? ((row.QuantityTotalResValue[$index] - row.QuantityValues[$index]) || 0 | number:2) : '-' }}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ row.AllowResourceAssignment ? (row.QuantityTotalResValue[$index] || 0 | number:2) : '-' }}</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<!--NonProjectTime rows-->
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="row.RowType == RowType.NonProjectTimeTotal && !row.IsUpperHidden">
|
||
<td ng-repeat="col in (row.QuantityValues) track by $index" ng-show="data.Headers[$index].Show"
|
||
ng-if="data.Headers[$index].Initialized">
|
||
{{col || 0 | number:2}}
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="(row.RowType == RowType.NonProjectTimeTotal || npCategory.RowType == RowType.NonProjectTimeCategory || npCategory.RowType == RowType.NonProjectTime) && !row.IsUpperHidden"
|
||
ng-show="!row.IsCollapsed && (npCategory.RowType != RowType.NonProjectTime || !npCategory.IsParentCollapsed)"
|
||
ng-repeat-start="npCategory in row.Categories track by $index">
|
||
<td ng-repeat="col in (npCategory.QuantityValues) track by $index" ng-show="data.Headers[$index].Show"
|
||
ng-if="data.Headers[$index].Initialized">
|
||
<span ng-if="col != null && npCategory.ReadOnly[$index]">
|
||
{{col || 0 | number:2}}
|
||
</span>
|
||
<a href="#" editable-text="npCategory.QuantityValues[$index]" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkNonProjectTimeValue($data, npCategory.Id, npCategory.ParentId, null, $index)"
|
||
ng-if="!npCategory.ReadOnly[$index] && col != null" e-required>
|
||
{{ (col || 0 | number:2) }}
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
<tr style="border-left: 0 !important;"
|
||
ng-if="row.RowType == RowType.NonProjectTimeTotal && npCategory.RowType == RowType.NonProjectTime && !npCategory.IsTeamMode && !row.IsUpperHidden"
|
||
ng-show="!row.IsCollapsed && !npCategory.IsParentCollapsed && !npCategory.IsCollapsed"
|
||
ng-repeat="res in npCategory.Resources">
|
||
<td style="height:31px;" ng-repeat="col in res.QuantityValues track by $index" ng-show="data.Headers[$index].Show"
|
||
ng-if="data.Headers[$index].Initialized">
|
||
<a href="#" editable-text="res.QuantityValues[$index]" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkNonProjectTimeValue($data, npCategory.Id, res.NonProjectTimeCategoryId, res.Id, $index)"
|
||
ng-if="res.QuantityValues[$index] != null && !row.ReadOnly[$index] && !res.ReadOnly && !res.ReadOnlyWeeks[$index]" e-required>
|
||
{{ (res.QuantityValues[$index] || 0 | number:2) }}
|
||
</a>
|
||
<span ng-if="res.QuantityValues[$index] != null && !row.ReadOnly[$index] && (res.ReadOnly || res.ReadOnlyWeeks[$index])">
|
||
{{ (res.QuantityValues[$index] || 0 | number:2) }}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
<tr ng-repeat-end ng-if="false"></tr>
|
||
<!--Resources assigned to scenario from top part of the grid -->
|
||
<tr ng-repeat="res in row.Resources" ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed"
|
||
ng-if="!row.IsUpperHidden && row.RowType != RowType.Team && row.ScenarioId != null && row.ExpCatId != null" class="resRow">
|
||
<td ng-repeat="col in (data.Headers) track by $index " ng-show="col.Show" style="height:31px;"
|
||
ng-if="col.Initialized" ng-class="res.CSSClass[$index]">
|
||
<a href="#" editable-text="res.QuantityValues[$index]" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit"
|
||
onbeforesave="checkResourceValue($data, row.ScenarioId, row.ExpCatId, res.Id, row.TeamId, $index)"
|
||
ng-if="!row.ReadOnly[$index] && !res.ReadOnly && !res.ReadOnlyWeeks[$index]" e-required>
|
||
{{ (res.QuantityValues[$index] || 0 | number:2) }}
|
||
</a>
|
||
<span ng-if="!row.ReadOnly[$index] && (res.ReadOnly || res.ReadOnlyWeeks[$index])">
|
||
{{ (res.QuantityValues[$index] || 0 | number:2) }}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
<!--Resources assigned to expenditure category from bottom part of the grid -->
|
||
<tr ng-repeat="res in row.Resources" ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed"
|
||
ng-if="!row.IsLowerHidden && row.RowType != RowType.Team && row.ScenarioId == null && row.ExpCatId != null">
|
||
<td ng-class="res.CSSClass[$index]" class="capacity-total"
|
||
ng-repeat="col in (res.QuantityValues) track by $index" ng-show="data.Headers[$index].Show" ng-if="data.Headers[$index].Initialized">
|
||
<!--Displays Allocated/Capacity for all switcher values except Remaining/Capacity -->
|
||
<div ng-if="calendarFilters.ShowCapacity != 4" class="exp-cat-total">
|
||
<div class="top-side">{{ (col || 0 | number:2)}}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ (res.QuantityTotalResValue[$index] || 0 | number:2)}}</div>
|
||
</div>
|
||
<!--Displays Remaining/Capacity for Remaining/Capacity switcher value -->
|
||
<div ng-if="calendarFilters.ShowCapacity == 4" class="exp-cat-total">
|
||
<div class="top-side">{{ ((res.QuantityTotalResValue[$index] - res.AllocatedQuantityValues[$index]) || 0 | number:2)}}</div>
|
||
<hr />
|
||
<div class="bottom-side">{{ (res.QuantityTotalResValue[$index] || 0 | number:2)}}</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<!--Resource Assign-->
|
||
<tr ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed && !!row.AvailableResources" class="resRow assign-row"
|
||
ng-if="!row.IsUpperHidden && row.RowType != RowType.Team && row.ScenarioId != null && row.ExpCatId != null">
|
||
<td style="height:54px;" colspan="{{data.VisibleCellCount}}"></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<table class="table" style="width: 100%" id="capacity-table-empty" ng-if="data == null">
|
||
<tbody>
|
||
<tr>
|
||
<td style="text-align: center;">
|
||
There is no data available.
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<form name="saveScenarioForm">
|
||
<div id="saveScenarioModal" class="modal fade" tabindex="-1" role="dialog" style="display: none;" data-backdrop="static">
|
||
<div class="modal-dialog" style="width: 660px;">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||
<h4 class="modal-title">Save Changes</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="panel-body form-horizontal">
|
||
<div ng-show="SaveAs == 1 && saveType == 1 && data2Update.ChangedSupperExpCatProjects.length">
|
||
<div class="alert alert-warning">
|
||
<span>The following projects cannot be saved as Bottom Up and will be saved as Top Down:</span>
|
||
<ul>
|
||
<li ng-repeat="project in data2Update.ChangedSupperExpCatProjects ">{{project.Name}}</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<div class="col-sm-12">
|
||
<input id="save-as-update" name="save-as-update" type="radio" ng-model="SaveAs" value="0" />
|
||
<label for="save-as-update" class="control-label">Save Changes to Current Scenario</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<div class="col-sm-12">
|
||
<input id="save-as-new" name="save-as-new" type="radio" ng-model="SaveAs" value="1" />
|
||
<label for="save-as-new" class="control-label">Create New Scenario</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-group" ng-show="SaveAs == 1">
|
||
<div class="row">
|
||
<div class="col-sm-offset-1 col-sm-2">
|
||
<label class="control-label">Name: </label>
|
||
</div>
|
||
<div class="col-sm-9">
|
||
<input type="text" ng-model="ScenarioName" id="scenarioName" name="scenarioName" class="form-control" ng-required="SaveAs == 1" />
|
||
<span class="validation-error" ng-show="SaveAs == 1 && saveScenarioForm.scenarioName.$error.required">Scenario Name is a required field</span>
|
||
</div>
|
||
</div>
|
||
<div class="row" style="margin-top: 5px;">
|
||
<div class="col-sm-offset-1 col-sm-2">
|
||
<label class="control-label">Status: </label>
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<input type="checkbox" ng-model="isActiveScenario" id="is-active-scenario" name="is-active-scenario" class="form-control" />
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<label class="control-label">Scenario Type: </label>
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<select ng-model="saveType" id="save-type" name="save-type" class="form-control">
|
||
<option value="0">Keep Current</option>
|
||
<option value="1">Bottom Up</option>
|
||
<option value="2">Top Down</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="panel-body form-horizontal">
|
||
<div class="form-group">
|
||
<div class="col-sm-12">
|
||
<input id="update-projections" style="margin-top: 5px;" name="update-projections" type="checkbox" ng-model="isMatchChecked" ng-disabled="saveType == '1'" value="0" />
|
||
<label for="update-projections" class="control-label"><b>For Projections Only</b>: update projections to match Resource Allocations</label>
|
||
<br />
|
||
<i>(Projections of Bottom Up scenarios will be updated regardless of the state of this checkbox)</i>
|
||
</div>
|
||
</div>
|
||
<div class="alert alert-danger" ng-show="isOverAllocated && !isMatchChecked">
|
||
<ul>
|
||
<li>
|
||
Current scenario contains overallocated Categories and you need to update Projections to match Resource Allocations to continue
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-disabled="(isOverAllocated && !isMatchChecked)" ng-click="saveScenarioForm.$valid && saveChanges()">Ok</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||
</div>
|
||
</div> <!-- / .modal-content -->
|
||
</div> <!-- / .modal-dialog -->
|
||
</div> <!-- / .modal -->
|
||
</form>
|
||
</div>
|