security: use more antiforgery tokens

This commit is contained in:
Gary Sharp
2025-07-25 12:32:44 +10:00
parent fd43d85778
commit 7deead494b
222 changed files with 12919 additions and 11728 deletions
@@ -1,11 +1,11 @@
@model Disco.Web.Areas.Config.Models.DeviceModel.CreateModel
@{
Authorization.RequireAll(Claims.Config.DeviceModel.CreateCustom, Claims.Config.DeviceModel.Configure);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Device Models", MVC.Config.DeviceModel.Index(null), "Create Custom");
}
@using (Html.BeginForm())
{
{
@Html.AntiForgeryToken()
<div class="form" style="width: 450px">
<table>
@@ -14,21 +14,23 @@
Name / Description:
</th>
<td>
@Html.TextBoxFor(model => model.Description)<br />@Html.ValidationMessageFor(model => model.Description)
@Html.TextBoxFor(model => model.Description)<br />@Html.ValidationMessageFor(model => model.Description)
</td>
</tr>
<tr>
<th>
Manufacturer:
</th>
<td>@Html.TextBoxFor(model => model.Manufacturer)<br />@Html.ValidationMessageFor(model => model.Manufacturer)
<td>
@Html.TextBoxFor(model => model.Manufacturer)<br />@Html.ValidationMessageFor(model => model.Manufacturer)
</td>
</tr>
<tr>
<th>
Model:
</th>
<td>@Html.TextBoxFor(model => model.ManufacturerModel)<br />@Html.ValidationMessageFor(model => model.ManufacturerModel)
<td>
@Html.TextBoxFor(model => model.ManufacturerModel)<br />@Html.ValidationMessageFor(model => model.ManufacturerModel)
</td>
</tr>
</table>
@@ -47,7 +47,7 @@ namespace Disco.Web.Areas.Config.Views.DeviceModel
#line 2 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Authorization.RequireAll(Claims.Config.DeviceModel.CreateCustom, Claims.Config.DeviceModel.Configure);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Device Models", MVC.Config.DeviceModel.Index(null), "Create Custom");
@@ -58,7 +58,7 @@ WriteLiteral("\r\n");
#line 7 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
using (Html.BeginForm())
{
{
#line default
@@ -86,11 +86,11 @@ WriteLiteral(" style=\"width: 450px\"");
WriteLiteral(">\r\n <table>\r\n <tr>\r\n <th>\r\n N" +
"ame / Description:\r\n </th>\r\n <td>\r\n");
WriteLiteral(" ");
WriteLiteral(" ");
#line 17 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.TextBoxFor(model => model.Description));
Write(Html.TextBoxFor(model => model.Description));
#line default
@@ -99,17 +99,19 @@ WriteLiteral("<br />");
#line 17 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.ValidationMessageFor(model => model.Description));
Write(Html.ValidationMessageFor(model => model.Description));
#line default
#line hidden
WriteLiteral("\r\n </td>\r\n </tr>\r\n <tr>\r\n <th" +
">\r\n Manufacturer:\r\n </th>\r\n <td" +
">");
">\r\n");
WriteLiteral(" ");
#line 24 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
#line 25 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.TextBoxFor(model => model.Manufacturer));
@@ -118,17 +120,19 @@ WriteLiteral("\r\n </td>\r\n </tr>\r\n <tr>
WriteLiteral("<br />");
#line 24 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
#line 25 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.ValidationMessageFor(model => model.Manufacturer));
#line default
#line hidden
WriteLiteral("\r\n </td>\r\n </tr>\r\n <tr>\r\n <th" +
">\r\n Model:\r\n </th>\r\n <td>");
">\r\n Model:\r\n </th>\r\n <td>\r\n");
WriteLiteral(" ");
#line 31 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
#line 33 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.TextBoxFor(model => model.ManufacturerModel));
@@ -137,7 +141,7 @@ WriteLiteral("\r\n </td>\r\n </tr>\r\n <tr>
WriteLiteral("<br />");
#line 31 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
#line 33 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
Write(Html.ValidationMessageFor(model => model.ManufacturerModel));
@@ -165,7 +169,7 @@ WriteLiteral(">\r\n $(function () {\r\n $(\'#Description\').fo
" });\r\n </script>\r\n");
#line 44 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
#line 46 "..\..\Areas\Config\Views\DeviceModel\Create.cshtml"
}
@@ -274,6 +274,7 @@
<hr />
using (Html.BeginForm(MVC.API.DeviceModel.Image(Model.DeviceModel.Id, true, null), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<input type="file" name="Image" id="Image" style="width: 220px;" />
<input class="button small" type="submit" value="Upload Image" />
}
@@ -290,7 +291,7 @@
{
<button id="DeviceModel_Decommission" class="button">Decommission All Devices</button>
<div id="DeviceModel_Decommission_Dialog" class="dialog" title="Model Device Decommission">
@using (Html.BeginForm(MVC.API.Device.DeviceModelDecommission(Model.DeviceModel.Id), FormMethod.Post))
@using (Html.BeginForm(MVC.API.Device.DeviceModelDecommission(Model.DeviceModel.Id)))
{
@Html.AntiForgeryToken()
<div class="clearfix" style="margin-bottom: 10px;">
@@ -347,7 +348,44 @@
}
@if (Model.CanDelete)
{
@Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete")
<button id="buttonDelete" type="button" class="button">Delete</button>
<div id="dialogConfirmDelete" class="dialog" title="Delete this Device Model?">
@using (Html.BeginForm(MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true)))
{
@Html.AntiForgeryToken()
}
<p>
<i class="fa fa-exclamation-triangle fa-lg warning"></i>
This item will be permanently deleted and cannot be recovered. Are you sure?
</p>
</div>
<script type="text/javascript">
$(function () {
let dialog = null;
$('#buttonDelete').on('click', function () {
if (!dialog) {
dialog = $("#dialogConfirmDelete").dialog({
resizable: false,
width: 300,
modal: true,
autoOpen: false,
buttons: {
"Delete": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
dialog.dialog('open');
});
});
</script>
}
@if (Model.DeviceCount > 0)
{
@@ -936,6 +936,20 @@ WriteLiteral(" <hr />\r\n");
#line 275 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
using (Html.BeginForm(MVC.API.DeviceModel.Image(Model.DeviceModel.Id, true, null), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#line default
#line hidden
#line 277 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 277 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
@@ -963,7 +977,7 @@ WriteLiteral(" value=\"Upload Image\"");
WriteLiteral(" />\r\n");
#line 279 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 280 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
}
@@ -973,7 +987,7 @@ WriteLiteral(" />\r\n");
WriteLiteral(" </td>\r\n </tr>\r\n </table>\r\n</div>\r\n<h2>Components</h2>\r\n");
#line 286 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 287 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.Partial(MVC.Config.DeviceModel.Views._DeviceComponentsTable, Model.DeviceComponentsModel));
@@ -982,7 +996,7 @@ Write(Html.Partial(MVC.Config.DeviceModel.Views._DeviceComponentsTable, Model.De
WriteLiteral("\r\n");
#line 287 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 288 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model));
@@ -995,13 +1009,13 @@ WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
#line 289 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 290 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 289 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 290 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.CanDecommission)
{
@@ -1027,28 +1041,28 @@ WriteLiteral(" title=\"Model Device Decommission\"");
WriteLiteral(">\r\n");
#line 293 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 294 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 293 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
using (Html.BeginForm(MVC.API.Device.DeviceModelDecommission(Model.DeviceModel.Id), FormMethod.Post))
#line 294 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
using (Html.BeginForm(MVC.API.Device.DeviceModelDecommission(Model.DeviceModel.Id)))
{
#line default
#line hidden
#line 295 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 296 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 295 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 296 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
@@ -1073,13 +1087,13 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n");
#line 301 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 302 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 301 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 302 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
foreach (DecommissionReasons decommissionReason in Enum.GetValues(typeof(DecommissionReasons)).Cast<DecommissionReasons>().OrderBy(r => r.ToString()))
{
@@ -1090,33 +1104,33 @@ WriteLiteral(" <li>\r\n
WriteLiteral(" type=\"radio\"");
WriteAttribute("id", Tuple.Create(" id=\"", 12649), Tuple.Create("\"", 12719)
, Tuple.Create(Tuple.Create("", 12654), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 12654), true)
WriteAttribute("id", Tuple.Create(" id=\"", 12682), Tuple.Create("\"", 12752)
, Tuple.Create(Tuple.Create("", 12687), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 12687), true)
#line 304 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 12693), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line 305 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 12726), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 12693), false)
, 12726), false)
);
WriteLiteral("\r\n name=\"decommissionReason\"");
WriteAttribute("value", Tuple.Create(" value=\"", 12786), Tuple.Create("\"", 12820)
WriteAttribute("value", Tuple.Create(" value=\"", 12819), Tuple.Create("\"", 12853)
#line 305 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 12794), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line 306 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 12827), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 12794), false)
, 12827), false)
);
WriteLiteral(" ");
#line 305 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 306 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty);
@@ -1124,21 +1138,21 @@ WriteLiteral(" ");
#line hidden
WriteLiteral(" />\r\n <label");
WriteAttribute("for", Tuple.Create(" for=\"", 12960), Tuple.Create("\"", 13031)
, Tuple.Create(Tuple.Create("", 12966), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 12966), true)
WriteAttribute("for", Tuple.Create(" for=\"", 12993), Tuple.Create("\"", 13064)
, Tuple.Create(Tuple.Create("", 12999), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 12999), true)
#line 306 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 13005), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line 307 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 13038), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 13005), false)
, 13038), false)
);
WriteLiteral(">");
#line 306 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 307 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(decommissionReason.ReasonMessage());
@@ -1147,7 +1161,7 @@ WriteLiteral(">");
WriteLiteral("</label>\r\n </li>\r\n");
#line 308 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 309 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
@@ -1166,7 +1180,7 @@ WriteLiteral(" />\r\n Unassign devices users\r\n
"\r\n </div>\r\n");
#line 316 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 317 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
@@ -1210,7 +1224,7 @@ WriteLiteral(@">
");
#line 347 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 348 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
@@ -1219,23 +1233,104 @@ WriteLiteral(@">
WriteLiteral(" ");
#line 348 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 349 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.CanDelete)
{
#line default
#line hidden
WriteLiteral(" <button");
WriteLiteral(" id=\"buttonDelete\"");
WriteLiteral(" type=\"button\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Delete</button>\r\n");
WriteLiteral(" <div");
WriteLiteral(" id=\"dialogConfirmDelete\"");
WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Delete this Device Model?\"");
WriteLiteral(">\r\n");
#line 353 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 350 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete"));
#line 353 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
using (Html.BeginForm(MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true)))
{
#line default
#line hidden
#line 355 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 350 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 355 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" <p>\r\n <i");
WriteLiteral(" class=\"fa fa-exclamation-triangle fa-lg warning\"");
WriteLiteral("></i>\r\n This item will be permanently deleted and cannot be recove" +
"red. Are you sure?\r\n </p>\r\n </div>\r\n");
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
let dialog = null;
$('#buttonDelete').on('click', function () {
if (!dialog) {
dialog = $(""#dialogConfirmDelete"").dialog({
resizable: false,
width: 300,
modal: true,
autoOpen: false,
buttons: {
""Delete"": function () {
$(this)
.dialog(""option"", ""buttons"", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog(""close"");
}
}
});
}
dialog.dialog('open');
});
});
</script>
");
#line 389 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
@@ -1244,7 +1339,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 352 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 390 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.DeviceCount > 0)
{
if (Authorization.Has(Claims.Device.Actions.Export))
@@ -1254,14 +1349,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 356 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 394 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Model, Model.DeviceModel.Id)));
#line default
#line hidden
#line 356 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 394 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0)
@@ -1271,14 +1366,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 360 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 398 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.ActionLinkButton(string.Format("View {0} Device{1}", Model.DeviceCount, (Model.DeviceCount != 1 ? "s" : null)), MVC.Search.Query(Model.DeviceModel.Id.ToString(), "DeviceModel")));
#line default
#line hidden
#line 360 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line 398 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
}
@@ -8,15 +8,19 @@
}
@if (canConfig)
{
<table id="deviceComponents" data-devicemodelid="@(Model.DeviceModelId.HasValue ? Model.DeviceModelId.Value.ToString() : string.Empty)">
<table id="deviceComponents" data-devicemodelid="@(Model.DeviceModelId.HasValue ? Model.DeviceModelId.Value.ToString() : string.Empty)" data-addurl="@Url.Action(MVC.API.DeviceModel.ComponentAdd(null, null, null))" data-updateurl="@Url.Action(MVC.API.DeviceModel.ComponentUpdate())" data-removeurl="@Url.Action(MVC.API.DeviceModel.ComponentRemove())" data-geturl="@Url.Action(MVC.API.DeviceModel.Component())" data-updatejobsubtypesurl="@Url.Action(MVC.API.DeviceModel.ComponentUpdateJobSubTypes())">
<tr>
<th>Description
<th>
Description
</th>
<th>Cost
<th>
Cost
</th>
<th>Job Types
<th>
Job Types
</th>
<th class="actions">&nbsp;
<th class="actions">
&nbsp;
</th>
</tr>
@foreach (var item in Model.DeviceComponents)
@@ -47,183 +51,179 @@
</table>
<script type="text/javascript">
$(function () {
var $deviceComponents = $('#deviceComponents');
const $deviceComponents = $('#deviceComponents');
$('#addDeviceComponent').click(function () {
var dc = $('<tr><td><input type="text" class="description" /></td><td><input type="text" class="cost" /></td><td><span class="fa-stack edit"><i class="fa fa-list-alt fa-stack-2x"></i><i class="fa fa-asterisk fa-stack-1x hidden"></i></span></td><td><i class="fa fa-times-circle remove"></i></td></tr>');
dc.find('input').focus(function () { $(this).select() })
const dc = $('<tr><td><input type="text" class="description" /></td><td><input type="text" class="cost" /></td><td><span class="fa-stack edit"><i class="fa fa-list-alt fa-stack-2x"></i><i class="fa fa-asterisk fa-stack-1x hidden"></i></span></td><td><i class="fa fa-times-circle remove"></i></td></tr>');
dc.insertBefore($deviceComponents.find('tr').last());
dc.find('input.description').focus();
return false;
});
$deviceComponents.on('change', 'input', updateComponent);
$deviceComponents.on('change', 'input', function () { updateComponent(this); });
$deviceComponents.on('focus', 'input', function () { $(this).select(); });
$deviceComponents.on('click', '.remove', removeComponent);
$deviceComponents.on('click', '.edit', editComponentJobTypes);
$deviceComponents.on('click', '.edit', function () { editComponentJobTypes(this); });
function removeComponentConfirmed(id, row) {
var data = { id: id };
$.ajax({
url: '@Url.Action(MVC.API.DeviceModel.ComponentRemove())',
dataType: 'json',
data: data,
success: function (d) {
if (d == 'OK') {
row.remove();
} else {
alert('Unable to remove component: ' + d);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to remove component: ' + textStatus);
async function removeComponentConfirmed(id, row) {
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
body.append('id', id);
try {
const response = await fetch($deviceComponents.attr('data-removeurl'), {
method: 'POST',
body: body
});
if (response.ok) {
row.remove();
} else {
alert('Unable to remove component: ' + response.statusText);
}
});
}
} catch (e) {
alert('Unable to remove component: ' + e);
}
}
function removeComponent() {
var componentRow = $(this).closest('tr');
var id = componentRow.attr('data-devicecomponentid');
const componentRow = $(this).closest('tr');
const id = componentRow.attr('data-devicecomponentid');
if (id) {
var dialog = $("#dialogConfirmRemove");
var buttons = dialog.dialog("option", "buttons");
const dialog = $("#dialogConfirmRemove");
const buttons = dialog.dialog("option", "buttons");
buttons['Remove'] = function () { removeComponentConfirmed(id, componentRow); $(this).dialog("close"); };
var buttons = dialog.dialog("option", "buttons", buttons);
dialog.dialog("option", "buttons", buttons);
dialog.dialog('open');
} else {
// New - Remove
componentRow.remove();
}
}
function updateComponent() {
var componentRow = $(this).closest('tr');
async function updateComponent(input) {
const componentRow = $(input).closest('tr');
componentRow.find('input').attr('disabled', true).addClass('updating');
var id = componentRow.attr('data-devicecomponentid');
const id = componentRow.attr('data-devicecomponentid');
if (id) {
// Update
var data = {
id: id,
Description: componentRow.find('input.description').val(),
Cost: componentRow.find('input.cost').val()
};
$.ajax({
url: '@Url.Action(MVC.API.DeviceModel.ComponentUpdate())',
dataType: 'json',
type: 'POST',
data: data,
success: function (d) {
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
body.append('id', id);
body.append('description', componentRow.find('input.description').val());
body.append('cost', componentRow.find('input.cost').val());
try {
const response = await fetch($deviceComponents.attr('data-updateurl'), {
method: 'POST',
body: body
});
if (response.ok) {
const result = await response.json();
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (d.Result == 'OK') {
componentRow.find('input.description').val(d.Component.Description);
componentRow.find('input.cost').val(d.Component.Cost);
} else {
alert('Unable to update component: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to update component: ' + textStatus);
componentRow.find('input.description').val(result.Description);
componentRow.find('input.cost').val(result.Cost);
} else {
alert('Unable to update component: ' + response.statusText);
}
});
} catch (e) {
alert('Unable to update component: ' + e);
}
} else {
// Add
id = componentRow.closest('table').attr('data-devicemodelid');
var data = {
id: id,
Description: componentRow.find('input.description').val(),
Cost: componentRow.find('input.cost').val()
};
$.ajax({
url: '@Url.Action(MVC.API.DeviceModel.ComponentAdd(null, null, null))',
dataType: 'json',
type: 'POST',
data: data,
success: function (d) {
const modelId = componentRow.closest('table').attr('data-devicemodelid');
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
body.append('id', modelId);
body.append('description', componentRow.find('input.description').val());
body.append('cost', componentRow.find('input.cost').val());
try {
const response = await fetch($deviceComponents.attr('data-addurl'), {
method: 'POST',
body: body
});
if (response.ok) {
const result = await response.json();
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (d.Result == 'OK') {
componentRow.attr('data-devicecomponentid', d.Component.Id);
componentRow.find('input.description').val(d.Component.Description);
componentRow.find('input.cost').val(d.Component.Cost);
} else {
alert('Unable to add component: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to add component: ' + textStatus);
componentRow.attr('data-devicecomponentid', result.Id);
componentRow.find('input.description').val(result.Description);
componentRow.find('input.cost').val(result.Cost);
} else {
alert('Unable to add component: ' + response.statusText);
}
});
} catch (e) {
alert('Unable to add component: ' + e);
}
}
}
function editComponentJobTypes() {
var edit$this = $(this);
var componentRow = edit$this.closest('tr');
var id = componentRow.attr('data-devicecomponentid');
async function editComponentJobTypes(input) {
const edit$this = $(input);
const componentRow = edit$this.closest('tr');
const id = componentRow.attr('data-devicecomponentid');
if (id) {
var data = {
id: id
};
$.ajax({
url: '@Url.Action(MVC.API.DeviceModel.Component())',
dataType: 'json',
data: data,
success: function (d) {
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (d.Result == 'OK') {
$dialogUpdateJobTypes = $('#dialogUpdateJobTypes');
$dialogUpdateJobTypes.find('input:checked').each(function () { $(this).prop('checked', false) });
for (var i = 0; i < d.Component.JobSubTypes.length; i++) {
var sjt = d.Component.JobSubTypes[i];
$dialogUpdateJobTypes.find('#SubTypes_' + sjt).prop('checked', true);
}
$('#CheckboxBulkSelect_dialogUpdateJobTypes').checkboxBulkSelect('update');
var buttons = $dialogUpdateJobTypes.dialog("option", "buttons");
buttons['Save'] = function () {
$dialogUpdateJobTypes.dialog("disable");
var selectedSJTs = [];
$dialogUpdateJobTypes.find('input:checked').each(function () { selectedSJTs.push($(this).val()) });
try {
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
body.append('id', id);
const getResponse = await fetch($deviceComponents.attr('data-geturl'), {
method: 'POST',
body: body
})
var data = {
id: id,
JobSubTypes: selectedSJTs
};
$.ajax({
url: '@Url.Action(MVC.API.DeviceModel.ComponentUpdateJobSubTypes())',
dataType: 'json',
type: 'POST',
traditional: true,
data: data,
success: function (d) {
if (d.Result == 'OK') {
if (d.Component.JobSubTypes.length > 0) {
edit$this.find('.fa-asterisk').removeClass('hidden');
} else {
edit$this.find('.fa-asterisk').addClass('hidden');
}
$dialogUpdateJobTypes.dialog("enable");
$dialogUpdateJobTypes.dialog("close");
} else {
alert('Unable to update component sub types: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to update component sub types: ' + textStatus);
}
});
};
var buttons = $dialogUpdateJobTypes.dialog("option", "buttons", buttons);
$dialogUpdateJobTypes.dialog('open');
} else {
alert('Unable to load component: ' + d.Result);
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (getResponse.ok) {
const component = await getResponse.json();
$dialogUpdateJobTypes = $('#dialogUpdateJobTypes');
$dialogUpdateJobTypes.find('input:checked').each(function () { $(this).prop('checked', false) });
for (var i = 0; i < component.JobSubTypes.length; i++) {
var sjt = component.JobSubTypes[i];
$dialogUpdateJobTypes.find('#SubTypes_' + sjt).prop('checked', true);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to load component: ' + textStatus);
}
});
}
$('#CheckboxBulkSelect_dialogUpdateJobTypes').checkboxBulkSelect('update');
const buttons = $dialogUpdateJobTypes.dialog("option", "buttons");
buttons['Save'] = function () {
async function saveAsync() {
const body = new FormData();
let jobSubTypeCount = 0;
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
body.append('id', id);
$dialogUpdateJobTypes.find('input:checked').each(function () { body.append('jobSubTypes', $(this).val()); jobSubTypeCount++; });
try {
const updateResponse = await fetch($deviceComponents.attr('data-updatejobsubtypesurl'), {
method: 'POST',
body: body
})
if (updateResponse.ok) {
if (jobSubTypeCount > 0) {
edit$this.find('.fa-asterisk').removeClass('hidden');
} else {
edit$this.find('.fa-asterisk').addClass('hidden');
}
$dialogUpdateJobTypes.dialog("close");
} else {
alert('Unable to update component sub types: ' + updateResponse.statusText);
}
} catch (e) {
alert('Unable to update component sub types: ' + e);
}
}
saveAsync();
};
$dialogUpdateJobTypes.dialog("option", "buttons", buttons);
$dialogUpdateJobTypes.dialog('open');
} else {
alert('Unable to load component: ' + getResponse.statusText);
}
} catch (e) {
alert('Unable to load component: ' + e);
}
}
}
$("#dialogConfirmRemove").dialog({
@@ -278,11 +278,14 @@ else
{
<table id="deviceComponents" data-devicemodelid="@(Model.DeviceModelId.HasValue ? Model.DeviceModelId.Value.ToString() : string.Empty)">
<tr>
<th>Description
<th>
Description
</th>
<th>Cost
<th>
Cost
</th>
<th>Job Types
<th>
Job Types
</th>
</tr>
@foreach (var item in Model.DeviceComponents)
@@ -80,22 +80,77 @@ WriteLiteral(" data-devicemodelid=\"");
#line hidden
WriteLiteral("\"");
WriteLiteral(">\r\n <tr>\r\n <th>Description\r\n </th>\r\n <th>" +
"Cost\r\n </th>\r\n <th>Job Types\r\n </th>\r\n " +
" <th");
WriteLiteral(" data-addurl=\"");
#line 11 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentAdd(null, null, null)));
#line default
#line hidden
WriteLiteral("\"");
WriteLiteral(" data-updateurl=\"");
#line 11 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentUpdate()));
#line default
#line hidden
WriteLiteral("\"");
WriteLiteral(" data-removeurl=\"");
#line 11 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentRemove()));
#line default
#line hidden
WriteLiteral("\"");
WriteLiteral(" data-geturl=\"");
#line 11 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.Component()));
#line default
#line hidden
WriteLiteral("\"");
WriteLiteral(" data-updatejobsubtypesurl=\"");
#line 11 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentUpdateJobSubTypes()));
#line default
#line hidden
WriteLiteral("\"");
WriteLiteral(">\r\n <tr>\r\n <th>\r\n Description\r\n </th>" +
"\r\n <th>\r\n Cost\r\n </th>\r\n <th>\r\n " +
" Job Types\r\n </th>\r\n <th");
WriteLiteral(" class=\"actions\"");
WriteLiteral(">&nbsp;\r\n </th>\r\n </tr>\r\n");
WriteLiteral(">\r\n &nbsp;\r\n </th>\r\n </tr>\r\n");
#line 22 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 26 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line default
#line hidden
#line 22 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 26 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
foreach (var item in Model.DeviceComponents)
{
@@ -107,7 +162,7 @@ WriteLiteral(" <tr");
WriteLiteral(" data-devicecomponentid=\"");
#line 24 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 28 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(item.Id);
@@ -121,14 +176,14 @@ WriteLiteral(" type=\"text\"");
WriteLiteral(" class=\"description\"");
WriteAttribute("value", Tuple.Create(" value=\"", 883), Tuple.Create("\"", 908)
WriteAttribute("value", Tuple.Create(" value=\"", 1318), Tuple.Create("\"", 1343)
#line 26 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 891), Tuple.Create<System.Object, System.Int32>(item.Description
#line 30 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 1326), Tuple.Create<System.Object, System.Int32>(item.Description
#line default
#line hidden
, 891), false)
, 1326), false)
);
WriteLiteral(" />\r\n </td>\r\n <td>\r\n <input");
@@ -137,14 +192,14 @@ WriteLiteral(" type=\"text\"");
WriteLiteral(" class=\"cost\"");
WriteAttribute("value", Tuple.Create(" value=\"", 1010), Tuple.Create("\"", 1042)
WriteAttribute("value", Tuple.Create(" value=\"", 1445), Tuple.Create("\"", 1477)
#line 29 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 1018), Tuple.Create<System.Object, System.Int32>(item.Cost.ToString("C")
#line 33 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 1453), Tuple.Create<System.Object, System.Int32>(item.Cost.ToString("C")
#line default
#line hidden
, 1018), false)
, 1453), false)
);
WriteLiteral(" />\r\n </td>\r\n <td>\r\n <span");
@@ -157,17 +212,17 @@ WriteLiteral(" class=\"fa fa-list-alt fa-stack-2x\"");
WriteLiteral("></i>\r\n <i");
WriteAttribute("class", Tuple.Create(" class=\"", 1237), Tuple.Create("\"", 1328)
, Tuple.Create(Tuple.Create("", 1245), Tuple.Create("fa", 1245), true)
, Tuple.Create(Tuple.Create(" ", 1247), Tuple.Create("fa-asterisk", 1248), true)
, Tuple.Create(Tuple.Create(" ", 1259), Tuple.Create("fa-stack-1x", 1260), true)
WriteAttribute("class", Tuple.Create(" class=\"", 1672), Tuple.Create("\"", 1763)
, Tuple.Create(Tuple.Create("", 1680), Tuple.Create("fa", 1680), true)
, Tuple.Create(Tuple.Create(" ", 1682), Tuple.Create("fa-asterisk", 1683), true)
, Tuple.Create(Tuple.Create(" ", 1694), Tuple.Create("fa-stack-1x", 1695), true)
#line 34 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 1271), Tuple.Create<System.Object, System.Int32>(item.JobSubTypes.Count == 0 ? " hidden" : string.Empty
#line 38 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
, Tuple.Create(Tuple.Create("", 1706), Tuple.Create<System.Object, System.Int32>(item.JobSubTypes.Count == 0 ? " hidden" : string.Empty
#line default
#line hidden
, 1271), false)
, 1706), false)
);
WriteLiteral("></i>\r\n </span>\r\n </td>\r\n <td>\r\n" +
@@ -178,7 +233,7 @@ WriteLiteral(" class=\"fa fa-times-circle remove\"");
WriteLiteral("></i>\r\n </td>\r\n </tr>\r\n");
#line 41 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 45 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
@@ -200,213 +255,142 @@ WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
var $deviceComponents = $('#deviceComponents');
$('#addDeviceComponent').click(function () {
var dc = $('<tr><td><input type=""text"" class=""description"" /></td><td><input type=""text"" class=""cost"" /></td><td><span class=""fa-stack edit""><i class=""fa fa-list-alt fa-stack-2x""></i><i class=""fa fa-asterisk fa-stack-1x hidden""></i></span></td><td><i class=""fa fa-times-circle remove""></i></td></tr>');
dc.find('input').focus(function () { $(this).select() })
dc.insertBefore($deviceComponents.find('tr').last());
dc.find('input.description').focus();
return false;
});
$deviceComponents.on('change', 'input', updateComponent);
$deviceComponents.on('focus', 'input', function () { $(this).select(); });
$deviceComponents.on('click', '.remove', removeComponent);
$deviceComponents.on('click', '.edit', editComponentJobTypes);
function removeComponentConfirmed(id, row) {
var data = { id: id };
$.ajax({
url: '");
#line 69 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentRemove()));
#line default
#line hidden
WriteLiteral("\',\r\n dataType: \'json\',\r\n data: data,\r\n " +
" success: function (d) {\r\n if (d == \'OK\') {" +
"\r\n row.remove();\r\n } else {\r\n " +
" alert(\'Unable to remove component: \' + d);\r\n " +
" }\r\n },\r\n error: function (j" +
"qXHR, textStatus, errorThrown) {\r\n alert(\'Unable to remov" +
"e component: \' + textStatus);\r\n }\r\n });\r\n " +
" }\r\n function removeComponent() {\r\n var componentRow" +
" = $(this).closest(\'tr\');\r\n var id = componentRow.attr(\'data-devi" +
"cecomponentid\');\r\n if (id) {\r\n var dialog = $(" +
"\"#dialogConfirmRemove\");\r\n var buttons = dialog.dialog(\"optio" +
"n\", \"buttons\");\r\n buttons[\'Remove\'] = function () { removeCom" +
"ponentConfirmed(id, componentRow); $(this).dialog(\"close\"); };\r\n " +
" var buttons = dialog.dialog(\"option\", \"buttons\", buttons);\r\n " +
" dialog.dialog(\'open\');\r\n } else {\r\n // New" +
" - Remove\r\n componentRow.remove();\r\n }\r\n " +
" }\r\n function updateComponent() {\r\n var component" +
"Row = $(this).closest(\'tr\');\r\n componentRow.find(\'input\').attr(\'d" +
"isabled\', true).addClass(\'updating\');\r\n\r\n var id = componentRow.a" +
"ttr(\'data-devicecomponentid\');\r\n if (id) {\r\n /" +
"/ Update\r\n var data = {\r\n id: id,\r\n " +
" Description: componentRow.find(\'input.description\').val(),\r" +
"\n Cost: componentRow.find(\'input.cost\').val()\r\n " +
" };\r\n $.ajax({\r\n url: \'");
#line 111 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentUpdate()));
#line default
#line hidden
WriteLiteral(@"',
dataType: 'json',
type: 'POST',
data: data,
success: function (d) {
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (d.Result == 'OK') {
componentRow.find('input.description').val(d.Component.Description);
componentRow.find('input.cost').val(d.Component.Cost);
} else {
alert('Unable to update component: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to update component: ' + textStatus);
}
});
} else {
// Add
id = componentRow.closest('table').attr('data-devicemodelid');
var data = {
id: id,
Description: componentRow.find('input.description').val(),
Cost: componentRow.find('input.cost').val()
};
$.ajax({
url: '");
#line 137 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentAdd(null, null, null)));
#line default
#line hidden
WriteLiteral(@"',
dataType: 'json',
type: 'POST',
data: data,
success: function (d) {
componentRow.find('input').attr('disabled', false).removeClass('updating');
if (d.Result == 'OK') {
componentRow.attr('data-devicecomponentid', d.Component.Id);
componentRow.find('input.description').val(d.Component.Description);
componentRow.find('input.cost').val(d.Component.Cost);
} else {
alert('Unable to add component: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to add component: ' + textStatus);
}
});
}
}
function editComponentJobTypes() {
var edit$this = $(this);
var componentRow = edit$this.closest('tr');
var id = componentRow.attr('data-devicecomponentid');
if (id) {
var data = {
id: id
};
$.ajax({
url: '");
#line 168 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.Component()));
#line default
#line hidden
WriteLiteral("\',\r\n dataType: \'json\',\r\n data: data" +
",\r\n success: function (d) {\r\n " +
"componentRow.find(\'input\').attr(\'disabled\', false).removeClass(\'updating\');\r\n " +
" if (d.Result == \'OK\') {\r\n " +
" $dialogUpdateJobTypes = $(\'#dialogUpdateJobTypes\');\r\n " +
" $dialogUpdateJobTypes.find(\'input:checked\').each(function () { $(this).pr" +
"op(\'checked\', false) });\r\n for (var i = 0; i < d." +
"Component.JobSubTypes.length; i++) {\r\n var sj" +
"t = d.Component.JobSubTypes[i];\r\n $dialogUpda" +
"teJobTypes.find(\'#SubTypes_\' + sjt).prop(\'checked\', true);\r\n " +
" }\r\n $(\'#CheckboxBulkSelect_dialogUpda" +
"teJobTypes\').checkboxBulkSelect(\'update\');\r\n var " +
"buttons = $dialogUpdateJobTypes.dialog(\"option\", \"buttons\");\r\n " +
" buttons[\'Save\'] = function () {\r\n " +
" $dialogUpdateJobTypes.dialog(\"disable\");\r\n " +
" var selectedSJTs = [];\r\n $dialogUpdateJobTyp" +
"es.find(\'input:checked\').each(function () { selectedSJTs.push($(this).val()) });" +
"\r\n\r\n var data = {\r\n " +
" id: id,\r\n JobSubTypes: sele" +
"ctedSJTs\r\n };\r\n " +
" $.ajax({\r\n url: \'");
#line 192 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(Url.Action(MVC.API.DeviceModel.ComponentUpdateJobSubTypes()));
#line default
#line hidden
WriteLiteral("\',\r\n dataType: \'json\',\r\n " +
" type: \'POST\',\r\n tra" +
"ditional: true,\r\n data: data,\r\n " +
" success: function (d) {\r\n " +
" if (d.Result == \'OK\') {\r\n " +
" if (d.Component.JobSubTypes.length > 0) {\r\n " +
" edit$this.find(\'.fa-asterisk\').removeClass(\'hidden\');" +
"\r\n } else {\r\n " +
" edit$this.find(\'.fa-asterisk\').addClass(\'hidden\'" +
");\r\n }\r\n " +
" $dialogUpdateJobTypes.dialog(\"enable\");\r\n " +
" $dialogUpdateJobTypes.dialog(\"close\");\r\n " +
" } else {\r\n " +
" alert(\'Unable to update component sub types: \' + d.Result);\r\n " +
" }\r\n " +
" },\r\n error: function (jqXHR, textStatus" +
", errorThrown) {\r\n alert(\'Unable to u" +
"pdate component sub types: \' + textStatus);\r\n " +
" }\r\n });\r\n " +
" };\r\n var buttons = $dialogUpdateJobTypes.dialog(" +
"\"option\", \"buttons\", buttons);\r\n $dialogUpdateJob" +
"Types.dialog(\'open\');\r\n } else {\r\n " +
" alert(\'Unable to load component: \' + d.Result);\r\n " +
" }\r\n },\r\n error: function" +
" (jqXHR, textStatus, errorThrown) {\r\n alert(\'Unable t" +
"o load component: \' + textStatus);\r\n }\r\n " +
" });\r\n }\r\n\r\n }\r\n\r\n $(\"#dialogConfirmRemov" +
"e\").dialog({\r\n resizable: false,\r\n height: 140,\r\n " +
" modal: true,\r\n autoOpen: false,\r\n b" +
"uttons: {\r\n \"Remove\": function () {\r\n " +
"$(this).dialog(\"close\");\r\n },\r\n Cancel: fu" +
"nction () {\r\n $(this).dialog(\"close\");\r\n " +
" }\r\n }\r\n });\r\n\r\n $(\'#dialogUpdateJobTypes" +
"\').dialog({\r\n resizable: false,\r\n modal: true,\r\n " +
" autoOpen: false,\r\n width: 550,\r\n but" +
"tons: {\r\n \"Save\": function () {\r\n $(th" +
"is).dialog(\"close\");\r\n },\r\n Cancel: functi" +
"on () {\r\n $(this).dialog(\"close\");\r\n }" +
"\r\n }\r\n });\r\n\r\n $(\'#CheckboxBulkSelect_dialo" +
"gUpdateJobTypes\').checkboxBulkSelect({ parentSelector: \'div\' });\r\n });\r\n " +
" </script>\r\n");
WriteLiteral(">\r\n $(function () {\r\n const $deviceComponents = $(\'#deviceCompo" +
"nents\');\r\n\r\n $(\'#addDeviceComponent\').click(function () {\r\n " +
" const dc = $(\'<tr><td><input type=\"text\" class=\"description\" /></td><td><i" +
"nput type=\"text\" class=\"cost\" /></td><td><span class=\"fa-stack edit\"><i class=\"f" +
"a fa-list-alt fa-stack-2x\"></i><i class=\"fa fa-asterisk fa-stack-1x hidden\"></i>" +
"</span></td><td><i class=\"fa fa-times-circle remove\"></i></td></tr>\');\r\n " +
" dc.insertBefore($deviceComponents.find(\'tr\').last());\r\n d" +
"c.find(\'input.description\').focus();\r\n return false;\r\n " +
" });\r\n\r\n $deviceComponents.on(\'change\', \'input\', function () { update" +
"Component(this); });\r\n $deviceComponents.on(\'focus\', \'input\', functio" +
"n () { $(this).select(); });\r\n\r\n $deviceComponents.on(\'click\', \'.remo" +
"ve\', removeComponent);\r\n $deviceComponents.on(\'click\', \'.edit\', funct" +
"ion () { editComponentJobTypes(this); });\r\n\r\n async function removeCo" +
"mponentConfirmed(id, row) {\r\n const body = new FormData();\r\n " +
" body.append(\'__RequestVerificationToken\', document.body.dataset.antif" +
"orgery);\r\n body.append(\'id\', id);\r\n\r\n try {\r\n " +
" const response = await fetch($deviceComponents.attr(\'data-removeu" +
"rl\'), {\r\n method: \'POST\',\r\n body: " +
"body\r\n });\r\n\r\n if (response.ok) {\r\n " +
" row.remove();\r\n } else {\r\n " +
" alert(\'Unable to remove component: \' + response.statusText);\r\n " +
" }\r\n } catch (e) {\r\n alert(\'Unable to r" +
"emove component: \' + e);\r\n }\r\n }\r\n function" +
" removeComponent() {\r\n const componentRow = $(this).closest(\'tr\')" +
";\r\n const id = componentRow.attr(\'data-devicecomponentid\');\r\n " +
" if (id) {\r\n const dialog = $(\"#dialogConfirmRemov" +
"e\");\r\n const buttons = dialog.dialog(\"option\", \"buttons\");\r\n " +
" buttons[\'Remove\'] = function () { removeComponentConfirmed(id" +
", componentRow); $(this).dialog(\"close\"); };\r\n dialog.dialog(" +
"\"option\", \"buttons\", buttons);\r\n dialog.dialog(\'open\');\r\n " +
" } else {\r\n // New - Remove\r\n c" +
"omponentRow.remove();\r\n }\r\n }\r\n async funct" +
"ion updateComponent(input) {\r\n const componentRow = $(input).clos" +
"est(\'tr\');\r\n componentRow.find(\'input\').attr(\'disabled\', true).ad" +
"dClass(\'updating\');\r\n\r\n const id = componentRow.attr(\'data-device" +
"componentid\');\r\n if (id) {\r\n // Update\r\n " +
" const body = new FormData();\r\n body.append(\'__R" +
"equestVerificationToken\', document.body.dataset.antiforgery);\r\n " +
" body.append(\'id\', id);\r\n body.append(\'description\', compon" +
"entRow.find(\'input.description\').val());\r\n body.append(\'cost\'" +
", componentRow.find(\'input.cost\').val());\r\n\r\n try {\r\n " +
" const response = await fetch($deviceComponents.attr(\'data-update" +
"url\'), {\r\n method: \'POST\',\r\n " +
" body: body\r\n });\r\n\r\n if (respon" +
"se.ok) {\r\n const result = await response.json();\r\n " +
" componentRow.find(\'input\').attr(\'disabled\', false).remo" +
"veClass(\'updating\');\r\n componentRow.find(\'input.descr" +
"iption\').val(result.Description);\r\n componentRow.find" +
"(\'input.cost\').val(result.Cost);\r\n } else {\r\n " +
" alert(\'Unable to update component: \' + response.statusText);\r\n " +
" }\r\n } catch (e) {\r\n " +
" alert(\'Unable to update component: \' + e);\r\n }\r\n " +
" } else {\r\n // Add\r\n const modelId =" +
" componentRow.closest(\'table\').attr(\'data-devicemodelid\');\r\n " +
"const body = new FormData();\r\n body.append(\'__RequestVerifica" +
"tionToken\', document.body.dataset.antiforgery);\r\n body.append" +
"(\'id\', modelId);\r\n body.append(\'description\', componentRow.fi" +
"nd(\'input.description\').val());\r\n body.append(\'cost\', compone" +
"ntRow.find(\'input.cost\').val());\r\n\r\n try {\r\n " +
" const response = await fetch($deviceComponents.attr(\'data-addurl\'), {\r\n " +
" method: \'POST\',\r\n body: bod" +
"y\r\n });\r\n\r\n if (response.ok) {\r\n " +
" const result = await response.json();\r\n " +
" componentRow.find(\'input\').attr(\'disabled\', false).removeClass(\'upd" +
"ating\');\r\n componentRow.attr(\'data-devicecomponentid\'" +
", result.Id);\r\n componentRow.find(\'input.description\'" +
").val(result.Description);\r\n componentRow.find(\'input" +
".cost\').val(result.Cost);\r\n } else {\r\n " +
" alert(\'Unable to add component: \' + response.statusText);\r\n " +
" }\r\n } catch (e) {\r\n alert(" +
"\'Unable to add component: \' + e);\r\n }\r\n }\r\n " +
" }\r\n async function editComponentJobTypes(input) {\r\n " +
" const edit$this = $(input);\r\n const componentRow = edit$th" +
"is.closest(\'tr\');\r\n const id = componentRow.attr(\'data-devicecomp" +
"onentid\');\r\n\r\n if (id) {\r\n try {\r\n " +
" const body = new FormData();\r\n body.append(\'_" +
"_RequestVerificationToken\', document.body.dataset.antiforgery);\r\n " +
" body.append(\'id\', id);\r\n const getResponse = awa" +
"it fetch($deviceComponents.attr(\'data-geturl\'), {\r\n m" +
"ethod: \'POST\',\r\n body: body\r\n " +
"})\r\n\r\n componentRow.find(\'input\').attr(\'disabled\', false)" +
".removeClass(\'updating\');\r\n if (getResponse.ok) {\r\n " +
" const component = await getResponse.json();\r\n " +
" $dialogUpdateJobTypes = $(\'#dialogUpdateJobTypes\');\r\n " +
" $dialogUpdateJobTypes.find(\'input:checked\').each(function () { $" +
"(this).prop(\'checked\', false) });\r\n for (var i = 0; i" +
" < component.JobSubTypes.length; i++) {\r\n var sjt" +
" = component.JobSubTypes[i];\r\n $dialogUpdateJobTy" +
"pes.find(\'#SubTypes_\' + sjt).prop(\'checked\', true);\r\n " +
" }\r\n $(\'#CheckboxBulkSelect_dialogUpdateJobTypes\').ch" +
"eckboxBulkSelect(\'update\');\r\n const buttons = $dialog" +
"UpdateJobTypes.dialog(\"option\", \"buttons\");\r\n buttons" +
"[\'Save\'] = function () {\r\n async function saveAsy" +
"nc() {\r\n const body = new FormData();\r\n " +
" let jobSubTypeCount = 0;\r\n " +
" body.append(\'__RequestVerificationToken\', document.body.dataset.anti" +
"forgery);\r\n body.append(\'id\', id);\r\n " +
" $dialogUpdateJobTypes.find(\'input:checked\').each(func" +
"tion () { body.append(\'jobSubTypes\', $(this).val()); jobSubTypeCount++; });\r\n\r\n " +
" try {\r\n " +
" const updateResponse = await fetch($deviceComponents.attr(\'data-updatejobsubty" +
"pesurl\'), {\r\n method: \'POST\',\r\n " +
" body: body\r\n " +
" })\r\n\r\n if (updateResponse.ok) {" +
"\r\n if (jobSubTypeCount > 0) {\r\n " +
" edit$this.find(\'.fa-asterisk\').removeC" +
"lass(\'hidden\');\r\n } else {\r\n " +
" edit$this.find(\'.fa-asterisk\').addClass(\'" +
"hidden\');\r\n }\r\n " +
" $dialogUpdateJobTypes.dialog(\"close\");\r\n " +
" } else {\r\n aler" +
"t(\'Unable to update component sub types: \' + updateResponse.statusText);\r\n " +
" }\r\n } catch" +
" (e) {\r\n alert(\'Unable to update componen" +
"t sub types: \' + e);\r\n }\r\n " +
" }\r\n saveAsync();\r\n " +
" };\r\n $dialogUpdateJobTypes.dialog(\"option\"," +
" \"buttons\", buttons);\r\n $dialogUpdateJobTypes.dialog(" +
"\'open\');\r\n } else {\r\n alert(\'U" +
"nable to load component: \' + getResponse.statusText);\r\n }" +
"\r\n } catch (e) {\r\n alert(\'Unable to lo" +
"ad component: \' + e);\r\n }\r\n }\r\n }\r\n" +
"\r\n $(\"#dialogConfirmRemove\").dialog({\r\n resizable: fal" +
"se,\r\n height: 140,\r\n modal: true,\r\n " +
" autoOpen: false,\r\n buttons: {\r\n \"Remove\": fun" +
"ction () {\r\n $(this).dialog(\"close\");\r\n " +
" },\r\n Cancel: function () {\r\n $(this)" +
".dialog(\"close\");\r\n }\r\n }\r\n });\r\n\r\n" +
" $(\'#dialogUpdateJobTypes\').dialog({\r\n resizable: fals" +
"e,\r\n modal: true,\r\n autoOpen: false,\r\n " +
" width: 550,\r\n buttons: {\r\n \"Save\": functio" +
"n () {\r\n $(this).dialog(\"close\");\r\n }," +
"\r\n Cancel: function () {\r\n $(this).dia" +
"log(\"close\");\r\n }\r\n }\r\n });\r\n\r\n " +
" $(\'#CheckboxBulkSelect_dialogUpdateJobTypes\').checkboxBulkSelect({ paren" +
"tSelector: \'div\' });\r\n });\r\n </script>\r\n");
WriteLiteral(" <div");
@@ -470,18 +454,18 @@ WriteLiteral(" data-devicemodelid=\"");
#line hidden
WriteLiteral("\"");
WriteLiteral(">\r\n <tr>\r\n <th>Description\r\n </th>\r\n <th>" +
"Cost\r\n </th>\r\n <th>Job Types\r\n </th>\r\n <" +
"/tr>\r\n");
WriteLiteral(">\r\n <tr>\r\n <th>\r\n Description\r\n </th>" +
"\r\n <th>\r\n Cost\r\n </th>\r\n <th>\r\n " +
" Job Types\r\n </th>\r\n </tr>\r\n");
#line 288 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 291 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line default
#line hidden
#line 288 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 291 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
foreach (var item in Model.DeviceComponents)
{
@@ -493,7 +477,7 @@ WriteLiteral(" <tr");
WriteLiteral(" data-devicecomponentid=\"");
#line 290 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 293 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(item.Id);
@@ -506,7 +490,7 @@ WriteLiteral(">\r\n <td>\r\n");
WriteLiteral(" ");
#line 292 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 295 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(item.Description);
@@ -517,7 +501,7 @@ WriteLiteral("\r\n </td>\r\n <td>\r\n");
WriteLiteral(" ");
#line 295 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 298 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(item.Cost.ToString("C"));
@@ -526,13 +510,13 @@ WriteLiteral(" ");
WriteLiteral("\r\n </td>\r\n <td>\r\n");
#line 298 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 301 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line default
#line hidden
#line 298 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 301 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
if (item.JobSubTypes.Count > 0)
{
@@ -542,13 +526,13 @@ WriteLiteral("\r\n </td>\r\n <td>\r\n");
WriteLiteral(" <ul>\r\n");
#line 301 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 304 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line default
#line hidden
#line 301 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 304 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
foreach (var jst in item.JobSubTypes)
{
@@ -558,7 +542,7 @@ WriteLiteral(" <ul>\r\n");
WriteLiteral(" <li>");
#line 303 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 306 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
Write(jst.Description);
@@ -567,7 +551,7 @@ WriteLiteral(" <li>");
WriteLiteral("</li>\r\n");
#line 304 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 307 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
@@ -576,7 +560,7 @@ WriteLiteral("</li>\r\n");
WriteLiteral(" </ul>\r\n");
#line 306 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 309 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
else
{
@@ -591,7 +575,7 @@ WriteLiteral(" class=\"smallMessage\"");
WriteLiteral(">&lt;None Specified&gt;</span>\r\n");
#line 310 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 313 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
@@ -600,7 +584,7 @@ WriteLiteral(">&lt;None Specified&gt;</span>\r\n");
WriteLiteral(" </td>\r\n </tr>\r\n");
#line 313 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 316 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
@@ -609,7 +593,7 @@ WriteLiteral(" </td>\r\n </tr>\r\n");
WriteLiteral(" </table>\r\n");
#line 315 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
#line 318 "..\..\Areas\Config\Views\DeviceModel\_DeviceComponentsTable.cshtml"
}
#line default