922 lines
44 KiB
Plaintext
922 lines
44 KiB
Plaintext
@model EnVisage.Models.TeamboardModel
|
||
@using EnVisage.Code
|
||
@{
|
||
ViewBag.Title = "Team Dashboard";
|
||
}
|
||
@section stylesheets
|
||
{
|
||
<link href="~/Content/stylesheets/xeditable.css" rel="stylesheet" type="text/css">
|
||
}
|
||
@section scripts
|
||
{
|
||
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
|
||
<script src="~/Scripts/Angular/angular.min.js"></script>
|
||
<script src="~/Scripts/Angular/angular-route.min.js"></script>
|
||
<script src="~/Scripts/Angular/xeditable.min.js"></script>
|
||
<script src="~/Scripts/Angular/app.js"></script>
|
||
<script src="~/Scripts/Angular/controllers.js"></script>
|
||
<script src="~/Scripts/jquery.collapsiblepanel.js"></script>
|
||
<script type="text/javascript">
|
||
$().ready(function () {
|
||
$('.collapsible').collapsiblePanel();
|
||
|
||
selectTeam('@(Model.Teams.FirstOrDefault() != null ? Model.Teams.FirstOrDefault().Id : Guid.Empty)');
|
||
|
||
var header = $('#panelTeamCalendar').parent().find('.panel-heading'); //$('#panelTeamCalendar').find('.ui-widget-header').first();
|
||
header.click(function () {
|
||
if (angular.element(document.getElementById('controller1')).scope().data == null) {
|
||
angular.element(document.getElementById('controller1')).scope().calendarFilters.TeamId = $('#list').val();
|
||
angular.element(document.getElementById('controller1')).scope().getCalendar();
|
||
}
|
||
});
|
||
$('#panelForecast').on('hidden.bs.collapse', function () {
|
||
$('#divForecastMenu').hide();
|
||
});
|
||
$('#panelForecast').on('shown.bs.collapse', function () {
|
||
$('#divForecastMenu').show();
|
||
if ($('#forecastBlock').children().length == 0)
|
||
loadForecastPanel($('#list').val());
|
||
});
|
||
|
||
$('#panelTeamCalendar').on('hidden.bs.collapse', function () {
|
||
$('#divCalendarMenu').hide();
|
||
});
|
||
$('#panelTeamCalendar').on('shown.bs.collapse', function () {
|
||
$('#divCalendarMenu').show();
|
||
//if ($('#forecastBlock').children().length == 0)
|
||
// initCMMenuItems($('#list').val());
|
||
});
|
||
});
|
||
|
||
var resizeFreez = function () {
|
||
var t = $("#table");
|
||
|
||
var thsWidthI = 0;
|
||
var thsWidthS = 0;
|
||
var thsWidth = 0;
|
||
var tr = t.find("tr:eq(1)");
|
||
var ths = tr.find("th");
|
||
var dateThs = ths.filter(":gt(2):visible");
|
||
if (dateThs.length == 0)
|
||
return;
|
||
var visibleColumns = 0;
|
||
ths.filter(":visible").each(function (i, o) {
|
||
thsWidth += $(o).outerWidth(true);
|
||
thsWidthI += $(o).innerWidth();
|
||
thsWidthS += $(o).width();
|
||
visibleColumns++;
|
||
});
|
||
var divWidthO = t.parent().outerWidth(true);
|
||
var divWidthI = t.parent().innerWidth();
|
||
var thName = ths.eq(1);
|
||
var thNameWidth = thName.width();
|
||
var longestCategory = 0;
|
||
t.find("td:nth-child(2)").each(function (i, td) {
|
||
var text = $(td).html();
|
||
var txtElement = $("<td></td>").html(text).css({
|
||
'class': "headcol"
|
||
}).prependTo($(td).parent());
|
||
longestCategory = Math.max(longestCategory, txtElement.width());
|
||
txtElement.remove();
|
||
});
|
||
var delta = 0;
|
||
if (thsWidthI > divWidthI) {
|
||
// if width of all columns > visible table then we need to shrink name column to the width of smallest category name
|
||
delta = -Math.min(thNameWidth - longestCategory, thsWidthI - divWidthI + visibleColumns + 1);
|
||
} else if (thsWidthI < divWidthI) {
|
||
delta = divWidthI - thsWidthI - visibleColumns - 1;
|
||
}
|
||
if (delta == 0)
|
||
return;
|
||
t.find("tbody tr td:nth-child(2)").each(rszObj, [delta, null, null]);
|
||
t.find("th:nth-child(2)").each(rszObj, [delta, null, null]);
|
||
t.find("tfoot td:first").each(rszObj, [delta, null, null]);
|
||
t.find("tbody tr td:nth-child(3)").each(rszObj, [null, delta, null]);
|
||
t.find("th:nth-child(3)").each(rszObj, [null, delta, null]);
|
||
t.find("tfoot td:eq(1)").each(rszObj, [null, delta, null]);
|
||
var total3With = ths.eq(0).outerWidth() + ths.eq(1).outerWidth() + ths.eq(2).outerWidth();
|
||
t.parent().each(rszObj, [null, null, total3With - 1]);
|
||
};
|
||
function rszObj(deltaWidth, deltaLeft, padLeft) {
|
||
if (deltaWidth != null && deltaWidth != 0) {
|
||
var oldWidth = $(this).width();
|
||
$(this).css('width', oldWidth + deltaWidth);
|
||
}
|
||
if (deltaLeft != null && deltaLeft != 0) {
|
||
var oldLeft = $(this).css('left');
|
||
if (oldLeft != null && oldLeft.length > 0) {
|
||
var l = parseInt(oldLeft.substr(0, oldLeft.length - 1));
|
||
if (!isNaN(l))
|
||
$(this).css('left', l + deltaLeft);
|
||
}
|
||
}
|
||
if (padLeft != null && !isNaN(padLeft))
|
||
$(this).css('padding-left', padLeft);
|
||
}
|
||
|
||
init.push(function () {
|
||
reInitFields();
|
||
$("#btnReloadCalendar").click();
|
||
var options = {
|
||
format: 'm/d/yyyy'
|
||
};
|
||
$('#bs-datepicker-from').datepicker(options);
|
||
$('#bs-datepicker-to').datepicker(options);
|
||
$('#fs-datepicker-range').datepicker(options);
|
||
$('#bs-datepicker-range').datepicker(options);
|
||
|
||
$('#percentage_container').slider({
|
||
'range': 'min',
|
||
'min': 0,
|
||
'max': 100,
|
||
'value': 100,
|
||
change: function (event, ui) {
|
||
onPercentageChange(event, ui, $(this));
|
||
changeScope(ui.value);
|
||
},
|
||
slide: function (event, ui) {
|
||
onPercentageSlide(event, ui, $(this));
|
||
changeScope(ui.value);
|
||
}
|
||
});
|
||
|
||
$('#list option:first').remove();
|
||
|
||
angular.element(document.getElementById('controller')).scope().teamId = $('#list option').first().val();
|
||
angular.element(document.getElementById('controller')).scope().teamChanged();
|
||
$('#visibilitydropdown2').click(function (event) {
|
||
event.stopPropagation();
|
||
});
|
||
});
|
||
|
||
function reInitFields() {
|
||
angular.element(window).resize(function () {
|
||
resizeFreez();
|
||
});
|
||
|
||
$('#monthWeekMode').switcher({
|
||
on_state_content: 'Month',
|
||
off_state_content: 'Week'
|
||
});
|
||
$('#monthWeekMode').parent().css("width", "80px");
|
||
}
|
||
|
||
function selectTeam(id) {
|
||
if (id != '@Guid.Empty') {
|
||
$('#SelectedTeamId').val(id);
|
||
|
||
$('#resourceInfoLoaderIndicator').show();
|
||
|
||
//expand panels with charts and tricky tables or they will be messed up
|
||
if(!$("#panelCapacityPlanning").hasClass("collapse in"))
|
||
$("#panelCapacityPlanning").collapse('show');
|
||
|
||
if ($("#panelTeamCalendar").hasClass("collapse in")) {
|
||
angular.element(document.getElementById('controller1')).scope().calendarFilters.TeamId = id;
|
||
angular.element(document.getElementById('controller1')).scope().getCalendar();
|
||
|
||
} else {
|
||
angular.element(document.getElementById('controller1')).scope().data = null;
|
||
}
|
||
|
||
$.post('/Team/GetTeamResourcesInfo', { 'teamId': id }, function (data) {
|
||
if (data != undefined) {
|
||
$('div#TeamInfo').html(data);
|
||
$('#resourceInfoLoaderIndicator').hide();
|
||
}
|
||
});
|
||
GetExpCatDropdown(id);
|
||
//InitGraph(id);
|
||
|
||
if ($("#panelForecast").hasClass("collapse in")) {
|
||
loadForecastPanel(id);
|
||
} else {
|
||
$('#forecastBlock').html('');
|
||
}
|
||
}
|
||
}
|
||
|
||
function GetExpCatDropdown(id) {
|
||
var expCatDropDown = $('#capacityExpCat');
|
||
$.ajax({
|
||
url: '/Team/GetExpCatDropdown',
|
||
type: 'post',
|
||
data: { teamId: id },
|
||
success: function (data) {
|
||
expCatDropDown.empty();
|
||
$.each(data["data"], function (i, variant) {
|
||
expCatDropDown.append('<option value="' + variant.Value + '">' + variant.Text + '</option>');
|
||
});
|
||
},
|
||
error: function () {
|
||
alert('Error');
|
||
}
|
||
});
|
||
}
|
||
|
||
function increaseCapasity() {
|
||
blockUI();
|
||
$.ajax({
|
||
url: "/Team/ChangeCapacity" + '?startDate=' + $('#capacityStartDate').val() + '&endDate=' + $('#capacityEndDate').val() + '&expCat=' + $('#capacityExpCat').val() + '&capacityValue=' + $('#capacityAmount').val() + '&teamId=' + $('#SelectedTeamId').val(),
|
||
type: 'post',
|
||
data: {},
|
||
success: function (data) {
|
||
//InitGraph($('#SelectedTeamId').val());
|
||
if ($("#panelForecast").hasClass("collapse in")) {
|
||
loadForecastPanel($('#list').val());
|
||
} else {
|
||
$('#forecastBlock').html('');
|
||
}
|
||
unblockUI();
|
||
$('#btnReloadCalendar').click()
|
||
},
|
||
error: function () {
|
||
unblockUI();
|
||
alert('Error');
|
||
}
|
||
});
|
||
}
|
||
function decreaseCapasity() {
|
||
blockUI();
|
||
$.ajax({
|
||
url: "/Team/ChangeCapacity" + '?startDate=' + $('#capacityStartDate').val() + '&endDate=' + $('#capacityEndDate').val() + '&expCat=' + $('#capacityExpCat').val() + '&capacityValue=-' + $('#capacityAmount').val() + '&teamId=' + $('#SelectedTeamId').val() + '&fullTime=' + $('#fullTime').prop('checked'),
|
||
type: 'post',
|
||
data: {},
|
||
success: function (data) {
|
||
if ($("#panelForecast").hasClass("collapse in")) {
|
||
loadForecastPanel($('#list').val());
|
||
} else {
|
||
$('#forecastBlock').html('');
|
||
}
|
||
unblockUI();
|
||
$('#btnReloadCalendar').click()
|
||
},
|
||
error: function () {
|
||
unblockUI();
|
||
alert('Error');
|
||
}
|
||
});
|
||
}
|
||
|
||
function resetCapasity() {
|
||
blockUI();
|
||
$.ajax({
|
||
url: "/Team/ResetCapacity" + '?startDate=' + $('#capacityStartDate').val() + '&endDate=' + $('#capacityEndDate').val() + '&expCat=' + $('#capacityExpCat').val() + '&teamId=' + $('#SelectedTeamId').val() + '&fullTime=' + $('#fullTime').prop('checked'),
|
||
type: 'post',
|
||
data: {},
|
||
success: function (data) {
|
||
if ($("#panelForecast").hasClass("collapse in")) {
|
||
loadForecastPanel($('#list').val());
|
||
} else {
|
||
$('#forecastBlock').html('');
|
||
}
|
||
unblockUI();
|
||
$('#btnReloadCalendar').click()
|
||
},
|
||
error: function () {
|
||
unblockUI();
|
||
alert('Error');
|
||
}
|
||
});
|
||
}
|
||
function switchFulltime(id) {
|
||
if ($('#fullTime').prop('checked')) {
|
||
$('.enddate').css('visibility', 'hidden');
|
||
$('.enddatespan').hide();
|
||
}
|
||
else {
|
||
$('.enddate').css('visibility', 'visible');
|
||
$('.enddatespan').show();
|
||
}
|
||
|
||
}
|
||
function onPercentageSlide(event, ui, obj) {
|
||
var value = ui.value;
|
||
obj.children(".sliderValue").val(value);
|
||
obj.children(".sliderTitle").html(value + '%');
|
||
}
|
||
function onPercentageChange(event, ui, obj) {
|
||
var value = ui.value;
|
||
obj.children(".sliderValue").val(value);
|
||
obj.children(".sliderTitle").html(value + '%');
|
||
}
|
||
function changeScope(value) {
|
||
var scope = angular.element(document.getElementById('controller')).scope();
|
||
scope.onPercentageChange(value);
|
||
}
|
||
function showWarningModal(title, message) {
|
||
var modal = $("#modal-warning");
|
||
if (modal != null) {
|
||
var divTitle = $("#modal-warning .modal-title");
|
||
if (divTitle != null)
|
||
divTitle.text(title);
|
||
var divMessage = $("#modal-warning .modal-body");
|
||
if (divMessage != null) {
|
||
divMessage.text($.trim(message));
|
||
if (divMessage.text().length > 0) {
|
||
$("#modal-warning").modal();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
function loadForecastPanel(id) {
|
||
//reset forecast block menu
|
||
var paramsObj = {
|
||
teamId: id,
|
||
mode: 'team'
|
||
};
|
||
var loadUrl = '@Url.Action("Index", "ForecastDashboard")?menuId=visibilitydropdown&src=Team_Board&additionalFilters=' + JSON.stringify(paramsObj);
|
||
$("#forecastBlock")
|
||
.load(loadUrl, function (response, status, xhr) {
|
||
if (status == "error") {
|
||
showErrorModal('Loading error', 'We are sorry but there was an error, please try again later.');
|
||
} else {
|
||
initForecastDashboard();
|
||
}
|
||
});
|
||
}
|
||
</script>
|
||
}
|
||
|
||
<style type="text/css">
|
||
#capacity-table .headcol {
|
||
left : -3px;
|
||
}
|
||
</style>
|
||
|
||
<div class="table-light table-responsive" ng-app="app">
|
||
<input type="hidden" id="SelectedTeamId" name="SelectedTeamId" />
|
||
<div class="panel">
|
||
<div class="panel-body">
|
||
<div id="controller" ng-controller="teamDetailsCalendarController">
|
||
@if (Model.Teams.Count > 1)
|
||
{
|
||
<div class="form-group">
|
||
<label class="col col-sm-1 control-label" style="margin-top: 5px;">Team</label>
|
||
<div class="col col-sm-2">
|
||
@Html.DropDownList("list", Model.Teams.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name }),
|
||
new { @onchange = "selectTeam($(event.target).val())", @class = "form-control", @ng_model = "teamId", @ng_change = "teamChanged()" })
|
||
@* <select id="list" ng-model="teamId" name="list" ng-options="s.Value as s.Text for s in teams" onchange = "selectTeam($(event.target).val())" ng_change = "teamChanged()" class="form-control"></select>*@
|
||
</div>
|
||
<div class="col col-sm-2">
|
||
<span id="resourceInfoLoaderIndicator" class="control-label" style="margin-left: 10px; display: none;">
|
||
<img src="~/Content/images/load.gif" />
|
||
loading...</span>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<div id="TeamInfo">
|
||
@if (Model.Teams.Count > 0)
|
||
{
|
||
Html.Partial("~/Views/PeopleResource/_resourcesList.cshtml", Model.Teams.First());
|
||
}
|
||
else
|
||
{
|
||
<label class="label">You do not have access to any team</label>
|
||
}
|
||
</div>
|
||
|
||
<div class="panel">
|
||
<div class="panel-heading">
|
||
<span class="panel-title ui-expander">
|
||
<a data-toggle="collapse" data-target="#panelSkills" class="collapsed">
|
||
<i class="panel-title-icon fa fa-wrench"></i>Skills
|
||
</a>
|
||
</span>
|
||
</div>
|
||
<div id="panelSkills" class="panel-collapse collapse">
|
||
<div class="panel-body padding-sm">
|
||
Skills info placeholder
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel">
|
||
<div class="panel-heading">
|
||
<span class="panel-title ui-expander">
|
||
<a data-toggle="collapse" data-target="#panelCapacityPlanning">
|
||
<i class="panel-title-icon fa fa-tasks"></i>Capacity Planning
|
||
</a>
|
||
</span>
|
||
<span class="pull-right"> </span>
|
||
</div>
|
||
<div id="panelCapacityPlanning" class="panel-collapse collapse in">
|
||
<div class="panel-body padding-sm">
|
||
<ul id="uidemo-tabs-default-demo" class="nav nav-tabs">
|
||
<li class="active">
|
||
<a href="#general" data-toggle="tab">Simple<span class="badge badge-primary"></span></a>
|
||
</li>
|
||
<li>
|
||
<a href="#other" data-toggle="tab">Advanced<span class=" badge badge-primary"></span></a>
|
||
</li>
|
||
</ul>
|
||
<div class="tab-content tab-content-bordered">
|
||
<div class="tab-pane fade in active" id="general">
|
||
<div class="row">
|
||
<div class="col-lg-2 col-md-3 col-sm-4">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label">Expenditure Category</label>
|
||
<select id="capacityExpCat" class="form-control" name="capacityExpCat">
|
||
</select>
|
||
@*@Html.DropDownList("capacityExpCat", Utils.GetTeamExpenditureCategories(Guid.Parse("63cba2d8-e92c-489c-9eec-ef17a9d6319e")), new { @id = "capacityExpCat", @class = "form-control" })*@
|
||
</div>
|
||
</div>
|
||
<div class="col-lg-3 col-md-4 col-sm-5">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label">Start<span class="enddatespan">/End</span> Date</label>
|
||
<div>
|
||
<div class="input-daterange input-group" id="bs-datepicker-range" style="float:left;width:75%">
|
||
<input class="form-control valid" id="capacityStartDate" name="capacityStartDate" type="text" value="@(new DateTime(DateTime.Today.Year, DateTime.Today.Month + 1, 1).ToShortDateString())">
|
||
<span class="input-group-addon enddate">to</span>
|
||
<input class="form-control enddate" id="capacityEndDate" name="capacityEndDate" type="text" value="@(new DateTime(DateTime.Today.Year + 1, DateTime.Today.Month + 1, 1).AddDays(-1).ToShortDateString())">
|
||
|
||
</div>
|
||
<div style="float:left;margin-left:5px;padding-top:5px;">
|
||
<input type="checkbox" name="fullTime" id="fullTime" onclick="switchFulltime()" /> Full time
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="col-lg-2 col-md-3 col-sm-4">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label">Number of Resources</label>
|
||
<input id="capacityAmount" class="form-control" />
|
||
</div>
|
||
</div>
|
||
<div class="col-lg-3 col-md-3 col-sm-4">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label"> </label><br />
|
||
<a class="btn btn-primary" onclick="increaseCapasity();"><i class="fa fa-arrow-up "></i> Increase</a>
|
||
<a class="btn btn-danger" onclick="decreaseCapasity();"><i class="fa fa-arrow-down "></i> Decrease</a>
|
||
<a class="btn btn-danger" onclick="resetCapasity();"><i class="fa fa-refresh"></i> Reset</a>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
</div>
|
||
</div>
|
||
<div class="tab-pane fade in" id="other">
|
||
<div style="float: left; margin: 5px;">Default View</div>
|
||
<div style="float: left; margin: 3px; margin-right: 10px;">
|
||
<input type="checkbox" name="monthWeekMode" id="monthWeekMode" class="switcher" ng-model="calendarFilters.IsViewModeMonth" ng-click="switchViewMode()" />
|
||
</div>
|
||
<button class="btn btn-success" id="btnReloadCalendar" ng-click="getCalendar()"><i class="fa fa-refresh"></i> Reload</button>
|
||
<div class="btn-group">
|
||
<button type="button" class="btn btn-primary btn-top" data-toggle="modal" data-target="#push_pull" ng-disabled="!anyChecked()">Push/Pull Category Resource</button>
|
||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" ng-disabled="!anyChecked()"><i class="fa fa-caret-down"></i></button>
|
||
<ul class='dropdown-menu dropdown-menu-form' role='menu'>
|
||
<li><a ng-click="quickPushPull(true, 1)" href="#">Push 1 wk</a></li>
|
||
<li><a ng-click="quickPushPull(true, 2)" href="#">Push 2 wk</a></li>
|
||
<li><a ng-click="quickPushPull(true, 3)" href="#">Push 3 wk</a></li>
|
||
<li class="divider"></li>
|
||
<li><a ng-click="quickPushPull(false, 1)" href="#">Pull 1 wk</a></li>
|
||
<li><a ng-click="quickPushPull(false, 2)" href="#">Pull 2 wk</a></li>
|
||
<li><a ng-click="quickPushPull(false, 3)" href="#">Pull 3 wk</a></li>
|
||
</ul>
|
||
</div>
|
||
<button class="btn btn-primary" data-toggle="modal" data-target="#reallocator">Reallocate Resource</button>
|
||
<button class="btn btn-primary" data-toggle="modal" data-target="#editTotal">Edit Total</button>
|
||
<button class="btn btn-primary" data-toggle="modal" data-target="#modalFormatCells" ng-click="prefillFormatCells()" ng-disabled="!anyChecked()">Format Cells</button>
|
||
<button class="btn btn-danger" ng-disabled="!anyUpdated()" ng-click="saveChanges()"><i class="fa fa-trash-o"></i> Save Changes</button>
|
||
|
||
|
||
|
||
<div class="table-light table-responsive very-big-table freezeTable">
|
||
<table class="table table-striped table-bordered dataTable" id="table" ng-if="data != null">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 20px;" class="headcol"></th>
|
||
<th style="width: 300px; left: 38px;" class="headcol">Name</th>
|
||
<th style="width: 100px; left: 355px;" class="headcol">Grand Totals</th>
|
||
<th ng-repeat="header in (data.Headers | filter : {IsMonth:true})" style="text-decoration: underline; color: #4083a9; cursor: pointer;" 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}}
|
||
</th>
|
||
</tr>
|
||
<tr>
|
||
<th style="width: 20px;" class="headcol">
|
||
<input type="checkbox" ng-model="data.ScenarioCalendar[0].Checked" ng-click="checkAll()" /></th>
|
||
<th style="width: 300px; left: 38px;" class="headcol"></th>
|
||
<th style="width: 100px; left: 355px;" class="headcol"></th>
|
||
<th ng-repeat="header in data.Headers" ng-show="header.Show">{{ header.IsMonth ? '' : header.Title}}
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody ng-repeat="row in data.ScenarioCalendar" ng-if="$index > 0">
|
||
<tr ng-if="checkEditable(row.UseType)">
|
||
<td style="width: 20px;" class="headcol">
|
||
<input type="checkbox" ng-model="row.Checked" ng-click="collectchecked(row)" />
|
||
</td>
|
||
<td style="width: 300px; left: 38px; " class="headcol" ng-click="onExpCatClick(row)" resize-freez>
|
||
|
||
{{ row.ExpCatName || 'empty' }}
|
||
</td>
|
||
<td style="width: 100px; left: 355px;" class="headcol">
|
||
<span>{{ calendarFilters.IsTableModeQuantity ? (row.GrandTotalQuantity || 0 | number:2) : (row.GrandTotalCost || 0 | currency) }}</span>
|
||
</td>
|
||
<td class="{{$index}}" ng-class="{cellover : !data.Headers[$index].IsMonth && calendarFilters.IsTableModeQuantity && row.RestQuantity[$index] < 0}" ng-repeat="col in (calendarFilters.IsTableModeQuantity ? row.QuantityValues : row.CostValues) track by $index" ng-show="data.Headers[$index].Show">
|
||
<a href="#" ng-click="resizeFreezAng()" editable-text="col" e-name="ColValue" e-ng-blur="onTxtBlur(this);" onshow="watchKeyInput(this)" buttons="no" blur="submit" onbeforesave="checkValue($data, row.ExpCatId, $index)" ng-if="(!data.Headers[$index].IsMonth)" e-required>{{ calendarFilters.IsTableModeQuantity ? (col || 0 | number:2) : (col || 0 | currency) }}
|
||
</a>
|
||
<span ng-show="data.Headers[$index].IsMonth">{{ calendarFilters.IsTableModeQuantity ? (col || 0 | number:2) : (col || 0 | currency) }}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
<tr ng-if="!checkEditable(row.UseType)">
|
||
<td style="width: 20px;" class="headcol">
|
||
<input type="checkbox" class="cb_checked" ng-model="row.Checked" ng-click="collectchecked(row)" />
|
||
</td>
|
||
<td style="width: 300px; left: 38px;" class="headcol" ng-click="onExpCatClick(row)" resize-freez>
|
||
|
||
{{ row.ExpCatName || 'empty' }}
|
||
</td>
|
||
<td style="width: 100px; left: 355px;" class="headcol">
|
||
<span>{{ calendarFilters.IsTableModeQuantity ? (row.GrandTotalQuantity || 0 | number:2) : (row.GrandTotalCost || 0 | currency) }}</span>
|
||
</td>
|
||
<td class="{{$index}}" ng-class="getCellCss(row.ExpCatId, $index)" ng-repeat="col in (calendarFilters.IsTableModeQuantity ? row.QuantityValues : row.CostValues) track by $index" ng-show="data.Headers[$index].Show">
|
||
<span>{{ calendarFilters.IsTableModeQuantity ? (col || 0 | number:2) : (col || 0 | currency) }}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
<tfoot>
|
||
<tr>
|
||
<td colspan="2" style="width: 338px; text-align: right;" class="headcol">{{data.ScenarioCalendar[0].ExpCatName}}</td>
|
||
<td style="width: 100px; left: 355px;" class="headcol">{{calendarFilters.IsTableModeQuantity ? (data.ScenarioCalendar[0].GrandTotalQuantity || 0 | number:2) : (data.ScenarioCalendar[0].GrandTotalCost || 0 | currency)}}</td>
|
||
<td class="{{$index}}" ng-repeat="col in (calendarFilters.IsTableModeQuantity ? data.ScenarioCalendar[0].QuantityValues : data.ScenarioCalendar[0].CostValues) track by $index" ng-show="data.Headers[$index].Show">{{ calendarFilters.IsTableModeQuantity ? (col || 0 | number:2) : (col || 0 | currency) }}
|
||
</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Modal -->
|
||
<form name="editTotalForm">
|
||
<div id="editTotal" class="modal fade" tabindex="-1" role="dialog" style="display: none;">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||
<h4 class="modal-title">Edit Total</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Expenditure Category</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="editTotal.ExpCat" ng-options="s.Id as s.Name for s in availableExpenditures" ng-change="recalcTotal()" class="form-control">
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Quantity/Cost</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="editTotal.SeatsCost" ng-options="option.value as option.name for option in typeOptions" ng-change="recalcTotal()" class="form-control"></select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Old Total Value</label>
|
||
<div class="col-sm-8">
|
||
<input ng-model="editTotal.CurrentTotal" class="form-control" disabled="disabled" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">New Total Value</label>
|
||
<div class="col-sm-8">
|
||
<input ng-model="editTotal.NewTotal" name="NewTotal" class="form-control" required />
|
||
</div>
|
||
<div class="col-sm-offset-4 col-sm-6">
|
||
<span class="validation-error" ng-show="editTotalForm.NewTotal.$error.required">NewTotal is a required field</span>
|
||
</div>
|
||
</div>
|
||
|
||
<hr>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Use Current Curve</label>
|
||
<div class="col-sm-8">
|
||
<input type="radio" ng-model="editTotal.Curve" value="source">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Use Different Curve</label>
|
||
<div class="col-sm-8">
|
||
<div class="radio">
|
||
<input type="radio" ng-model="editTotal.Curve" value="other">
|
||
<select ng-model="reallocator.OtherCurve" name="selCategoryCurve" ng-disabled="!isOtherSelectedTotal()" ng-options="s.Id as s.Name for s in availableExpenditures" class="form-control">
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-body -->
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-click="editTotalFunc()">Save</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-content -->
|
||
</div>
|
||
<!-- / .modal-dialog -->
|
||
</div>
|
||
<!-- /.modal -->
|
||
</form>
|
||
<!-- / Modal -->
|
||
<!-- Modal -->
|
||
<form name="reallocatorForm">
|
||
<div id="reallocator" class="modal fade" tabindex="-1" role="dialog" style="display: none;">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||
<h4 class="modal-title">Reallocate Resource</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<h4>Expenditure Category</h4>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">From</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="reallocator.SourceExpCat" ng-options="s.Id as s.Name for s in availableExpenditures" class="form-control"></select>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">To</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="reallocator.TargetExpCat" ng-options="s.Id as s.Name for s in availableExpenditures" class="form-control"></select>
|
||
</div>
|
||
</div>
|
||
<h4>Week Ending</h4>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">From</label>
|
||
<div class="col-sm-8">
|
||
<div class="input-group date" id="bs-datepicker-from">
|
||
<input type="text" ng-model="reallocator.SourceWeekEnding" name="SourceWeekEnding" class="form-control" ng-value="reallocator.SourceWeekEnding" required><span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-offset-4 col-sm-6">
|
||
<span class="validation-error" ng-show="reallocatorForm.SourceWeekEnding.$error.required">Source WeekEnding is a required field</span>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">To</label>
|
||
<div class="col-sm-8">
|
||
<div class="input-group date" id="bs-datepicker-to">
|
||
<input type="text" ng-model="reallocator.TargetWeekEnding" name="TargetWeekEnding" class="form-control" ng-value="reallocator.TargetWeekEnding" required><span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-offset-4 col-sm-6">
|
||
<span class="validation-error" ng-show="reallocatorForm.TargetWeekEnding.$error.required">Target WeekEnding is a required field</span>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">% to Transfer</label>
|
||
<div class="col-sm-8">
|
||
<div id="percentage_container">
|
||
<input id="percentage" type="hidden" class="sliderValue" ng-value="reallocator.Percentage" />
|
||
<span class="sliderTitle">100%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Reallocate By</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="reallocator.ReallocateBy" ng-options="option.value as option.name for option in typeOptions" class="form-control"></select>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label">Use Source Curve</label>
|
||
<div class="col-sm-8">
|
||
<input type="radio" ng-model="reallocator.CurveType" value="source">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selCategoryTypes">Use Target Curve</label>
|
||
<div class="col-sm-8">
|
||
<input type="radio" ng-model="reallocator.CurveType" value="target">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selCategoryTypes">Use Different Curve</label>
|
||
<div class="col-sm-8">
|
||
<div class="radio">
|
||
<input type="radio" ng-model="reallocator.CurveType" value="other">
|
||
<select ng-model="reallocator.OtherCurve" name="selCategoryCurve" ng-disabled="!isOtherSelectedReallocator()" ng-options="s.Id as s.Name for s in availableExpenditures" class="form-control"></select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-body -->
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-click="reallocateResource()">Reallocate</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-content -->
|
||
</div>
|
||
<!-- / .modal-dialog -->
|
||
</div>
|
||
<!-- /.modal -->
|
||
</form>
|
||
<!-- / Modal -->
|
||
<!-- Modal -->
|
||
<form name="pushPullForm">
|
||
<div id="push_pull" class="modal fade" tabindex="-1" role="dialog" style="display: none;">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||
<h4 class="modal-title">Push/Pull</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<div class="col-sm-4">
|
||
</div>
|
||
<div class="col-sm-8">
|
||
<div class="col-sm-6">
|
||
<label class="col-sm-4 control-label" for="sourceType">Push</label>
|
||
<input type="radio" ng-model="pushpuller.push" name="sourceType" ng-value="true" checked="checked">
|
||
</div>
|
||
|
||
<div class="col-sm-5">
|
||
<label class="col-sm-4 control-label" for="sourceType">Pull</label>
|
||
<input type="radio" ng-model="pushpuller.push" name="sourceType" ng-value="false">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selCategoryTypes">Resources</label>
|
||
<div class="col-sm-8">
|
||
<select multiple="multiple" ng-model="pushpuller.resource" class="form-control" ng-options="s.ExpCatId as s.ExpCatName for s in checkedExpenditures"></select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selCategoryTypes">By number of weeks</label>
|
||
<div class="col-sm-8">
|
||
<input ng-model="pushpuller.weeks" style="width: 60px;" type="number" id="replyNumber" name="replyNumber" min="0" data-bind="value: replyNumber" required />
|
||
</div>
|
||
<div class="col-sm-6">
|
||
<span class="validation-error" ng-show="pushPullForm.replyNumber.$error.required">Reply Number is a required field</span>
|
||
<span class="validation-error" ng-show="pushPullForm.replyNumber.$error.min">Reply Number can't be less 0</span>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
<!-- / .modal-body -->
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-click="pushPull()">OK</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-content -->
|
||
</div>
|
||
<!-- / .modal-dialog -->
|
||
</div>
|
||
<!-- /.modal -->
|
||
</form>
|
||
<!-- / Modal -->
|
||
<!-- / Modal -->
|
||
<form name="formatCellsForm">
|
||
<div id="modalFormatCells" class="modal fade" tabindex="-1" role="dialog" style="display: none;">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||
<h4 class="modal-title">Format Cells</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="panel-body form-horizontal">
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selFormatExpCats">Expenditure Categories</label>
|
||
<div class="col-sm-8">
|
||
<select ng-model="formatCells.SelectedExpCats" name="selFormatExpCats" ng-options="s.Id as s.Name for s in formatCells.ExpCats"
|
||
class="form-control" size="8" style="height: 173px;">
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="selFormatExpCats">Week Ending from</label>
|
||
<div class="col-sm-8">
|
||
<div class="input-daterange input-group" style="z-index: 1040;" id="fs-datepicker-range">
|
||
<input class="form-control" ng-model="formatCells.StartDate" id="formatStartDate" name="formatStartDate" type="text" required />
|
||
<span class="input-group-addon">to</span>
|
||
<input class="form-control" ng-model="formatCells.EndDate" id="formatEndDate" name="formatEndDate" type="text" required />
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-offset-4 col-sm-6">
|
||
<span class="validation-error" ng-show="formatCellsForm.formatStartDate.$error.required">Start Date is a required field</span>
|
||
<br />
|
||
<span class="validation-error" ng-show="formatCellsForm.formatEndDate.$error.required">End Date is a required field</span>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="col-sm-4 control-label" for="formatCellsDecimalPlaces">Decimal Places</label>
|
||
<div class="col-sm-2">
|
||
<input type="number" min="0" max="5" ng-model="formatCells.DecimalPlaces" name="formatCellsDecimalPlaces" class="form-control" required />
|
||
</div>
|
||
<div class="col-sm-6">
|
||
<span class="validation-error" ng-show="formatCellsForm.formatCellsDecimalPlaces.$error.required">DecimalPlaces is a required field</span>
|
||
<span class="validation-error" ng-show="formatCellsForm.formatCellsDecimalPlaces.$error.min">DecimalPlaces has so min value</span>
|
||
<span class="validation-error" ng-show="formatCellsForm.formatCellsDecimalPlaces.$error.max">DecimalPlaces has too long value</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-click="submitFormatCells()">Ok</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-content -->
|
||
</div>
|
||
<!-- / .modal-dialog -->
|
||
</div>
|
||
<!-- / .modal -->
|
||
</form>
|
||
<!-- / Modal -->
|
||
<!-- Warning modal alert -->
|
||
<div id="modal-warning" class="modal modal-alert modal-warning fade">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<i class="fa fa-times-circle"></i>
|
||
</div>
|
||
<div class="modal-title"></div>
|
||
<div class="modal-body"></div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-danger" data-dismiss="modal">OK</button>
|
||
</div>
|
||
</div>
|
||
<!-- / .modal-content -->
|
||
</div>
|
||
<!-- / .modal-dialog -->
|
||
</div>
|
||
<!-- / .modal -->
|
||
<!-- Modal -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- / .panel-body -->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel">
|
||
<div class="panel-heading">
|
||
<span class="panel-title ui-expander">
|
||
<a data-toggle="collapse" data-target="#panelTeamCalendar" class="collapsed">
|
||
<i class="panel-title-icon fa fa-calendar"></i>Team Calendar
|
||
</a>
|
||
</span>
|
||
<span class="pull-right"> </span>
|
||
<div class="btn-group btn-group-xs pull-right" id="divCalendarMenu" style="display: none;">
|
||
<button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown"><i class="fa fa-bars"></i> <i class="fa fa-caret-down"></i></button>
|
||
<ul class="dropdown-menu dropdown-menu-right" id="visibilitydropdown_calendar">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="panelTeamCalendar" class="panel-collapse collapse">
|
||
<div class="panel-body padding-sm">
|
||
@Html.Partial("../CapacityManagement/_capacityManagement", Model)
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel widget-messages-alt">
|
||
<div class="panel-heading">
|
||
<span class="panel-title ui-expander">
|
||
<a data-toggle="collapse" data-target="#panelForecast" class="collapsed">
|
||
<i class="panel-title-icon fa fa-bar-chart-o"></i>Team Forecast
|
||
</a>
|
||
</span>
|
||
<span class="pull-right"> </span>
|
||
<div class="btn-group btn-group-xs pull-right" id="divForecastMenu" style="display: none;">
|
||
<button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown"><i class="fa fa-bars"></i> <i class="fa fa-caret-down"></i></button>
|
||
<ul class="dropdown-menu dropdown-menu-right" id="visibilitydropdown">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="panelForecast" class="panel-collapse collapse">
|
||
<div class="panel-body padding-sm">
|
||
<div class="panel" id="graph-container">
|
||
<div class="panel-body">
|
||
@{
|
||
Html.RenderPartial("_chart");
|
||
}
|
||
</div>
|
||
</div>
|
||
<div class="messages-list" id="forecastBlock"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|