EnVisageOnline/Main/Source/EnVisage/Views/Scenarios/_generalStep.cshtml

441 lines
20 KiB
Plaintext

@using EnVisage.Code
@using EnVisage.Models
@model CreateScenarioModel.GeneralInfoModel
@{
// need to init cost saving controller
var jsModel = new
{
deadlineDate = Model.ProjectDeadline.HasValue ? Model.ProjectDeadline.Value.ToString("MM/dd/yyyy") : null
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(jsModel);
}
<script type="text/javascript">
function onStep1Failure(xhr) {
showErrorModal();
$('#Action').val('');
}
function onStep1Success(result) {
if (!!result && !!result.Html) {
$('#generalStep').html(result.Html);
if (result.Status) {
initStep1(true);
_detailsController.init(result.Data, stepSubmitCallback);
}
else {
initStep1(false);
}
return;
}
$('#Action').val('');
}
function initDatePickers() {
var options = {
format: 'mm/dd/yyyy',
autoclose: true,
orientation: $('body').hasClass('right-to-left') ? "auto right" : 'auto auto',
startDate: '@Constants.MIN_SELECTABLE_DATE',
endDate: '@(!string.IsNullOrWhiteSpace(jsModel.deadlineDate) ? jsModel.deadlineDate : Constants.MAX_SELECTABLE_DATE)'
};
$('#bs-datepicker-scenario-range').datepicker(options);
$('#bs-datepicker-scenario-range').find('#@Html.IdFor(x=> x.StartDate)').on('change', function (e) {
var startDate = new Date($(this).val());
var endDate = $('#bs-datepicker-scenario-range').find('#@Html.IdFor(x=> x.EndDate)').val();
//AG: ENV-782. The API of this forked datepicker does not seem to work correct or we use it incorrectly in this particularly case -
//I cannot access datepicker methods by standard $(selector).datepicker('method', arg1, arg2, ...)
//Setting date value directly into the textbox does not work as it does not call inline calendar update
//so we need to use API method for that
// SA: We update datepicker component inner date (for scenario finish date) and then reset
// the inner date. When inner date set, the calendar scrolls to this date and shows it,
// when expanded. And when we reset inner date then, the control still shows the proper month
// in its expandable panel
if (!endDate && startDate.getTime() > 0) {
$('#bs-datepicker-scenario-range').data('datepicker').pickers[1].viewDate = new Date(startDate.getFullYear(), startDate.getMonth(), 12);
//$('#bs-datepicker-scenario-range').data('datepicker').pickers[1].update(startDate);
//$('#bs-datepicker-scenario-range').data('datepicker').pickers[1].update('');
}
triggerScenarioRangeChangedEvent();
});
$('#bs-datepicker-scenario-range').find('#@Html.IdFor(x=> x.EndDate)').on('change', function (e) {
triggerScenarioRangeChangedEvent();
});
$('#bs-datepicker-scenario-range span.input-group-addon').hide();
}
function triggerScenarioRangeChangedEvent() {
var startDateEl = $('#bs-datepicker-scenario-range').find('#@Html.IdFor(x=> x.StartDate)'),
endDateEl = $('#bs-datepicker-scenario-range').find('#@Html.IdFor(x=> x.EndDate)');
var eventData = {
startDate: startDateEl.val(),
endDate: endDateEl.val()
};
// Check dates and display warnings
var displayWarning = dateConstraintsViolated(eventData.startDate, eventData.endDate);
if (displayWarning) {
$('#dates-constraints-warning').show();
}
else {
$('#dates-constraints-warning').hide();
}
triggerBroadcastFromRootScope('scenarioRangeChanged', eventData);
}
function dateConstraintsViolated(startDate, endDate) {
if (!projectHasDependencies)
return false;
var newScenarioStatusIsActive = $('#@Html.IdFor(x=> x.CreateAsActive)').is(':checked');
if (!newScenarioStatusIsActive)
return false;
var startDateConstraint = @(Model.StartDateConstraintMs.HasValue ? String.Format("{0}; // {1}", Model.StartDateConstraintMs.Value.ToString(), Model.StartDateConstraint.Value.ToShortDateString()) : "null");
var endDateConstraint = @(Model.EndDateConstraintMs.HasValue ? String.Format("{0}; // {1}", Model.EndDateConstraintMs.Value.ToString(), Model.EndDateConstraint.Value.ToShortDateString()) : "null");
var startDateVioldated = false;
var endDateVioldated = false;
if (startDate && startDateConstraint) {
var startDateMs = DateTimeConverter.stringToMs(startDate);
startDateVioldated = startDateMs < startDateConstraint;
}
if (endDate && endDateConstraint) {
var endDateMs = DateTimeConverter.stringToMs(endDate);
endDateVioldated = endDateMs > endDateConstraint;
}
return startDateVioldated || endDateVioldated;
}
function initSwitchers() {
$('input.yes-no-switcher').switcher({
on_state_content: 'Yes',
off_state_content: 'No'
}).parent().css("width", "80px");
$('#@Html.IdFor(x=> x.IsBottomUp)').switcher({
on_state_content: 'Bottom Up',
off_state_content: 'Top Down'
}).parent().css("width", "100px");
$('input[type=hidden][name=@Html.NameFor(x=> x.IsBottomUp)]').val(@Model.IsBottomUp.ToString().ToLower());
$('#@Html.IdFor(x=> x.IsBottomUp)').on('change', function (e, r) {
var isBottomUp = $(this).is(':checked');
$('input[type=hidden][name=@Html.NameFor(x=> x.IsBottomUp)]').val(isBottomUp);
refreshFormAccordingToScenarioType(isBottomUp);
refreshSlidersVisibilityAccordingToScenarioType(isBottomUp);
});
$('#@Html.IdFor(x=> x.TemplateId)').on('change', onTemplateChanged);
if (projectHasDependencies) {
$('#@Html.IdFor(x=> x.CreateAsActive)').on('change', onScenarioStatusChanged);
}
}
function triggerScenarioWorkFlowChangedEvent(e) {
var value = e.val;
var eventData = {
WorkFlowSchema: value
};
triggerBroadcastFromRootScope('scenarioWorkFlowSchemaChanged', eventData);
}
function initStep1(disableSliders, projectId) {
setTemplatesDataSource(@Model.IsBottomUp.ToString().ToLower());
$("#wfSchemaName").select2({
allowClear: true
}).on("select2-selecting", function (e) { triggerScenarioWorkFlowChangedEvent(e); }).on("select2-clearing",function(e){triggerScenarioWorkFlowChangedEvent(e);});
$("#generalStep .forselect2").select2({
allowClear: true,
minimumResultsForSearch: 5
});
initDatePickers();
initSwitchers();
compileDynamicAngularHtml($("#teamsContainer"));
$('#teamsContainer').on('$destroy', destroyAngularForm);
$.validator.unobtrusive.parseDynamicContent("#generalStepForm");
reloadEC(true);
if (disableSliders) {
var slidersController = getSlidersController();
if (slidersController) {
slidersController.$apply(function () {
slidersController.setReadonly();
});
}
}
refreshSlidersVisibilityAccordingToScenarioType(@Model.IsBottomUp.ToString().ToLower());
$('#generalStep').find('input[type=checkbox],input[type=text],select,textarea').on("change", function () {
if (typeof onScenarioDataChanged === 'function')
onScenarioDataChanged();
});
if (projectHasDependencies) {
var elem = $('div.date-dependency-constraints');
if (elem && elem.length) {
elem.scenarioDependencyInformer({
projectId: projectId,
dataUrl: '@Url.Action("GetDependencies", "Project")'
});
}
$('#@Html.IdFor(x=> x.CreateAsActive)').trigger('change');
}
}
function onTemplateChanged(e, skipValidation) {
$('input[type=hidden][name=@Html.NameFor(x=> x.TemplateId)]').val($(this).val());
if (!skipValidation) {
$(this).parents('form').validate().element($(this));
}
reloadEC(false);
}
function setTemplatesDataSource(isBottomUp) {
if (isBottomUp) {
$("#@Html.IdFor(x=> x.TemplateId)").html('@Utils.GetTemplates(Model.TemplateId, true)');
}
else {
$("#@Html.IdFor(x=> x.TemplateId)").html('@Utils.GetTemplates(Model.TemplateId, false)');
}
};
function onScenarioStatusChanged(e) {
if (!projectHasDependencies)
return;
var newScenarioStatusIsActive = $('#@Html.IdFor(x=> x.CreateAsActive)').is(':checked');
var elem = $('div.date-dependency-constraints');
if (newScenarioStatusIsActive)
elem.scenarioDependencyInformer('show');
else
elem.scenarioDependencyInformer('hide');
// Call to hide any dependency warning, if visible any
triggerScenarioRangeChangedEvent();
};
function refreshFormAccordingToScenarioType(isBottomUp) {
setTemplatesDataSource(isBottomUp);
if (isBottomUp) {
$('#@Html.IdFor(x=> x.TemplateId)').attr('disabled', 'disabled');
$('input[type=hidden][name=@Html.NameFor(x=> x.TemplateId)]').removeAttr('disabled');
$("#fsCategories").hide();
$("#@Html.IdFor(x=> x.SelectedExpenditures)").select2('val', []);
$("#@Html.IdFor(x=> x.TemplateId)").trigger('change');
}
else {
$("#@Html.IdFor(x=> x.TemplateId)").trigger('change', true);
$('#@Html.IdFor(x=> x.TemplateId)').removeAttr('disabled');
$('input[type=hidden][name=@Html.NameFor(x=> x.TemplateId)]').attr('disabled', 'disabled');
$("#fsCategories").show();
}
};
function refreshSlidersVisibilityAccordingToScenarioType(isBottomUp) {
var slidersController = getSlidersController();
if (slidersController) {
slidersController.$apply(function () {
slidersController.changeSlidersVisibility(!isBottomUp);
});
}
};
function reloadEC(overrideChecked) {
var templateId = $('#@Html.IdFor(x=> x.TemplateId)').val();
if (!templateId)
return;
var selectedCategories = $('#@Html.IdFor(x=> x.SelectedExpenditures)').val();
var scope = angular.element(document.getElementById('slidersGroupContainer_@(Model.Teams.GroupDisplayId)')).scope();
var scenarioTeams = scope.getTeamList();
blockUI();
$.post('@Url.Action("GetECsByTemplateId", "Scenarios")', {
'Id': templateId,
'selectedExpCats': !!selectedCategories ? selectedCategories.split(',') : [],
'teams': scenarioTeams,
'overrideChecked': overrideChecked
}, function (data) {
if (!$("#SelectedExpenditures").data('select2')) {
// Multiselect
$("#@Html.IdFor(x=> x.SelectedExpenditures)").select2({
placeholder: "Select an Expenditure",
data: data.options,
multiple: true,
}).on('change', function () {
$(this).closest('form').validate().element($(this));
});
$("#@Html.IdFor(x => x.SelectedExpenditures)").select2('val', data.selected);
}
else {
// we should trigger change event manually because select2 widget does not do it when we set new value programmatically
$("#@Html.IdFor(x => x.SelectedExpenditures)").select2('val', data.selected).trigger('change');
}
$('#s2id_@Html.IdFor(x => x.SelectedExpenditures) input.select2-default').css('width', '200px');
if (!($("#fsFinancial").is(':visible') || $("#fsDetails").is(':visible'))) {
$("#fsTeamAllocation").show();
}
unblockUI();
});
}
function lockGeneralForm(needToLock) {
if (needToLock) {
$('#@Html.IdFor(x=> x.StartDate)').attr('disabled', 'disabled');
$('[name=@Html.NameFor(x=> x.StartDate)].hdn').removeAttr('disabled');
$('#@Html.IdFor(x=> x.EndDate)').attr('disabled', 'disabled');
$('[name=@Html.NameFor(x=> x.EndDate)].hdn').removeAttr('disabled');
$('#@Html.IdFor(x=> x.TemplateId)').attr('disabled', 'disabled');
$('[name=@Html.NameFor(x=> x.TemplateId)].hdn').removeAttr('disabled');
$('#@Html.IdFor(x=> x.IsBottomUp)').switcher('disable');
}
else {
$('#@Html.IdFor(x=> x.StartDate)').removeAttr('disabled');
$('[name=@Html.NameFor(x=> x.StartDate)].hdn').attr('disabled', 'disabled');
$('#@Html.IdFor(x=> x.EndDate)').removeAttr('disabled');
$('[name=@Html.NameFor(x=> x.EndDate)].hdn').attr('disabled', 'disabled');
$('#@Html.IdFor(x=> x.TemplateId)').removeAttr('disabled');
$('[name=@Html.NameFor(x=> x.TemplateId)].hdn').attr('disabled', 'disabled');
$('#@Html.IdFor(x=> x.IsBottomUp)').switcher('enable');
}
};
function getSlidersController() {
var slidersGroupContainer = $("#teamsContainer").find('*[data-slider-group]');
var slidersController = slidersGroupContainer ? angular.element(slidersGroupContainer.get(0)).scope() : undefined;
return slidersController;
};
</script>
@using (Ajax.BeginForm("SubmitCreateScenarioStep1", "Scenarios", new AjaxOptions
{
HttpMethod = "Post",
OnBegin = "blockUI",
OnSuccess = "onStep1Success",
OnFailure = "onStep1Failure(xhr)",
OnComplete = "unblockUI",
}, new
{
@id = "generalStepForm",
@class = "form-horizontal",
}))
{
@Html.HiddenFor(m => m.ScenarioId)
@Html.HiddenFor(m => m.ProjectId)
@Html.HiddenFor(m => m.PartId)
@Html.HiddenFor(m => m.ProjectDeadline)
@Html.HiddenFor(m => m.StatusIsEditable)
@Html.HiddenFor(m => m.HideName)
@Html.HiddenFor(m => m.SerializedModel)
@Html.AntiForgeryToken()
<fieldset id="fsGeneral" class="form-group-margin">
<legend class="text-bold">Scenario Information</legend>
<div class="row">
<div class="col-sm-7">
<div class="form-group no-margin-hr">
@Html.LabelFor(model => model.ProjectName, new { @class = "control-label" })
@Html.TextBoxFor(model => model.ProjectName, new { @class = "form-control", @readonly = "readonly" })
</div>
</div>
</div>
<div class="row">
@if (!Model.HideName)
{
<div class="col-sm-7">
<div class="form-group no-margin-hr">
@Html.LabelFor(model => model.ScenarioName, new { @class = "control-label" })
@Html.TextBoxFor(model => model.ScenarioName, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ScenarioName)
</div>
</div>
}
<div class="col-sm-5">
<div class="form-group no-margin-hr">
<label class="control-label">Scenario Dates</label>
<div class="input-daterange input-group" id="bs-datepicker-scenario-range">
@Html.EditorFor(t => t.StartDate, new { htmlAttributes = new { @class = "form-control date" } })
<div class="input-group-addon">to</div>
@Html.EditorFor(model => model.EndDate, new { htmlAttributes = new { @class = "form-control date" } })
</div>
<div>
<input type="hidden" name="@Html.NameFor(t => t.StartDate).ToString()" class="hdn" value="@(Model.StartDate.HasValue ? Model.StartDate.Value.ToShortDateString() : string.Empty)" />
<input type="hidden" name="@Html.NameFor(t => t.EndDate).ToString()" class="hdn" value="@(Model.EndDate.HasValue ? Model.EndDate.Value.ToShortDateString() : string.Empty)" />
</div>
@Html.ValidationMessageFor(model => model.StartDate)
@Html.ValidationMessageFor(model => model.EndDate)
@if (Model.ProjectDeadline.HasValue)
{
<div><i>Project Deadline: @Model.ProjectDeadline.Value.ToShortDateString()</i></div>
}
<div class="date-dependency-constraints"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4 col-md-5">
<div class="form-group no-margin-hr">
@Html.LabelFor(model => model.TemplateId, new { @class = "control-label" })
@Html.DropDownListFor(model => model.TemplateId, new List<SelectListItem>(), new { @class = "form-control forselect2" })
<input type="hidden" name="@Html.NameFor(t => t.TemplateId).ToString()" class="hdn" value="@(Model.TemplateId.HasValue ? Model.TemplateId.Value.ToString() : string.Empty)" />
@Html.ValidationMessageFor(model => model.TemplateId)
</div>
</div>
<div class="col-sm-2 col-md-2">
<div class="form-group no-margin-hr switcher-block">
@Html.LabelFor(model => model.IsBottomUp, new { @class = "control-label" })
@Html.CheckBoxFor(model => model.IsBottomUp, new { @class = "switcher form-control" })
</div>
</div>
<div class="col-sm-3 col-md-2">
<div class="form-group no-margin-hr switcher-block @(Model.StatusIsEditable ? "" : "hidden")">
@Html.LabelFor(model => model.CreateAsActive, new { @class = "control-label" })
@Html.CheckBoxFor(model => model.CreateAsActive, new { @class = "switcher form-control yes-no-switcher" })
@Html.ValidationMessageFor(model => model.CreateAsActive)
</div>
</div>
@{
IEnumerable<SelectListItem> workFlowList = Utils.GetWorkFlowSchemas(WorkFlowArea.Scenarios.GetHashCode(), new Guid(User.Identity.GetID()));
if (workFlowList.Count() > 1)
{
<div class="col-sm-4 col-md-3">
<div class="form-group no-margin-hr">
@Html.LabelFor(model => model.WorkFlowSchemaCode, new { @class = "control-label" })
@Html.DropDownListFor(model => model.WorkFlowSchemaCode, workFlowList, new { @class = "form-control", @id = "wfSchemaName" })
<input type="hidden" name="@Html.NameFor(t => t.WorkFlowSchemaCode).ToString()" class="hdn" value="@(!string.IsNullOrEmpty(Model.WorkFlowSchemaCode) ? Model.WorkFlowSchemaCode : string.Empty)" />
@Html.ValidationMessageFor(model => model.WorkFlowSchemaCode)
</div>
</div>
}
}
</div>
</fieldset>
<fieldset id="fsCategories" class="form-group-margin" style="display: @(Model.IsBottomUp ? "none" : "block") ">
<legend class="text-bold small-bottom-margin">Expenditure Categories</legend>
<div class="row">
<div class="form-group no-margin-hr select2-primary">
@Html.TextBoxFor(x => x.SelectedExpenditures)
@Html.ValidationMessageFor(model => model.SelectedExpenditures)
</div>
</div>
</fieldset>
<fieldset id="fsTeamAllocation">
<legend class="text-bold small-bottom-margin">Teams</legend>
<div class="row">
<div class="col-sm-12" id="teamsContainer">
@Html.EditorFor(x => x.Teams)
</div>
</div>
</fieldset>
@Html.ValidationSummary(false, "The scenario could not be saved due to the following errors:")
<div class="alert alert-warning" id="dates-constraints-warning" style="display: none;">
Scenario dates violate project's dependencies date constraints
</div>
}