feature: device model/profile decommissioning

This commit is contained in:
Gary Sharp
2025-07-05 13:55:44 +10:00
parent 583552ffdd
commit 6e99b4503b
17 changed files with 714 additions and 23 deletions
@@ -12,5 +12,6 @@ namespace Disco.Models.UI.Config.DeviceModel
int DeviceDecommissionedCount { get; set; } int DeviceDecommissionedCount { get; set; }
bool CanDelete { get; set; } bool CanDelete { get; set; }
bool CanDecommission { get; set; }
} }
} }
@@ -17,5 +17,6 @@ namespace Disco.Models.UI.Config.DeviceProfile
int DeviceDecommissionedCount { get; set; } int DeviceDecommissionedCount { get; set; }
bool CanDelete { get; set; } bool CanDelete { get; set; }
bool CanDecommission { get; set; }
} }
} }
@@ -48,12 +48,5 @@ namespace Disco.Services
return true; return true;
} }
public static void Decommission(this DeviceBatch db, DiscoDataContext database, DecommissionReasons Reason, bool unassignUsers)
{
if (!db.CanDecommission(database))
throw new InvalidOperationException("Decommission of Device Batch is Denied");
}
} }
} }
@@ -48,6 +48,17 @@ namespace Disco.Services
Database.DeviceModels.Remove(dm); Database.DeviceModels.Remove(dm);
} }
public static bool CanDecommission(this DeviceModel dm, DiscoDataContext database)
{
if (!UserService.CurrentAuthorization.Has(Claims.Device.Actions.Import))
return false;
if (!database.Devices.Any(d => d.DeviceModelId == dm.Id && d.DecommissionedDate == null))
return false;
return true;
}
public static Tuple<DeviceModel, bool> GetOrCreateDeviceModel(this DbSet<DeviceModel> DeviceModelsSet, string Manufacturer, string Model, string ModelType) public static Tuple<DeviceModel, bool> GetOrCreateDeviceModel(this DbSet<DeviceModel> DeviceModelsSet, string Manufacturer, string Model, string ModelType)
{ {
if (string.IsNullOrWhiteSpace(Manufacturer)) if (string.IsNullOrWhiteSpace(Manufacturer))
@@ -71,6 +71,17 @@ namespace Disco.Services
Database.DeviceProfiles.Remove(dp); Database.DeviceProfiles.Remove(dp);
} }
public static bool CanDecommission(this DeviceProfile dp, DiscoDataContext database)
{
if (!UserService.CurrentAuthorization.Has(Claims.Device.Actions.Import))
return false;
if (!database.Devices.Any(d => d.DeviceProfileId == dp.Id && d.DecommissionedDate == null))
return false;
return true;
}
public static IEnumerable<PluginFeatureManifest> GetCertificateProviders(this DeviceProfile dp) public static IEnumerable<PluginFeatureManifest> GetCertificateProviders(this DeviceProfile dp)
{ {
if (!string.IsNullOrEmpty(dp.CertificateProviders)) if (!string.IsNullOrEmpty(dp.CertificateProviders))
@@ -93,6 +93,26 @@ namespace Disco.Services.Devices.Importing
return new DeviceDecommissionImportContext($"Batch: {deviceBatch.Name} ({deviceBatch.Id})", devices, decommissionReason, unassignUsers); return new DeviceDecommissionImportContext($"Batch: {deviceBatch.Name} ({deviceBatch.Id})", devices, decommissionReason, unassignUsers);
} }
public static DeviceDecommissionImportContext Create(DiscoDataContext database, DeviceProfile deviceProfile, DecommissionReasons decommissionReason, bool unassignUsers)
{
var devices = database.Devices
.Include(d => d.Jobs)
.Include(d => d.AssignedUser)
.Where(d => d.DeviceProfileId == deviceProfile.Id && d.DecommissionedDate == null)
.ToList();
return new DeviceDecommissionImportContext($"Profile: {deviceProfile.Name} ({deviceProfile.Id})", devices, decommissionReason, unassignUsers);
}
public static DeviceDecommissionImportContext Create(DiscoDataContext database, DeviceModel deviceModel, DecommissionReasons decommissionReason, bool unassignUsers)
{
var devices = database.Devices
.Include(d => d.Jobs)
.Include(d => d.AssignedUser)
.Where(d => d.DeviceModelId == deviceModel.Id && d.DecommissionedDate == null)
.ToList();
return new DeviceDecommissionImportContext($"Model: {deviceModel.Description} ({deviceModel.Id})", devices, decommissionReason, unassignUsers);
}
public IDeviceImportColumn GetColumn(int Index) public IDeviceImportColumn GetColumn(int Index)
=> throw new NotImplementedException(); => throw new NotImplementedException();
@@ -43,6 +43,12 @@ namespace Disco.Services.Devices.Importing
public static IDeviceImportContext BeginDecommissionImport(DiscoDataContext database, DeviceBatch deviceBatch, DecommissionReasons decommissionReason, bool unassignUsers) public static IDeviceImportContext BeginDecommissionImport(DiscoDataContext database, DeviceBatch deviceBatch, DecommissionReasons decommissionReason, bool unassignUsers)
=> DeviceDecommissionImportContext.Create(database, deviceBatch, decommissionReason, unassignUsers); => DeviceDecommissionImportContext.Create(database, deviceBatch, decommissionReason, unassignUsers);
public static IDeviceImportContext BeginDecommissionImport(DiscoDataContext database, DeviceProfile deviceProfile, DecommissionReasons decommissionReason, bool unassignUsers)
=> DeviceDecommissionImportContext.Create(database, deviceProfile, decommissionReason, unassignUsers);
public static IDeviceImportContext BeginDecommissionImport(DiscoDataContext database, DeviceModel deviceModel, DecommissionReasons decommissionReason, bool unassignUsers)
=> DeviceDecommissionImportContext.Create(database, deviceModel, decommissionReason, unassignUsers);
private static void GuessHeaderTypes(this IDeviceImportContext Context, DiscoDataContext Database) private static void GuessHeaderTypes(this IDeviceImportContext Context, DiscoDataContext Database)
{ {
using (var dataReader = Context.GetDataReader()) using (var dataReader = Context.GetDataReader())
@@ -730,6 +730,32 @@ namespace Disco.Web.Areas.API.Controllers
return RedirectToAction(MVC.Device.ImportReview(context.SessionId)); return RedirectToAction(MVC.Device.ImportReview(context.SessionId));
} }
[DiscoAuthorize(Claims.Device.Actions.Import)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult DeviceProfileDecommission(int id, DecommissionReasons? decommissionReason = null, bool? unassignUsers = null)
{
var deviceProfile = Database.DeviceProfiles.Find(id)
?? throw new ArgumentException("Invalid Device Profile Id", nameof(id));
if (decommissionReason == null)
throw new ArgumentNullException(nameof(decommissionReason), "Decommission Reason is required");
var context = DeviceImport.BeginDecommissionImport(Database, deviceProfile, decommissionReason.Value, unassignUsers.GetValueOrDefault());
Import_StoreContext(context);
return RedirectToAction(MVC.Device.ImportReview(context.SessionId));
}
[DiscoAuthorize(Claims.Device.Actions.Import)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult DeviceModelDecommission(int id, DecommissionReasons? decommissionReason = null, bool? unassignUsers = null)
{
var deviceModel = Database.DeviceModels.Find(id)
?? throw new ArgumentException("Invalid Device Model Id", nameof(id));
if (decommissionReason == null)
throw new ArgumentNullException(nameof(decommissionReason), "Decommission Reason is required");
var context = DeviceImport.BeginDecommissionImport(Database, deviceModel, decommissionReason.Value, unassignUsers.GetValueOrDefault());
Import_StoreContext(context);
return RedirectToAction(MVC.Device.ImportReview(context.SessionId));
}
#endregion #endregion
#region Exporting #region Exporting
@@ -40,6 +40,7 @@ namespace Disco.Web.Areas.Config.Controllers
}; };
m.CanDelete = m.DeviceModel.CanDelete(Database); m.CanDelete = m.DeviceModel.CanDelete(Database);
m.CanDecommission = m.DeviceModel.CanDecommission(Database);
if (m.DeviceCount - m.DeviceDecommissionedCount > 0) if (m.DeviceCount - m.DeviceDecommissionedCount > 0)
m.BulkGenerateDocumentTemplates = Database.DocumentTemplates.Where(t => !t.IsHidden).ToList(); m.BulkGenerateDocumentTemplates = Database.DocumentTemplates.Where(t => !t.IsHidden).ToList();
@@ -85,6 +85,7 @@ namespace Disco.Web.Areas.Config.Controllers
}); });
} }
m.CanDelete = m.DeviceProfile.CanDelete(Database); m.CanDelete = m.DeviceProfile.CanDelete(Database);
m.CanDecommission = m.DeviceProfile.CanDecommission(Database);
if (m.DeviceCount - m.DeviceDecommissionedCount > 0) if (m.DeviceCount - m.DeviceDecommissionedCount > 0)
m.BulkGenerateDocumentTemplates = Database.DocumentTemplates.Where(t => !t.IsHidden).ToList(); m.BulkGenerateDocumentTemplates = Database.DocumentTemplates.Where(t => !t.IsHidden).ToList();
@@ -18,6 +18,7 @@ namespace Disco.Web.Areas.Config.Models.DeviceModel
public int DeviceDecommissionedCount { get; set; } public int DeviceDecommissionedCount { get; set; }
public bool CanDelete { get; set; } public bool CanDelete { get; set; }
public bool CanDecommission { get; set; }
public override int DeviceGroupId => DeviceModel.Id; public override int DeviceGroupId => DeviceModel.Id;
} }
@@ -44,6 +44,7 @@ namespace Disco.Web.Areas.Config.Models.DeviceProfile
public int DeviceDecommissionedCount { get; set; } public int DeviceDecommissionedCount { get; set; }
public bool CanDelete { get; set; } public bool CanDelete { get; set; }
public bool CanDecommission { get; set; }
public override int DeviceGroupId => DeviceProfile.Id; public override int DeviceGroupId => DeviceProfile.Id;
} }
@@ -247,6 +247,65 @@
@Html.Partial(MVC.Config.DeviceModel.Views._DeviceComponentsTable, Model.DeviceComponentsModel) @Html.Partial(MVC.Config.DeviceModel.Views._DeviceComponentsTable, Model.DeviceComponentsModel)
@Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model) @Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model)
<div class="actionBar"> <div class="actionBar">
@if (Model.CanDecommission)
{
<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))
{
@Html.AntiForgeryToken()
<div class="clearfix" style="margin-bottom: 10px;">
<i class="fa fa-question-circle fa-lg information"></i>&nbsp;Why are these devices to be decommissioned?
</div>
<div>
<ul class="none">
@foreach (DecommissionReasons decommissionReason in Enum.GetValues(typeof(DecommissionReasons)).Cast<DecommissionReasons>().OrderBy(r => r.ToString()))
{
<li>
<input type="radio" id="DeviceModel_Decommission_Dialog_Reason_@((int)decommissionReason)"
name="decommissionReason" value="@((int)decommissionReason)" @((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty) />
<label for="DeviceModel_Decommission_Dialog_Reason_@((int)decommissionReason)">@(decommissionReason.ReasonMessage())</label>
</li>
}
</ul>
<br />
<label>
<input type="checkbox" value="true" name="unassignUsers" />
Unassign devices users
</label>
</div>
}
</div>
<script type="text/javascript">
$(function () {
let buttonDialog = null;
$('#DeviceModel_Decommission').click(function () {
if (!buttonDialog) {
buttonDialog = $('#DeviceModel_Decommission_Dialog')
.dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
"Decommission": function () {
const $this = $(this);
$this.find('form').trigger('submit');
$this.dialog("disable");
$this.dialog("option", "buttons", null);
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
return false;
});
});
</script>
}
@if (Model.CanDelete) @if (Model.CanDelete)
{ {
@Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete") @Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete")
@@ -824,6 +824,224 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
#line 250 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 250 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.CanDecommission)
{
#line default
#line hidden
WriteLiteral(" <button");
WriteLiteral(" id=\"DeviceModel_Decommission\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Decommission All Devices</button>\r\n");
WriteLiteral(" <div");
WriteLiteral(" id=\"DeviceModel_Decommission_Dialog\"");
WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Model Device Decommission\"");
WriteLiteral(">\r\n");
#line 254 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 254 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
using (Html.BeginForm(MVC.API.Device.DeviceModelDecommission(Model.DeviceModel.Id), FormMethod.Post))
{
#line default
#line hidden
#line 256 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 256 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"clearfix\"");
WriteLiteral(" style=\"margin-bottom: 10px;\"");
WriteLiteral(">\r\n <i");
WriteLiteral(" class=\"fa fa-question-circle fa-lg information\"");
WriteLiteral("></i>&nbsp;Why are these devices to be decommissioned?\r\n </div>\r\n");
WriteLiteral(" <div>\r\n <ul");
WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n");
#line 262 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
#line default
#line hidden
#line 262 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
foreach (DecommissionReasons decommissionReason in Enum.GetValues(typeof(DecommissionReasons)).Cast<DecommissionReasons>().OrderBy(r => r.ToString()))
{
#line default
#line hidden
WriteLiteral(" <li>\r\n <input");
WriteLiteral(" type=\"radio\"");
WriteAttribute("id", Tuple.Create(" id=\"", 9803), Tuple.Create("\"", 9873)
, Tuple.Create(Tuple.Create("", 9808), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 9808), true)
#line 265 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 9847), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 9847), false)
);
WriteLiteral("\r\n name=\"decommissionReason\"");
WriteAttribute("value", Tuple.Create(" value=\"", 9940), Tuple.Create("\"", 9974)
#line 266 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 9948), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 9948), false)
);
WriteLiteral(" ");
#line 266 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty);
#line default
#line hidden
WriteLiteral(" />\r\n <label");
WriteAttribute("for", Tuple.Create(" for=\"", 10114), Tuple.Create("\"", 10185)
, Tuple.Create(Tuple.Create("", 10120), Tuple.Create("DeviceModel_Decommission_Dialog_Reason_", 10120), true)
#line 267 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
, Tuple.Create(Tuple.Create("", 10159), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 10159), false)
);
WriteLiteral(">");
#line 267 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(decommissionReason.ReasonMessage());
#line default
#line hidden
WriteLiteral("</label>\r\n </li>\r\n");
#line 269 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" </ul>\r\n <br />\r\n <label" +
">\r\n <input");
WriteLiteral(" type=\"checkbox\"");
WriteLiteral(" value=\"true\"");
WriteLiteral(" name=\"unassignUsers\"");
WriteLiteral(" />\r\n Unassign devices users\r\n </label>" +
"\r\n </div>\r\n");
#line 277 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
let buttonDialog = null;
$('#DeviceModel_Decommission').click(function () {
if (!buttonDialog) {
buttonDialog = $('#DeviceModel_Decommission_Dialog')
.dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
""Decommission"": function () {
const $this = $(this);
$this.find('form').trigger('submit');
$this.dialog(""disable"");
$this.dialog(""option"", ""buttons"", null);
},
Cancel: function () {
$(this).dialog(""close"");
}
}
});
}
buttonDialog.dialog('open');
return false;
});
});
</script>
");
#line 308 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" ");
#line 309 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.CanDelete) if (Model.CanDelete)
{ {
@@ -831,14 +1049,14 @@ WriteLiteral(">\r\n");
#line default #line default
#line hidden #line hidden
#line 252 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 311 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete")); Write(Html.ActionLinkButton("Delete", MVC.API.DeviceModel.Delete(Model.DeviceModel.Id, true), "buttonDelete"));
#line default #line default
#line hidden #line hidden
#line 252 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 311 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
} }
@@ -848,7 +1066,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 254 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 313 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
if (Model.DeviceCount > 0) if (Model.DeviceCount > 0)
{ {
if (Authorization.Has(Claims.Device.Actions.Export)) if (Authorization.Has(Claims.Device.Actions.Export))
@@ -858,14 +1076,14 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
#line 258 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 317 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
Write(Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Model, Model.DeviceModel.Id))); Write(Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Model, Model.DeviceModel.Id)));
#line default #line default
#line hidden #line hidden
#line 258 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 317 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
} }
if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0) if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0)
@@ -875,14 +1093,14 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
#line 262 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 321 "..\..\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"))); 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 default
#line hidden #line hidden
#line 262 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml" #line 321 "..\..\Areas\Config\Views\DeviceModel\Show.cshtml"
} }
} }
@@ -1006,6 +1006,65 @@
} }
@Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model) @Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model)
<div class="actionBar"> <div class="actionBar">
@if (Model.CanDecommission)
{
<button id="DeviceProfile_Decommission" class="button">Decommission All Devices</button>
<div id="DeviceProfile_Decommission_Dialog" class="dialog" title="Profile Device Decommission">
@using (Html.BeginForm(MVC.API.Device.DeviceProfileDecommission(Model.DeviceProfile.Id), FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="clearfix" style="margin-bottom: 10px;">
<i class="fa fa-question-circle fa-lg information"></i>&nbsp;Why are these devices to be decommissioned?
</div>
<div>
<ul class="none">
@foreach (DecommissionReasons decommissionReason in Enum.GetValues(typeof(DecommissionReasons)).Cast<DecommissionReasons>().OrderBy(r => r.ToString()))
{
<li>
<input type="radio" id="DeviceProfile_Decommission_Dialog_Reason_@((int)decommissionReason)"
name="decommissionReason" value="@((int)decommissionReason)" @((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty) />
<label for="DeviceProfile_Decommission_Dialog_Reason_@((int)decommissionReason)">@(decommissionReason.ReasonMessage())</label>
</li>
}
</ul>
<br />
<label>
<input type="checkbox" value="true" name="unassignUsers" />
Unassign devices users
</label>
</div>
}
</div>
<script type="text/javascript">
$(function () {
let buttonDialog = null;
$('#DeviceProfile_Decommission').click(function () {
if (!buttonDialog) {
buttonDialog = $('#DeviceProfile_Decommission_Dialog')
.dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
"Decommission": function () {
const $this = $(this);
$this.find('form').trigger('submit');
$this.dialog("disable");
$this.dialog("option", "buttons", null);
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
return false;
});
});
</script>
}
@if (canDelete) @if (canDelete)
{ {
@Html.ActionLinkButton("Delete", MVC.API.DeviceProfile.Delete(Model.DeviceProfile.Id, true), "buttonDelete") @Html.ActionLinkButton("Delete", MVC.API.DeviceProfile.Delete(Model.DeviceProfile.Id, true), "buttonDelete")
@@ -2989,6 +2989,224 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
#line 1009 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1009 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
if (Model.CanDecommission)
{
#line default
#line hidden
WriteLiteral(" <button");
WriteLiteral(" id=\"DeviceProfile_Decommission\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Decommission All Devices</button>\r\n");
WriteLiteral(" <div");
WriteLiteral(" id=\"DeviceProfile_Decommission_Dialog\"");
WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Profile Device Decommission\"");
WriteLiteral(">\r\n");
#line 1013 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
#line default
#line hidden
#line 1013 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
using (Html.BeginForm(MVC.API.Device.DeviceProfileDecommission(Model.DeviceProfile.Id), FormMethod.Post))
{
#line default
#line hidden
#line 1015 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 1015 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"clearfix\"");
WriteLiteral(" style=\"margin-bottom: 10px;\"");
WriteLiteral(">\r\n <i");
WriteLiteral(" class=\"fa fa-question-circle fa-lg information\"");
WriteLiteral("></i>&nbsp;Why are these devices to be decommissioned?\r\n </div>\r\n");
WriteLiteral(" <div>\r\n <ul");
WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n");
#line 1021 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
#line default
#line hidden
#line 1021 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
foreach (DecommissionReasons decommissionReason in Enum.GetValues(typeof(DecommissionReasons)).Cast<DecommissionReasons>().OrderBy(r => r.ToString()))
{
#line default
#line hidden
WriteLiteral(" <li>\r\n <input");
WriteLiteral(" type=\"radio\"");
WriteAttribute("id", Tuple.Create(" id=\"", 56977), Tuple.Create("\"", 57049)
, Tuple.Create(Tuple.Create("", 56982), Tuple.Create("DeviceProfile_Decommission_Dialog_Reason_", 56982), true)
#line 1024 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
, Tuple.Create(Tuple.Create("", 57023), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 57023), false)
);
WriteLiteral("\r\n name=\"decommissionReason\"");
WriteAttribute("value", Tuple.Create(" value=\"", 57116), Tuple.Create("\"", 57150)
#line 1025 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
, Tuple.Create(Tuple.Create("", 57124), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 57124), false)
);
WriteLiteral(" ");
#line 1025 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty);
#line default
#line hidden
WriteLiteral(" />\r\n <label");
WriteAttribute("for", Tuple.Create(" for=\"", 57290), Tuple.Create("\"", 57363)
, Tuple.Create(Tuple.Create("", 57296), Tuple.Create("DeviceProfile_Decommission_Dialog_Reason_", 57296), true)
#line 1026 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
, Tuple.Create(Tuple.Create("", 57337), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default
#line hidden
, 57337), false)
);
WriteLiteral(">");
#line 1026 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write(decommissionReason.ReasonMessage());
#line default
#line hidden
WriteLiteral("</label>\r\n </li>\r\n");
#line 1028 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" </ul>\r\n <br />\r\n <label" +
">\r\n <input");
WriteLiteral(" type=\"checkbox\"");
WriteLiteral(" value=\"true\"");
WriteLiteral(" name=\"unassignUsers\"");
WriteLiteral(" />\r\n Unassign devices users\r\n </label>" +
"\r\n </div>\r\n");
#line 1036 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
let buttonDialog = null;
$('#DeviceProfile_Decommission').click(function () {
if (!buttonDialog) {
buttonDialog = $('#DeviceProfile_Decommission_Dialog')
.dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
""Decommission"": function () {
const $this = $(this);
$this.find('form').trigger('submit');
$this.dialog(""disable"");
$this.dialog(""option"", ""buttons"", null);
},
Cancel: function () {
$(this).dialog(""close"");
}
}
});
}
buttonDialog.dialog('open');
return false;
});
});
</script>
");
#line 1067 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
}
#line default
#line hidden
WriteLiteral(" ");
#line 1068 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
if (canDelete) if (canDelete)
{ {
@@ -2996,14 +3214,14 @@ WriteLiteral(">\r\n");
#line default #line default
#line hidden #line hidden
#line 1011 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1070 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write(Html.ActionLinkButton("Delete", MVC.API.DeviceProfile.Delete(Model.DeviceProfile.Id, true), "buttonDelete")); Write(Html.ActionLinkButton("Delete", MVC.API.DeviceProfile.Delete(Model.DeviceProfile.Id, true), "buttonDelete"));
#line default #line default
#line hidden #line hidden
#line 1011 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1070 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
} }
@@ -3013,7 +3231,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 1013 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1072 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
if (Authorization.Has(Claims.Device.Actions.Export)) if (Authorization.Has(Claims.Device.Actions.Export))
{ {
@@ -3021,14 +3239,14 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
#line 1015 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1074 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write(Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Profile, Model.DeviceProfile.Id))); Write(Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Profile, Model.DeviceProfile.Id)));
#line default #line default
#line hidden #line hidden
#line 1015 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1074 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
} }
@@ -3038,7 +3256,7 @@ WriteLiteral(" ");
WriteLiteral(" "); WriteLiteral(" ");
#line 1017 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1076 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0) if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0)
{ {
@@ -3046,14 +3264,14 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
#line 1019 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1078 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
Write(Html.ActionLinkButton(string.Format("View {0} Device{1}", Model.DeviceCount, (Model.DeviceCount != 1 ? "s" : null)), MVC.Search.Query(Model.DeviceProfile.Id.ToString(), "DeviceProfile"))); Write(Html.ActionLinkButton(string.Format("View {0} Device{1}", Model.DeviceCount, (Model.DeviceCount != 1 ? "s" : null)), MVC.Search.Query(Model.DeviceProfile.Id.ToString(), "DeviceProfile")));
#line default #line default
#line hidden #line hidden
#line 1019 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml" #line 1078 "..\..\Areas\Config\Views\DeviceProfile\Show.cshtml"
} }
@@ -224,6 +224,18 @@ namespace Disco.Web.Areas.API.Controllers
} }
[NonAction] [NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult DeviceProfileDecommission()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.DeviceProfileDecommission);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult DeviceModelDecommission()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.DeviceModelDecommission);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Export() public virtual System.Web.Mvc.ActionResult Export()
{ {
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export); return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export);
@@ -283,6 +295,8 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string ImportParse = "ImportParse"; public readonly string ImportParse = "ImportParse";
public readonly string ImportApply = "ImportApply"; public readonly string ImportApply = "ImportApply";
public readonly string DeviceBatchDecommission = "DeviceBatchDecommission"; public readonly string DeviceBatchDecommission = "DeviceBatchDecommission";
public readonly string DeviceProfileDecommission = "DeviceProfileDecommission";
public readonly string DeviceModelDecommission = "DeviceModelDecommission";
public readonly string Export = "Export"; public readonly string Export = "Export";
public readonly string ExportRetrieve = "ExportRetrieve"; public readonly string ExportRetrieve = "ExportRetrieve";
public readonly string SaveExport = "SaveExport"; public readonly string SaveExport = "SaveExport";
@@ -319,6 +333,8 @@ namespace Disco.Web.Areas.API.Controllers
public const string ImportParse = "ImportParse"; public const string ImportParse = "ImportParse";
public const string ImportApply = "ImportApply"; public const string ImportApply = "ImportApply";
public const string DeviceBatchDecommission = "DeviceBatchDecommission"; public const string DeviceBatchDecommission = "DeviceBatchDecommission";
public const string DeviceProfileDecommission = "DeviceProfileDecommission";
public const string DeviceModelDecommission = "DeviceModelDecommission";
public const string Export = "Export"; public const string Export = "Export";
public const string ExportRetrieve = "ExportRetrieve"; public const string ExportRetrieve = "ExportRetrieve";
public const string SaveExport = "SaveExport"; public const string SaveExport = "SaveExport";
@@ -575,6 +591,26 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string decommissionReason = "decommissionReason"; public readonly string decommissionReason = "decommissionReason";
public readonly string unassignUsers = "unassignUsers"; public readonly string unassignUsers = "unassignUsers";
} }
static readonly ActionParamsClass_DeviceProfileDecommission s_params_DeviceProfileDecommission = new ActionParamsClass_DeviceProfileDecommission();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_DeviceProfileDecommission DeviceProfileDecommissionParams { get { return s_params_DeviceProfileDecommission; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_DeviceProfileDecommission
{
public readonly string id = "id";
public readonly string decommissionReason = "decommissionReason";
public readonly string unassignUsers = "unassignUsers";
}
static readonly ActionParamsClass_DeviceModelDecommission s_params_DeviceModelDecommission = new ActionParamsClass_DeviceModelDecommission();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_DeviceModelDecommission DeviceModelDecommissionParams { get { return s_params_DeviceModelDecommission; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_DeviceModelDecommission
{
public readonly string id = "id";
public readonly string decommissionReason = "decommissionReason";
public readonly string unassignUsers = "unassignUsers";
}
static readonly ActionParamsClass_Export s_params_Export = new ActionParamsClass_Export(); static readonly ActionParamsClass_Export s_params_Export = new ActionParamsClass_Export();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Export ExportParams { get { return s_params_Export; } } public ActionParamsClass_Export ExportParams { get { return s_params_Export; } }
@@ -975,6 +1011,34 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo; return callInfo;
} }
[NonAction]
partial void DeviceProfileDecommissionOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, Disco.Models.Repository.DecommissionReasons? decommissionReason, bool? unassignUsers);
[NonAction]
public override System.Web.Mvc.ActionResult DeviceProfileDecommission(int id, Disco.Models.Repository.DecommissionReasons? decommissionReason, bool? unassignUsers)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.DeviceProfileDecommission);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "decommissionReason", decommissionReason);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "unassignUsers", unassignUsers);
DeviceProfileDecommissionOverride(callInfo, id, decommissionReason, unassignUsers);
return callInfo;
}
[NonAction]
partial void DeviceModelDecommissionOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, Disco.Models.Repository.DecommissionReasons? decommissionReason, bool? unassignUsers);
[NonAction]
public override System.Web.Mvc.ActionResult DeviceModelDecommission(int id, Disco.Models.Repository.DecommissionReasons? decommissionReason, bool? unassignUsers)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.DeviceModelDecommission);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "decommissionReason", decommissionReason);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "unassignUsers", unassignUsers);
DeviceModelDecommissionOverride(callInfo, id, decommissionReason, unassignUsers);
return callInfo;
}
[NonAction] [NonAction]
partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Web.Models.Device.ExportModel model); partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Web.Models.Device.ExportModel model);