311 lines
24 KiB
Plaintext
311 lines
24 KiB
Plaintext
@model Object
|
||
@{
|
||
var json = Newtonsoft.Json.JsonConvert.SerializeObject(Model);
|
||
|
||
// Get the target application page, the calendar will be currently displayed in
|
||
// Special formatting of filter controls is needed for Team Board
|
||
var targetPageName = (string)Model.GetType().GetProperty("TargetPage").GetValue(Model, null);
|
||
bool isTeamBoardPage = (targetPageName == "TeamBoard");
|
||
}
|
||
<div id="erorMsgPlaceholder"></div>
|
||
<div ng-controller="capacityManagementController" ng-init="init(@json)">
|
||
<div ng-show="::false" ng-cloak>
|
||
<ul menu-id="DisplayMode.MenuId" change-page-option-value="onPageOptionChange" ng-widget-options-menu data-section="capacityManagementView">
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.CapacityMode.Hide" style="padding-bottom:3px;">
|
||
<span class="switcherLbl">Resource Totals as</span>
|
||
<select ng-select2 ng-model="DisplayMode.CapacityMode.Value" data-key="showOption" minimumResultsForSearch="-1" width="180px"
|
||
ng-change="changeCapacityMode()" ng-disabled="DisplayMode.CapacityMode.Disabled">
|
||
<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>
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.GroupBy.Hide" style="padding-bottom:3px;">
|
||
<span class="switcherLbl">Group by</span>
|
||
<select ng-select2 ng-model="DisplayMode.GroupBy.Value" data-key="groupBy" minimumResultsForSearch="-1" width="180px"
|
||
ng-change="changeGroupBy()" ng-disabled="DisplayMode.GroupBy.Disabled">
|
||
<option ng-repeat="item in DisplayMode.GroupByItems track by $index" value="{{item.value}}">{{item.text}}</option>
|
||
</select>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<span class="switcherLbl">Mode</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.IsUOMHours" data-key="uomMode" class="switcher px"
|
||
ng-sw-on_state_content="# Hours" ng-sw-off_state_content="# Resources" ng-sw-width="93px" />
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<span class="switcherLbl">Projects Displayed as</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.IsBarMode" data-key="capBarMode" class="switcher px"
|
||
ng-sw-on_state_content="Colors" ng-sw-off_state_content="Values" ng-sw-width="73px" />
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<span class="switcherLbl">Default View</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.IsViewModeMonth" data-key="defaultView" class="switcher px"
|
||
ng-sw-on_state_content="Month" ng-sw-off_state_content="Week" ng-sw-width="93px" />
|
||
</li>
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.IsCapacityModeActuals.Hide">
|
||
<span class="switcherLbl">Use Capacity</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.IsCapacityModeActuals.Value" data-key="capacityView" class="switcher px"
|
||
ng-sw-on_state_content="Actual" ng-sw-off_state_content="Planned" ng-sw-width="93px" ng-disabled="DisplayMode.IsCapacityModeActuals.Disabled" />
|
||
</li>
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.ShowParts.Hide">
|
||
<span class="switcherLbl">Parts</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.ShowParts.Value" data-key="showParts" class="switcher px"
|
||
ng-sw-on_state_content="Show" ng-sw-off_state_content="Hide" ng-sw-width="93px" ng-disabled="DisplayMode.ShowParts.Disabled" />
|
||
</li>
|
||
<li class="divider"></li>
|
||
<li class="padding-xs-hr" style="padding-bottom:3px;">
|
||
<span class="switcherLbl" style="padding-top:6px;">Sort By </span>
|
||
<select ng-select2 ng-model="DisplayMode.SortBy" data-key="sortBy" minimumResultsForSearch="-1" dropdownAutoWidth="false" width="104px">
|
||
<option ng-repeat="item in SortByItems track by item.value" value="{{item.value}}">{{item.text}}</option>
|
||
</select>
|
||
</li>
|
||
<li class="padding-xs-hr">
|
||
<span class="switcherLbl">Sort Order</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.SortOrder" data-key="sortOrder" class="switcher px"
|
||
ng-sw-on_state_content="Asc" ng-sw-off_state_content="Desc" />
|
||
</li>
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.ShowUpper.Hide">
|
||
<span class="switcherLbl">Show Projects</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.ShowUpper.Value" data-key="showChart" class="switcher px"
|
||
ng-disabled="DisplayMode.ShowUpper.Disabled" ng-change="switchUpperPart()" />
|
||
</li>
|
||
<li class="padding-xs-hr" ng-show="!DisplayMode.ShowLower.Hide">
|
||
<span class="switcherLbl">Show Resources</span>
|
||
<input type="checkbox" ng-switcher ng-model="DisplayMode.ShowLower.Value" data-key="showCriteria" class="switcher px"
|
||
ng-disabled="DisplayMode.ShowLower.Disabled" ng-change="switchLowerPart()" />
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="form-inline panel-body" ng-cloak>
|
||
<div class="row">
|
||
<form class="form-horizontal" name="filterForm" id="filterForm">
|
||
<div class="col-sm-8 col-md-5 col-lg-4" ng-if="Filter.ShowFilters">
|
||
<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="Filter.EntityType" name="calendarFilterMode" data-ng-value="{{EntityType.Company}}" ng-change="switchFilterMode()" class="form-control" data-key="filterType" /><span class="radio-label">Business Unit</span><div class="radio-gap"></div>
|
||
<input type="radio" ng-model="Filter.EntityType" name="calendarFilterMode" data-ng-value="{{EntityType.View}}" ng-change="switchFilterMode()" class="form-control" data-key="filterType" /><span class="radio-label">View</span><div class="radio-gap"></div>
|
||
<input type="radio" ng-model="Filter.EntityType" name="calendarFilterMode" data-ng-value="{{EntityType.Team}}" ng-change="switchFilterMode()" class="form-control" data-key="filterType" /><span class="radio-label">Team</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-8 col-md-7 col-lg-4" ng-if="Filter.ShowFilters">
|
||
<div class="form-group no-margin-hr" style="width:100%">
|
||
<label class="control-label" for="selFilterElement">{{ Filter.FilteredEntityTitle }}</label><br />
|
||
<select ng-select2 ng-model="Filter.EntityId" name="selFilterElement" allowClear="true" data-key="filteredCompany"
|
||
placeholder="Select option" minimumResultsForSearch="5" ng-change="SelectedFilterElementChanged()"
|
||
option-class-expr="CSSClass" data-val="true" ng-data-val-required="The {{ Filter.FilteredEntityTitle }} field is required.">
|
||
<option></option>
|
||
<option ng-repeat="(optionId, option) in EntityFilterOptions track by $index" value="{{option.Value}}">{{option.Text}}</option>
|
||
</select>
|
||
<span class="field-validation-valid" data-valmsg-for="selFilterElement" data-valmsg-replace="true"></span>
|
||
</div>
|
||
</div>
|
||
<div class="@(isTeamBoardPage ? "col-sm-8 col-md-5 col-lg-5" : "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" ng-date-range start-date="Filter.StartDate" end-date="Filter.EndDate"
|
||
on-change-start-date="onPageOptionChange" on-change-end-date="onPageOptionChange">
|
||
<input class="form-control ng-date-range-start" 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="Filter.StartDate" name="filterStartDate" type="text" />
|
||
<div class="input-group-addon">to</div>
|
||
<input class="form-control enddate ng-date-range-end" data-val="true" data-val-date="The field End Date must be a date." data-val-required="The End Date field is required."
|
||
data-val-dategreaterthanorequal="End Date should not be less than Start Date" data-val-dategreaterthanorequal-otherpropertyname="filterStartDate"
|
||
data-key="capacityFilterEndDate" ng-model="Filter.EndDate" 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="@(isTeamBoardPage ? "col-sm-8 col-md-7 col-lg-7" : "col-sm-8 col-md-7 col-lg-4")">
|
||
<div class="form-group no-margin-hr" style="width:100%">
|
||
<div class="form-group select2-primary no-margin-hr" style="width: 100%;">
|
||
<label class="control-label">Cost Centers:</label>
|
||
<select ng-select2 ng-model="Filter.CostCenters" allowClear="true" data-key="filterCostCenters"
|
||
placeholder="All available Cost Centers" minimumResultsForSearch="5" multiple="multiple"
|
||
ng-change="SelectedFilterCostCentersChanged()" option-class-expr="CSSClass" data-val="true">
|
||
<option ng-repeat="option in AvailableFilterOptions.CostCenters track by $index" value="{{option.Value}}">{{option.Text}}</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="@(isTeamBoardPage ? "col-sm-8 col-md-7 col-lg-7" : "col-sm-8 col-md-7 col-lg-4")">
|
||
<div class="form-group no-margin-hr" style="width:100%">
|
||
<div class="form-group select2-primary no-margin-hr" style="width: 100%;">
|
||
<label class="control-label">Project Roles:</label>
|
||
<select ng-select2 ng-model="Filter.ProjectRoles" allowClear="true" data-key="filterProjectRoles"
|
||
placeholder="Select items to be displayed" minimumResultsForSearch="5" multiple="multiple"
|
||
ng-change="SelectedFilterProjectRolesChanged()" option-class-expr="CSSClass" data-val="true">
|
||
<option ng-repeat="option in AvailableFilterOptions.ProjectRolesVisible track by $index" value="{{option.Value}}">{{option.Text}}</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="@(isTeamBoardPage ? "col-sm-6 col-md-4 col-lg-5" : "col-sm-6 col-md-4 col-lg-3")">
|
||
<div class="form-group no-margin-hr">
|
||
<label class="control-label"> </label><br />
|
||
<button class="btn btn-default" ng-disabled="!filterValid()" ng-click="filterForm.$valid && rebuildCalendar(true)"><i class="fa fa-refresh"></i> Reload</button>
|
||
<button class="btn btn-primary" ng-disabled="!CalendarDataChanged" ng-click="saveChanges()" data-toggle="modal"><i class="fa fa-save"></i> Save Changes</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
@* In this case controller will be initialized via broadcasted event from the parent controller *@
|
||
<div ng-include="DisplayMode.CalendarView" onload="ngIncludeLoaded()"></div>
|
||
|
||
@*
|
||
If you need to use this control multiple times on a single page and without parent capacityManagementController controller use ng-init directive instead
|
||
|
||
<div ng-controller="activityCalendarController" ng-init="{StartDate: startDate1, EndDate: endDate1, ...}">
|
||
@Html.Partial("~/Views/ActivityCalendar/_activityCalendar.cshtml")
|
||
</div>
|
||
<div ng-controller="activityCalendarController" ng-init="{StartDate: startDate2, EndDate: endDate2, ...}">
|
||
@Html.Partial("~/Views/ActivityCalendar/_activityCalendar.cshtml")
|
||
</div>
|
||
<div ng-controller="activityCalendarController" ng-init="{StartDate: startDateN, EndDate: endDateN, ...}">
|
||
@Html.Partial("~/Views/ActivityCalendar/_activityCalendar.cshtml")
|
||
</div>
|
||
*@
|
||
|
||
<div id="saveScenarioModal" class="modal fade" tabindex="-1" role="dialog" style="display: none;" data-backdrop="static"
|
||
ng-modal-dialog-form show-form-event="ac.show-save-dialog" hide-form-event="ac.hide-save-dialog"
|
||
confirm-close-message="Calendar data save form contains unsaved changes, do you really want to close the form?">
|
||
<form name="saveScenarioForm">
|
||
<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-if="!WorkFlowChanges()">
|
||
<div ng-show="SaveChangesDialog.SaveAction == 1 && SaveChangesDialog.ScenarioType == 1 && SaveChangesDialog.ProjectsWithSuperExpenditures.length > 0">
|
||
<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 SaveChangesDialog.ProjectsWithSuperExpenditures ">{{project.ProjectName}}</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="SaveChangesDialog.SaveAction" ng-change="saveScenarioForm_SaveActionChanged()" 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="SaveChangesDialog.SaveAction" ng-change="saveScenarioForm_SaveActionChanged()" value="1" />
|
||
<label for="save-as-new" class="control-label">Create New Scenario</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-group" ng-show="SaveChangesDialog.SaveAction == 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="SaveChangesDialog.ScenarioName" id="scenarioName" name="scenarioName" class="form-control" ng-required="SaveChangesDialog.SaveAction == 1" />
|
||
<span class="field-validation-error" ng-show="SaveChangesDialog.SaveAction == 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-switcher ng-model="SaveChangesDialog.SetActive" class="form-control"
|
||
ng-sw-on_state_content="Active" ng-sw-off_state_content="Inactive" ng-sw-width="100px" />
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<label class="control-label">Scenario Type: </label>
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<select ng-select2 ng-model="SaveChangesDialog.ScenarioType" minimumResultsForSearch="-1" class="form-control"
|
||
ng-change="saveScenarioForm_ScenarioTypeChanged()">
|
||
<option value="0">Keep Current</option>
|
||
<option value="1">Bottom Up</option>
|
||
<option value="2">Top Down</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div ng-if="WorkFlowChanges()">
|
||
<div ng-show="SaveChangesDialog.SaveAction == 1 && SaveChangesDialog.ScenarioType == 1 && SaveChangesDialog.ProjectsWithSuperExpenditures.length > 0">
|
||
<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 SaveChangesDialog.ProjectsWithSuperExpenditures">{{project.ProjectName}}</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="alert alert-danger" ng-show="SaveChangesDialog.ShowValidationSummary">
|
||
<ul>
|
||
<li>
|
||
Current scenario contains overallocated Categories and you need to contact the Project Manager to increase the Projections to match your allocations.
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="form-group" ng-show="!SaveChangesDialog.ShowValidationSummary">
|
||
<div class="col-sm-9">
|
||
<table>
|
||
<tr class="row" ng-repeat="x in SaveChangesDialog.WorkFlowActions">
|
||
<td ng-hide="!x.HasChanges" class="col-sm-12">Set workflow status for Project: <b> {{ x.ProjectName }} </b></td>
|
||
<td ng-hide="!x.HasChanges" class="col-sm-12">
|
||
<div>
|
||
<select id="{{x.ScenarioId}}_WFCmdSelect" ng-options="cmd as cmd.command for cmd in x.Commands" ng-model="x.Selected" ng-change="updateWorkFlowOption(x.Selected)"></select>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@* <div ng-show="WorkFlowChanges()">*@
|
||
<div >
|
||
<div class="form-group">
|
||
<p>
|
||
The following projects have been modified. Please choose what we need to do with projections:
|
||
<br />
|
||
<i>(Projections of Bottom Up scenarios will be updated regardless of your choice)</i>
|
||
</p>
|
||
<div ng-repeat="prjItem in SaveChangesDialog.ChangedProjects track by $index" class="form-group">
|
||
<div class="row">
|
||
<label class="col-sm-5 control-label" for="ch_upd_prj_{{prjItem.ScenarioId}}">{{prjItem.Name}}</label>
|
||
<div class="col-sm-7">
|
||
<input type="checkbox" ng-switcher ng-model="prjItem.UpdateProjections" class="form-control" id="ch_upd_prj_{{prjItem.ScenarioId}}" name="ch_upd_prj_{{prjItem.ScenarioId}}"
|
||
ng-sw-on_state_content="Update Projections" ng-sw-off_state_content="Keep Current" ng-sw-width="135px"
|
||
ng-required="prjItem.Required" ng-click="saveScenarioForm_UpdateProjectionsChanged($index)" ng-disabled="prjItem.Disabled" />
|
||
<span class="field-validation-error" ng-show="prjItem.Invalid">
|
||
Update Projections for this project is required
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="alert alert-danger" ng-show="SaveChangesDialog.ShowValidationSummary">
|
||
<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>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-primary" ng-disabled="saveScenarioForm.$invalid" ng-click="saveChangesConfirmed(saveScenarioForm.$valid)">Ok</button>
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||
</div>
|
||
</div> <!-- / .modal-content -->
|
||
</div> <!-- / .modal-dialog -->
|
||
</form>
|
||
</div> <!-- / .modal -->
|
||
</div>
|