747 lines
42 KiB
Plaintext
747 lines
42 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. ENV-905. Backurl page name - to return to this page
|
|
}
|
|
|
|
if (Model is ViewBoardModel)
|
|
{
|
|
initDataObject.ViewId = ((ViewBoardModel)Model).SelectedViewId;
|
|
initDataObject.PageTitle = "dashboard"; // SA. ENV-905. Backurl page name - to return to this page
|
|
}
|
|
|
|
if (Model is TeamboardModel)
|
|
{
|
|
initDataObject.TeamId = ((TeamboardModel)Model).SelectedTeamId;
|
|
initDataObject.PageTitle = "dashboard"; // SA. ENV-905. Backurl page name - to return to this page
|
|
}
|
|
|
|
if (Model is PeopleResourceModel)
|
|
{
|
|
initDataObject.ResourceId = ((PeopleResourceModel)Model).Id;
|
|
initDataObject.PageTitle = "dashboard"; // SA. ENV-905. 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;
|
|
|
|
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');
|
|
|
|
@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', // SA. ENV-1235. Disable incorrect dates input
|
|
endDate: '@Constants.MAX_SELECTABLE_DATE' // SA. ENV-1235. Disable incorrect dates input
|
|
};
|
|
|
|
$('#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);
|
|
//$('#bs-datepicker-range').data('datepicker').pickers[1].update(tmpValue);
|
|
//$('#bs-datepicker-range').data('datepicker').pickers[1].update('');
|
|
}
|
|
|
|
$('#filterEndDate').data('datepicker').setStartDate(sDate);
|
|
}
|
|
});
|
|
|
|
$(window).scroll(function () {
|
|
$('.menuGroup').removeClass('open'); //.trigger('hide.bs.dropdown');
|
|
hideRedundantPopovers($('#capacity-table'), null);
|
|
});
|
|
|
|
$('.table-light').scroll(function () {
|
|
$('.menuGroup').removeClass('open'); //.trigger('hide.bs.dropdown');
|
|
hideRedundantPopovers($('#capacity-table'), null);
|
|
});
|
|
$(document).click(function (event) {
|
|
if (!$(event.target).is('[data-toggled="popover"]'))
|
|
hideRedundantPopovers($('#capacity-table'), null);
|
|
});
|
|
|
|
$('.for-select2').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
|
|
});
|
|
});
|
|
function onCMPreferencesItemClick(menu) {
|
|
saveCapacityManagementPreferences();
|
|
}
|
|
|
|
function dropDownFixPositionCalendar(button, dropdown) {
|
|
|
|
setDropdownProps(button, dropdown, liHeight);
|
|
|
|
|
|
hideRedundantPopovers($('#capacity-table'), null);
|
|
}
|
|
|
|
function hideRedundantPopovers(container, currentBtn) {
|
|
var id = null;
|
|
if (currentBtn) {
|
|
if (currentBtn.is('[data-toggle="popover"]'))
|
|
id = currentBtn.attr('id');
|
|
else
|
|
id = currentBtn.closest('[data-toggle="popover"]').attr('id');
|
|
}
|
|
container.find('[data-toggle="popover"]' + (id != null && id != undefined) ? '[id!="' + id + '"]' : '').popover('destroy');
|
|
}
|
|
|
|
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) {
|
|
angular.element(document.getElementById('controller1')).scope().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)" watch-resizing ng-cloak>
|
|
<div id="menuCalendarOptions" ng-show="false">
|
|
<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>
|
|
<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>
|
|
@if (!(Model is PeopleResourceModel))
|
|
{
|
|
<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>
|
|
</select>
|
|
</li>
|
|
}
|
|
@*"ng-change="changeCapacity(calendarFilters.ShowCapacity) <li class="padding-xs-hr" data-key="showOption"><div class="checkbox"><label><span class="switcherLbl" style="width:93px">Left Total</span>
|
|
<select id="selectOptions" class="form-control"
|
|
ng-model="calendarFilters.ShowCapacity"
|
|
ng-options="item.subItem as item.label for item in capacityValues track by item.id"
|
|
onchange="changeCapacityView()" ng-change="changeCapacity(calendarFilters.ShowCapacity)>
|
|
</select></label></div></li>*@
|
|
<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>
|
|
</div>
|
|
|
|
<div class="form-inline panel-body">
|
|
<div class="row">
|
|
@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-key="capacityFilterStartDate" ng-model="calendarFilters.StartDate" ng-change="onStartDate" id="filterStartDate" name="filterStartDate" type="text" />
|
|
<div class="input-group-addon">to</div>
|
|
<input class="form-control enddate" data-key="capacityFilterEndDate" ng-model="calendarFilters.EndDate" id="filterEndDate" name="filterEndDate" type="text">
|
|
</div>
|
|
|
|
@* <div class="input-daterange input-group date floatdaterange" id="bs-datepicker-rangeStart">
|
|
<input class="form-control" data-key="capacityFilterStartDate" ng-model="calendarFilters.StartDate" ng-change="onStartDate" id="filterStartDate" name="filterStartDate" type="text" />
|
|
</div>
|
|
<div class="pull-left floatdaterange-addon">To</div>
|
|
<div class="input-daterange input-group date floatdaterange" id="bs-datepicker-rangeEnd">
|
|
<input class="form-control enddate" data-key="capacityFilterEndDate" ng-model="calendarFilters.EndDate" id="filterEndDate" name="filterEndDate" type="text">
|
|
</div>*@
|
|
</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()" ng-click="saveChanges()"><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>
|
|
</div>
|
|
</div>
|
|
<div class="ac-control" >
|
|
<!--Project Cell-->
|
|
<div id="dataTable2:scroller:fxcol" style="height: auto; display: block; float: left; overflow: hidden;">
|
|
<div class="freezeTable1" id="dataTable2:scroller:fxCH" style="width: 100%; overflow: hidden;">
|
|
<table class="table1 table-light" ng-if="data != null && data.Calendar.length > 0" id="dataTable2_CFH"
|
|
style="margin-top: 0px; margin-left: 0px; display: block;border:0;">
|
|
<thead style="padding: 0px; margin: 0px;">
|
|
<tr >
|
|
<th style="height:84px;width:300px;
|
|
|
|
border-left: 0px !important;
|
|
border-right: 1px solid #dbdbdb !important;
|
|
border-bottom: 1px solid #dbdbdb !important;"
|
|
class="firstcol">
|
|
<div>Project</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
<!--Left Column-->
|
|
<div class="freezeTable1 height-container" id="dataTable2:scroller:fxCB"
|
|
style="overflow: hidden;">
|
|
<table class="table table1" id="dataTable2_CFB"
|
|
style="border:0; margin-top: -84px; margin-left: 0px; display: block;" dmt="84">
|
|
<tbody ng-repeat="row in data.Calendar track by $index">
|
|
<tr ng-if="$index == 0" style="border-top: 0px !important;border-bottom: 0px !important;">
|
|
<th style="height:84px;border-top: 0px !important;border-bottom: 0px !important;">Project</th></tr>
|
|
<tr style="border-top: 0px !important;border-left: 0px !important;" ng-if="row.RowType == 8 && !row.IsUpperHidden">
|
|
<!--Team = 8-->
|
|
<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>
|
|
</tr>
|
|
<tr style="border-left: 0px !important;" ng-if="row.RowType != 8" ng-show="!row.IsParentCollapsed &&
|
|
(((row.ProjectId == null && row.ScenarioId == null && row.ExpCatId != null) && !row.IsLowerHidden) ||
|
|
(row.ProjectId != null && !row.IsUpperHidden) || row.RowType == 6 || (row.IsTotals && !row.IsUpperHidden))"
|
|
ng-class="{'remaining-capacity-row':row.RowType == 6}">
|
|
<!--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 == 7}"
|
|
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 == 0 && (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: 300px; 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.Name1 || 'empty'}}">{{ row.Name1 || '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 == 0 && 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 == 7}" >
|
|
<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>
|
|
<!--Vacation, Training, Loan-outs, Capacity, Totals 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 == 5 || row.RowType == 6" title="{{ row.Name || 'empty' }}">
|
|
<!--Total = 5, Capacity = 6-->
|
|
{{ row.Name || 'empty' }}
|
|
</strong>
|
|
<span ng-if="row.RowType != 5 && row.RowType != 6" title="{{ row.Name || 'empty' }}">
|
|
{{ row.Name || 'empty' }}
|
|
</span>
|
|
</td>
|
|
</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 != 8 && row.ScenarioId != null && row.ExpCatId != null" class="resRow">
|
|
<td class="headcol1" style="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 >
|
|
<button 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 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 || res.GrandTotalQuantity > 0" ng-click="removeResource(row.ScenarioId, res.Id, row.ExpCatId, row.TeamId)"><i class="fa fa-times"></i></button>
|
|
</div>
|
|
</div>
|
|
</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 != 8 && 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>
|
|
</tr>
|
|
<tr style="border-left: none !important;" ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed" class="resRow assign-row"
|
|
ng-if="!row.IsUpperHidden && row.RowType != 8 && row.ScenarioId != null && row.ExpCatId != null">
|
|
<td class="headcol1 assign" style="border-left: none !important;padding-bottom: 1px !important;border-right: 1px solid #dbdbdb !important;">
|
|
<div class="col-sm-8">
|
|
<span>Assign a person:</span>
|
|
</div>
|
|
<br />
|
|
<div class="col-sm-8">
|
|
<select ng-model="row.ResourceToAssignId" style="min-width: 100px;">
|
|
<option ng-repeat="item in getExpCatResources(row)" value="{{item.Id}}">{{item.Name}}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<button class="btn btn-sm btn-success" ng-disabled="row.ResourceToAssignId == null" ng-click="assignResource(row.ResourceToAssignId, row.ScenarioId, row.ExpCatId, row.TeamId, $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">
|
|
<table class="table ac-table-header table-light" ng-if="data != null && data.Calendar.length > 0" id="dataTable2_header">
|
|
<thead>
|
|
<tr>
|
|
<th style="width:300px;" 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" watch-resizing>
|
|
<!-- Projects -->
|
|
<tbody ng-repeat="row in data.Calendar">
|
|
|
|
<tr class="team-row" ng-if="row.RowType == 8 && !row.IsUpperHidden">
|
|
<!--Team = 8-->
|
|
<td class="no-border"
|
|
ng-repeat="col in (data.Headers | filter : {Show:true})"></td>
|
|
</tr>
|
|
<tr ng-if="row.RowType != 8" ng-show="!row.IsParentCollapsed &&
|
|
(((row.ProjectId == null && row.ScenarioId == null && row.ExpCatId != null) && !row.IsLowerHidden) ||
|
|
(row.ProjectId != null && !row.IsUpperHidden) || row.RowType == 6 || (row.IsTotals && !row.IsUpperHidden))"
|
|
ng-class="{'remaining-capacity-row':row.RowType == 6}">
|
|
<!--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 == 5 )">
|
|
<!--Total = 5-->
|
|
{{ (col || 0 | number:2)}}
|
|
</strong>
|
|
<strong ng-if="!row.ReadOnly[$index] && row.IsTotals && ( row.RowType == 6)">
|
|
<!-- Capacity = 6-->
|
|
{{(CalcRemainingCapacity(col, $index)|| 0 | number:2)}}
|
|
</strong>
|
|
<span ng-if="(!calendarFilters.IsBarMode || row.RowType != 0) && !row.ReadOnly[$index] && (row.ProjectId != null || (row.IsTotals && row.RowType != 5 && row.RowType != 6))">
|
|
{{ (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.QuantityValues[$index] || 0 | number:2)}}
|
|
</div>
|
|
<hr />
|
|
<div class="bottom-side">{{ (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.QuantityExpCatTotalValue[$index] || 0 | number:2)}}</div>
|
|
<hr />
|
|
<div class="bottom-side">{{ (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.QuantityValues[$index] || 0 | number:2)}}</div>
|
|
<hr />
|
|
<div class="bottom-side">{{ (row.QuantityExpCatTotalValue[$index] || 0 | number:2)}}</div>
|
|
</div>
|
|
</td>
|
|
</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 != 8 && 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 != 8 && 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">
|
|
<div 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>
|
|
</td>
|
|
</tr>
|
|
<!--Resource Assign-->
|
|
<tr ng-show="!row.ExpCatCollapsed && !row.IsParentCollapsed" class="resRow assign-row"
|
|
ng-if="!row.IsUpperHidden && row.RowType != 8 && 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>
|
|
</div>
|
|
|