Files
Disco/Disco.Web/Views/Device/DeviceParts/_Subject.cshtml
T
2025-07-31 16:18:32 +10:00

1106 lines
65 KiB
Plaintext

@model Disco.Web.Models.Device.ShowModel
@using Disco.Services.Users.UserFlags;
@{
Authorization.Require(Claims.Device.Show);
Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers");
}
<table id="Device_Show_Subjects">
<tr>
<td id="Device_Show_Details">
<div>
<div id="Device_Show_Details_Asset">
<table class="none verticalHeadings">
<tr>
<td>
<span title="Computer Name">Name:</span>
</td>
<td>
@if (string.IsNullOrWhiteSpace(Model.Device.ComputerName))
{
<span id="Device_Show_Details_Asset_NameUnknown" title="Computer Name" class="smallMessage">&lt;Unknown/None&gt;</span>
}
else
{
<h4 id="Device_Show_Details_Asset_Name" title="Computer Name"><span data-clipboard>@Model.Device.ComputerName</span></h4>
}
</td>
</tr>
<tr>
<td>
<span title="Domain Name">Domain:</span>
</td>
<td>
@if (string.IsNullOrWhiteSpace(Model.Device.ComputerDomainName))
{
<span id="Device_Show_Details_Asset_DomainUnknown" title="Computer Domain" class="smallMessage">&lt;None&gt;</span>
}
else
{
<h4 id="Device_Show_Details_Asset_Domain" title="Computer Domain"><span data-clipboard>@Model.Device.ComputerDomainName</span></h4>
}
</td>
</tr>
<tr>
<td>Asset:</td>
<td>
@if (Authorization.Has(Claims.Device.Properties.AssetNumber))
{
@Html.TextBoxFor(m => m.Device.AssetNumber, new { @class = "small discreet" }) @AjaxHelpers.AjaxSave() @AjaxHelpers.AjaxLoader()
}
else
{
<span class="small discreet" data-clipboard>@(Model.Device.AssetNumber ?? "Unknown")</span>
}
</td>
</tr>
<tr>
<td>Location:</td>
<td>
@if (Authorization.Has(Claims.Device.Properties.Location))
{
@Html.TextBoxFor(m => m.Device.Location, new { @class = "small discreet" }) @AjaxHelpers.AjaxSave() @AjaxHelpers.AjaxLoader()
}
else
{
<span class="small discreet" data-clipboard>@(Model.Device.Location ?? "Unknown")</span>
}
</td>
</tr>
</table>
@if (Authorization.HasAny(Claims.Device.Properties.AssetNumber, Claims.Device.Properties.Location))
{
<script>
$(function () {
@if (Authorization.Has(Claims.Device.Properties.AssetNumber))
{<text>document.DiscoFunctions.PropertyChangeHelper($('#Device_AssetNumber'), 'Unknown', '@Url.Action(MVC.API.Device.UpdateAssetNumber(Model.Device.SerialNumber, null))', 'AssetNumber');</text>}
@if (Authorization.Has(Claims.Device.Properties.Location))
{<text>document.DiscoFunctions.PropertyChangeHelper($('#Device_Location'), 'Unknown', '@Url.Action(MVC.API.Device.UpdateLocation(Model.Device.SerialNumber, null))', 'Location');</text>}
});
</script>
}
</div>
<div id="Device_Show_Details_Dates" class="status">
<table class="none verticalHeadings">
<tr>
<td>
Created:
</td>
<td><span id="Device_Show_Details_Dates_Created">@CommonHelpers.FriendlyDate(Model.Device.CreatedDate)</span></td>
</tr>
@if (Model.Device.DecommissionedDate.HasValue)
{
<tr>
<td>
Decommissioned:
</td>
<td><span id="Device_Show_Details_Dates_Decommissioned">@CommonHelpers.FriendlyDate(Model.Device.DecommissionedDate)</span></td>
</tr>
}
<tr>
<td>
Enrolled:
</td>
<td>
@if (Model.Device.EnrolledDate.HasValue)
{
<text>First: </text><span id="Device_Show_Details_Asset_Enrolled_First">@CommonHelpers.FriendlyDate(Model.Device.EnrolledDate)</span>
if (Model.Device.LastEnrolDate.HasValue && Model.Device.EnrolledDate.Value != Model.Device.LastEnrolDate.Value)
{
<br /><text>Last: </text><span id="Device_Show_Details_Asset_Enrolled_Last">@CommonHelpers.FriendlyDate(Model.Device.LastEnrolDate)</span>
}
}
else
{
<span id="Device_Show_Details_Asset_Enrolled_Never" class="smallMessage">Never</span>
}
@if (Model.Device.AllowUnauthenticatedEnrol)
{
<span id="Device_Show_Details_Asset_Enrolled_Trusted" title="Trusted Unauthenticated Enrolment is Allowed"></span>
}
</td>
</tr>
</table>
</div>
<div id="Device_Show_Details_Status" class="status">
<table class="none verticalHeadings">
<tr>
<td>
<span title="Last Network Logon Date">Last Seen:</span>
</td>
<td>
@{
string lastSeenClass = null;
if (Model.Device.LastNetworkLogonDate.HasValue)
{
if (Model.Device.LastNetworkLogonDate.Value < DateTime.Now.AddDays(-30))
{
lastSeenClass = "error";
}
else
{
if (Model.Device.LastNetworkLogonDate.Value < DateTime.Now.AddDays(-7))
{
lastSeenClass = "alert";
}
}
}
}
<span id="Device_Show_Details_Status_LastSeen" class="@lastSeenClass" data-updateurl="@(Url.Action(MVC.API.Device.LastNetworkLogonDate(Model.Device.SerialNumber)))">@CommonHelpers.FriendlyDate(Model.Device.LastNetworkLogonDate)</span>
</td>
@if (!string.IsNullOrEmpty(Model.Device.ComputerName))
{
<script type="text/javascript">
$(function () {
const span = $('#Device_Show_Details_Status_LastSeen');
let updated = false;
let spanProgress = null;
async function updateLastNetworkLogonDate() {
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
const response = await fetch(span.attr('data-updateurl'), {
method: 'POST',
body: body
});
updated = true;
if (spanProgress)
spanProgress.remove();
if (!response.ok) {
alert('Unable to retrieve latest network logon date:\n' + response.statusText);
$('<span>').addClass('smallMessage').text('[may not be current]').appendTo(span);
} else {
const result = await response.json();
var spanClasses = '',
diff = moment().valueOf() - result.UnixEpoc;
if (diff > 2592000000) // 30 Days
spanClasses = 'error';
else if (diff > 604800000) // 7 Days
spanClasses = 'alert';
span.removeClass('alert error').addClass(spanClasses).attr('title', result.Formatted).text(result.Formatted).livestamp(result.UnixEpoc);
}
}
updateLastNetworkLogonDate();
window.setTimeout(function () {
if (!updated) {
spanProgress = $('<i>').addClass('ajaxLoading showInitially').attr('title', 'Loading...').appendTo(span);
}
}, 250);
});
</script>
}
</tr>
</table>
</div>
<div class="status">
@{
var assignedUser = Model.Device.AssignedUser;
}
<table class="none verticalHeadings">
<tr>
<td>
Assignment:
</td>
<td>
@if (assignedUser != null)
{
<div id="Device_Show_User" class="clearfix @(Model.HasAssignedUserPhoto ? "hasPhoto" : "noPhoto")">
@if (Model.HasAssignedUserPhoto)
{
<div id="Device_Show_User_Photo_Container">
<img id="Device_Show_User_Photo" src="@Url.Action(MVC.API.User.Photo(assignedUser.UserId))" />
</div>
}
<div id="Device_Show_User_DisplayName" title="Display Name">
<span data-clipboard>
@if (Authorization.Has(Claims.User.Show))
{
@Html.ActionLink(assignedUser.DisplayName, MVC.User.Show(assignedUser.UserId))
}
else
{
@assignedUser.DisplayName
}
</span>
</div>
<div id="Device_Show_User_Id" title="Id"><span data-clipboard>@assignedUser.FriendlyId()</span></div>
@if (Authorization.Has(Claims.User.ShowDetails))
{
if (!string.IsNullOrWhiteSpace(assignedUser.PhoneNumber))
{
<div id="Device_Show_User_PhoneNumber" title="Phone Number"><a href="tel:@assignedUser.PhoneNumber" data-clipboard>@assignedUser.PhoneNumber</a></div>
}
if (!string.IsNullOrWhiteSpace(assignedUser.EmailAddress))
{
<div id="Device_Show_User_EmailAddress" title="Email Address"><a href="mailto:@(Model.Device.AssignedUser.EmailAddress)" data-clipboard="@assignedUser.DisplayName &lt;@assignedUser.EmailAddress&gt;">@assignedUser.EmailAddress</a></div>
}
}
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
{
<div id="Device_Show_User_Flags">
@foreach (var flag in assignedUser.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
<script type="text/javascript">
$(function () {
$('#Device_Show_User_Flags')
.tooltip({
items: 'i.flag',
content: function () {
var $this = $(this);
return $this.children('.details').html();
},
tooltipClass: 'FlagAssignment_Tooltip',
position: {
my: "right top",
at: "right bottom",
collision: "flipfit flip"
},
hade: {
effect: ''
},
close: function (e, ui) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(100, 1);
},
function () {
$(this).fadeOut(100, function () { $(this).remove(); });
});
}
});
});
</script>
</div>
}
@if (Model.AssignedUserDetails != null && Model.AssignedUserDetails.Count(d => !d.Key.EndsWith("&")) > 0)
{
<div id="Device_Show_User_CustomDetails" class="status clearfix">
@foreach (var detail in Model.AssignedUserDetails.Where(d => !d.Key.EndsWith("&")))
{
<div>
<strong>@detail.Key.TrimEnd('*'):</strong>
@if (detail.Key.EndsWith("*"))
{
<a href="" class="reveal smallMessage">[reveal]</a>
<span class="reveal hidden">@Html.Partial(MVC.Shared.Views._CustomDetailValueRender, detail)</span>
}
else
{
@Html.Partial(MVC.Shared.Views._CustomDetailValueRender, detail)
}
</div>
}
<script type="text/javascript">
$(() => {
$('#Device_Show_User_CustomDetails').on('click', 'a.reveal', e => {
e.preventDefault();
const t = $(e.currentTarget);
t.next('span.reveal').removeClass('hidden');
t.remove();
return false;
})
});
</script>
</div>
}
</div>
}
else
{
<span class="smallMessage">Not Assigned</span>
}
</td>
</tr>
</table>
</div>
@if (Authorization.Has(Claims.Device.Actions.GenerateDocuments))
{
<div id="Device_Show_GenerateDocument_Container" class="status">
@Html.Partial(MVC.Shared.Views._GenerateDocumentControl, Model.GenerateDocumentControlModel)
</div>
}
</div>
</td>
<td id="Device_Show_Policies" rowspan="2">
<div>
<div id="Device_Show_Policies_Profile">
<h2 title="Device Profile">
@if (Authorization.Has(Claims.Config.DeviceProfile.Show))
{
@Html.ActionLink(Model.Device.DeviceProfile.Name, MVC.Config.DeviceProfile.Index(Model.Device.DeviceProfileId))
}
else
{
@Model.Device.DeviceProfile.Name
}
</h2>
<table class="none verticalHeadings">
<tr>
<td>
<span title="Distribution Type">Distribution:</span>
</td>
<td>
@Model.Device.DeviceProfile.DistributionType.ToString()
</td>
</tr>
<tr>
<td>
<span title="Address">Address:</span>
</td>
<td>
@{
if (Model.DeviceProfileDefaultOrganisationAddress != null)
{
<span id="Device_Show_Policies_Profile_Address">@Model.DeviceProfileDefaultOrganisationAddress.Name</span>
}
else
{
<span id="Device_Show_Policies_Profile_Address_None" class="smallMessage">None</span>
}
}
</td>
</tr>
<tr>
<td>
<span title="Provision Active Directory Account">Provision Account:</span>
</td>
<td>
@(Model.Device.DeviceProfile.ProvisionADAccount ? "Active Directory" : "No")
</td>
</tr>
<tr>
<td>
<span title="Provisioned Personal Certificates">Certificates:</span>
</td>
<td>
@(Model.DeviceProfileCertificateProviders != null ? string.Join(", ", Model.DeviceProfileCertificateProviders.Select(c => c.Name)) : "None Provisioned")
</td>
<tr>
<td>
<span title="Provisioned Wireless Profiles">Wireless Profiles:</span>
</td>
<td>
@(Model.DeviceProfileWirelessProfileProviders != null ? string.Join(", ", Model.DeviceProfileWirelessProfileProviders.Select(c => c.Name)) : "None Provisioned")
</td>
</tr>
</table>
@if (Model.Device.CanUpdateDeviceProfile())
{
<button id="Device_Show_Policies_Profile_Actions_Update_Button" class="button small">Update Profile</button>
<div id="Device_Show_Policies_Profile_Actions_Update_Dialog" class="dialog" title="Assign to Device Profile">
@using (Html.BeginForm(MVC.API.Device.UpdateDeviceProfileId(Model.Device.SerialNumber, redirect: true)))
{
<div class="profile-list">
@Html.AntiForgeryToken()
<ul class="none">
@foreach (var dp in Model.DeviceProfiles.OrderBy(i => i.Name))
{
var isDecommissioned = Model.DecommissionedDeviceProfileIds.Contains(dp.Id);
<li class="@(isDecommissioned ? "hidden" : null)">
<label title="Distribution: @(dp.DistributionType)">
<input type="radio" name="DeviceProfileId" value="@dp.Id" data-ouenforced="@dp.EnforceOrganisationalUnit" @(Model.Device.DeviceProfileId == dp.Id ? "checked " : null) />
@dp.Name
</label>
</li>
if (isDecommissioned)
{
<li class="hidden decommissioned-padding"></li>
}
}
</ul>
@if (Model.DecommissionedDeviceProfileIds.Count > 0)
{
<a class="button small show-decommissioned" href="#">Show Decommissioned</a>
}
</div>
<div class="enforce-ou">
<input id="deviceProfileMoveOrganisationalUnit" type="checkbox" name="enforceOrganisationalUnit" value="true" /><label for="deviceProfileMoveOrganisationalUnit">Move to Profiles Organisational Unit</label>
</div>
}
</div>
<script>
$(function () {
var currentProfile = '@(Model.Device.DeviceProfileId)';
var button = $('#Device_Show_Policies_Profile_Actions_Update_Button');
var buttonDialog = null;
var dialogInputs = null;
var dialogContainers = null;
button.click(function (e) {
e.preventDefault();
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Policies_Profile_Actions_Update_Dialog')
.dialog({
resizable: false,
modal: true,
maxHeight: 450,
autoOpen: false,
buttons: {
"Update Profile": function () {
var deviceProfileId = dialogInputs.filter(':checked').val();
if (deviceProfileId) {
var $this = $(this);
$this.dialog("disable");
$this.dialog("option", "buttons", null);
$this.find('form').submit();
} else {
alert('A device profile must be selected');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
});
dialogInputs = buttonDialog.find('input[type="radio"]');
dialogContainers = dialogInputs.closest('li');
dialogInputs.change(function () {
const $this = $(this);
dialogContainers.removeClass('selected');
$this.closest('li').addClass('selected');
$('#deviceProfileMoveOrganisationalUnit').prop('checked', $this.attr('data-ouenforced') === 'True');
});
buttonDialog.find('.show-decommissioned')
.click(function (e) {
e.preventDefault();
var $this = $(this);
buttonDialog.find('ul.none')
.find('li.hidden').removeClass('hidden')
.filter('.decommissioned-padding').remove();
$this.remove();
return false;
})
}
dialogInputs.filter('[data-deviceprofileid=' + currentProfile + ']').prop('checked', true).change();
buttonDialog.dialog('open');
return false;
});
});
</script>
}
</div>
<div id="Device_Show_Policies_Batch" class="status">
@if (Model.Device.DeviceBatchId.HasValue)
{
<h2 title="Device Batch">
@if (Authorization.Has(Claims.Config.DeviceBatch.Show))
{
@Html.ActionLink(Model.Device.DeviceBatch.Name, MVC.Config.DeviceBatch.Index(Model.Device.DeviceBatchId.Value))
}
else
{
@Model.Device.DeviceBatch.Name
}
</h2>
<table class="none verticalHeadings">
<tr>
<td>
<span title="Purchased Date">Purchased:</span>
</td>
<td>
@CommonHelpers.FriendlyDate(Model.Device.DeviceBatch.PurchaseDate)
</td>
</tr>
<tr>
<td>
<span title="Supplier">Supplier:</span>
</td>
<td>
@(Model.Device.DeviceBatch.Supplier ?? "Unknown")
</td>
</tr>
<tr>
<td>
<span title="Warranty Valid Until">Warranty Until:</span>
</td>
<td class="@(Model.Device.DeviceBatch.WarrantyValidUntil.HasValue && Model.Device.DeviceBatch.WarrantyValidUntil.Value < DateTime.Now ? "alert" : null)">
@CommonHelpers.FriendlyDate(Model.Device.DeviceBatch.WarrantyValidUntil, "Unknown", null)
</td>
</tr>
<tr>
<td>
<span title="Insurance Supplier">Insurance Supplier:</span>
</td>
<td>
@(Model.Device.DeviceBatch.InsuranceSupplier ?? "Unknown")
</td>
</tr>
<tr>
<td>
<span title="Insured Until">Insured Until:</span>
</td>
<td class="@(Model.Device.DeviceBatch.InsuredUntil.HasValue && Model.Device.DeviceBatch.InsuredUntil.Value < DateTime.Now ? "alert" : null)">
@CommonHelpers.FriendlyDate(Model.Device.DeviceBatch.InsuredUntil, "Unknown", null)
</td>
</tr>
</table>
}
else
{
<h2>Batch: <em>Not Associated</em></h2>
}
@if (Model.Device.CanUpdateDeviceBatch())
{
<button id="Device_Show_Policies_Batch_Actions_Update_Button" class="button small">Update Batch</button>
<div id="Device_Show_Policies_Batch_Actions_Update_Dialog" class="dialog" title="Assign to Device Batch">
<div>
@using (Html.BeginForm(MVC.API.Device.UpdateDeviceBatchId(Model.Device.SerialNumber, null, true)))
{
@Html.AntiForgeryToken()
<ul class="none">
@foreach (var db in Model.DeviceBatches.OrderBy(i => i.Name))
{
var isDecommissioned = Model.DecommissionedDeviceBatchIds.Contains(db.Id);
<li class="@(isDecommissioned ? "hidden" : null)">
<label title="Purchased: @(db.PurchaseDate.ToLongDateString())">
<input type="radio" data-devicebatchid="@db.Id" name="DeviceBatchId" value="@db.Id" />
@db.Name
</label>
</li>
if (isDecommissioned)
{
<li class="hidden decommissioned-padding"></li>
}
}
</ul>
}
@if (Model.DecommissionedDeviceBatchIds.Count > 0)
{
<a class="button small show-decommissioned" href="#">Show Decommissioned</a>
}
</div>
</div>
<script>
$(function () {
var currentBatch = '@(Model.Device.DeviceBatchId)';
var button = $('#Device_Show_Policies_Batch_Actions_Update_Button');
var buttonDialog = null;
var dialogInputs = null;
var dialogContainers = null;
button.click(function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Policies_Batch_Actions_Update_Dialog')
.dialog({
resizable: false,
modal: true,
maxHeight: 450,
autoOpen: false,
buttons: {
"Update Batch": function () {
var deviceBatchId = dialogInputs.filter(':checked').attr('data-devicebatchid');
if (deviceBatchId) {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
} else {
alert('A device batch must be selected');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
});
dialogInputs = buttonDialog.find('input');
dialogContainers = dialogInputs.closest('li');
dialogInputs.change(function () {
dialogContainers.removeClass('selected');
$(this).closest('li').addClass('selected');
});
buttonDialog.find('.show-decommissioned')
.click(function (e) {
e.preventDefault();
var $this = $(this);
buttonDialog.find('ul.none')
.find('li.hidden').removeClass('hidden')
.filter('.decommissioned-padding').remove();
$this.remove();
return false;
})
}
if (!!currentBatch) {
dialogInputs.filter('[data-devicebatchid=' + currentBatch + ']').prop('checked', true).change();
}
buttonDialog.dialog('open');
return false;
});
});
</script>
}
</div>
</div>
</td>
<td id="Device_Show_Aspects" rowspan="2">
<div>
<div id="Device_Show_Aspects_Model" class="clearfix">
<h2 id="Device_Show_Aspects_Model_Description" title="Model Description">
@if (Authorization.Has(Claims.Config.DeviceModel.Show))
{
@Html.ActionLink(Model.Device.DeviceModel.ToString(), MVC.Config.DeviceModel.Index(Model.Device.DeviceModelId))
}
else
{
@Model.Device.DeviceModel.ToString()
}
</h2>
<img id="Device_Show_Aspects_Model_Image" alt="Model Image" src="@Url.Action(MVC.API.DeviceModel.Image(Model.Device.DeviceModelId, Model.Device.DeviceModel.ImageHash()))" />
</div>
</div>
</td>
</tr>
<tr id="Device_Show_Subjects_Actions">
<td id="Device_Show_Device_Actions">
@if (Model.Device.CanCreateJob())
{
Html.BundleDeferred("~/ClientScripts/Modules/Disco-CreateJob");
@Html.ActionLinkSmallButton("Create Job", MVC.Job.Create(Model.Device.SerialNumber, Model.Device.AssignedUserId), "buttonCreateJob")
}
@if (Model.Device.CanUpdateAssignment())
{
<a id="Device_Show_User_Actions_Assign_Button" href="#" class="button small">Update Assignment</a>
<div id="Device_Show_User_Actions_Assign_Dialog" class="dialog" title="Assign this Device?">
<h4><i class="fa fa-info-circle information"></i>&nbsp;Assign to User:</h4>
<br />
@using (Html.BeginForm(MVC.API.Device.UpdateAssignedUserId(Model.Device.SerialNumber, redirect: true)))
{
@Html.AntiForgeryToken()
<input id="Device_Show_User_Actions_Assign_UserId" name="AssignedUserId" type="text" />
}
</div>
<script type="text/javascript">
$(function () {
var button = $('#Device_Show_User_Actions_Assign_Button');
var buttonDialog = null;
var inputUserId = null;
var dialogButtons = {
@{
if (assignedUser != null)
{
<text>
"Unassign": function () {
var $this = $(this);
$this.dialog("disable");
$this.dialog("option", "buttons", null);
inputUserId.val('');
inputUserId.closest('form').submit()
},
</text>
}
}
"Assign": function () {
var $this = $(this);
var userId = inputUserId.val();
if (userId) {
$this.dialog("disable");
$this.dialog("option", "buttons", null);
inputUserId.closest('form').submit()
} else {
alert('Enter a user to assign this device');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
button.click(function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_User_Actions_Assign_Dialog')
.dialog({
resizable: false,
height: 180,
modal: true,
autoOpen: false,
buttons: dialogButtons
});
inputUserId = $('#Device_Show_User_Actions_Assign_UserId');
inputUserId.focus(function () { inputUserId.select() })
.autocomplete({
source: '@(Url.Action(MVC.API.Search.UsersUpstream()))',
minLength: 2,
select: function (e, ui) {
inputUserId.val(ui.item.Id);
return false;
}
});
inputUserId.data('ui-autocomplete')._renderItem = function (ul, item) {
return $("<li>")
.data("item.autocomplete", item)
.append("<a><strong>" + item.DisplayName + "</strong><br>" + item.Id + " (" + item.Type + ")</a>")
.appendTo(ul);
};
}
buttonDialog.dialog('open');
inputUserId.focus();
return false;
});
});
</script>
}
@if (Model.Device.CanAddDeviceFlags() && Model.AvailableDeviceFlags != null && Model.AvailableDeviceFlags.Count > 0)
{
@Html.ActionLinkSmallButton("Add Flag", MVC.API.DeviceFlagAssignment.AddDevice(), "Device_Show_Details_Actions_AddFlag_Button")
<div id="Device_Show_Details_Actions_AddFlag_Dialog" class="dialog" title="Add Device Flag">
@using (Html.BeginForm(MVC.API.DeviceFlagAssignment.AddDevice()))
{
<input id="Device_Show_Details_Actions_AddFlag_Dialog_Id" type="hidden" name="id" />
<input id="Device_Show_Details_Actions_AddFlag_Dialog_DeviceSerialNumber" type="hidden" name="DeviceSerialNumber" value="@Model.Device.SerialNumber" />
<div class="flagPicker">
<input id="Device_Show_Details_Actions_AddFlag_Dialog_Filter" type="text" placeholder="Filter" autocomplete="off" />
@foreach (var flag in Model.AvailableDeviceFlags.OrderBy(jq => jq.Name))
{
<div class="flag" data-flagid="@(flag.Id)" data-flagname="@flag.Name">
<i class="fa fa-@(flag.Icon) fa-fw fa-lg d-@(flag.IconColour)"></i>@flag.Name
</div>
}
</div>
<div class="details">
<div>
<h4>Comments</h4>
<textarea name="Comments" id="Device_Show_Details_Actions_AddFlag_Dialog_Comments"></textarea>
</div>
</div>
}
</div>
<script type="text/javascript">
$(function () {
const button = $('#Device_Show_Details_Actions_AddFlag_Button');
let buttonDialog = null;
const buttonLink = button.attr('href');
let flagPicker = null;
let flagAddId = null;
let flagAddComments = null;
let details = null;
function flagSelected() {
const flag = $(this);
flagPicker.children().removeClass('selected');
flag.addClass('selected');
flagAddId.val(flag.attr('data-flagid'));
details.show();
flagAddComments.focus().select();
}
button.attr('href', '#').click(function (e) {
e.preventDefault();
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Details_Actions_AddFlag_Dialog');
buttonDialog.dialog({
width: 600,
height: 410,
resizable: false,
modal: true,
autoOpen: false,
buttons: {
Cancel: function () {
$(this).dialog("close");
},
"Add Flag": function () {
if (!!flagAddId.val()) {
const $this = $(this);
$this.dialog("disable");
$this.dialog("option", "buttons", null);
buttonDialog.find('form').submit();
} else {
alert('Select a Device Flag');
}
}
}
});
flagAddId = $('#Device_Show_Details_Actions_AddFlag_Dialog_Id');
flagAddComments = buttonDialog.find('#Device_Show_Details_Actions_AddFlag_Dialog_Comments');
flagPicker = buttonDialog.find('.flagPicker');
details = buttonDialog.find('.details');
$('#Device_Show_Details_Actions_AddFlag_Dialog_Filter').on('keyup', function (e) {
const filter = $(e.currentTarget).val().toLowerCase();
if (filter) {
flagPicker.children('div.flag').each(function () {
const $this = $(this);
if ($this.attr('data-flagname').toLowerCase().indexOf(filter) >= 0) {
$this.css('display', 'block');
} else {
$this.css('display', 'none');
}
});
} else {
flagPicker.children('div.flag').each(function () { $(this).css('display', 'block'); });
}
});
flagPicker.on('click', 'div.flag', flagSelected);
}
$('#Device_Show_Details_Actions_AddFlag_Dialog_Filter').val('');
buttonDialog.dialog('open');
return false;
});
});
</script>
}
@if (Model.Device.CanUpdateTrustEnrol())
{
<button id="Device_Show_Device_Actions_TrustEnrol_Button" type="button" class="button small">Trust Enrol</button>
<div id="Device_Show_Device_Actions_TrustEnrol_Dialog" class="dialog" title="Trust this Device?">
@using (Html.BeginForm(MVC.API.Device.UpdateAllowUnauthenticatedEnrol(Model.Device.SerialNumber, true.ToString(), true)))
{
@Html.AntiForgeryToken()
}
<p>
Devices flagged as 'trusted' are allowed a single-use device enrolment without providing authentication (for example: Active Directory Computer Account).
</p>
<p>
Once a device enrols, its trust setting is reset and additional enrolments need to be authenticated (domain joined) or manually trusted again.
</p>
<div class="info-box" style="margin-top: 1em;">
<p class="fa-p" style="margin-bottom: 1em;">
<i class="fa fa-exclamation-triangle"></i>This action will allow a device <em>claiming</em> to have the Serial Number '@(Model.Device.SerialNumber)' to be enrolled without authentication.
</p>
<div>
<strong>Are you sure you want to allow an unauthenticated enrolment?</strong>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
let buttonDialog;
$('#Device_Show_Device_Actions_TrustEnrol_Button').click(function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Device_Actions_TrustEnrol_Dialog').dialog({
resizable: false,
width: 400,
modal: true,
autoOpen: false,
buttons: {
"Trust": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
});
});
</script>
}
@if (Model.Device.CanUpdateUntrustEnrol())
{
<button id="Device_Show_Device_Actions_UntrustEnrol_Button" type="button" class="button small">Untrust Enrol</button>
<div id="Device_Show_Device_Actions_UntrustEnrol_Dialog" class="dialog" title="Untrust this Device?">
@using (Html.BeginForm(MVC.API.Device.UpdateAllowUnauthenticatedEnrol(Model.Device.SerialNumber, false.ToString(), true)))
{
@Html.AntiForgeryToken()
}
<div class="info-box">
<p class="fa-p" style="margin-bottom: 1em;">
<i class="fa fa-info-circle"></i>This action will require the device to enrol with authentication (for example: domain joined).
</p>
<div>
<strong>Are you sure you want to require an authenticated enrolment?</strong>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
let buttonDialog = null;
$('#Device_Show_Device_Actions_UntrustEnrol_Button').on('click', function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Device_Actions_UntrustEnrol_Dialog').dialog({
resizable: false,
width: 400,
modal: true,
autoOpen: false,
buttons: {
"Untrust": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
});
});
</script>
}
@if (Model.Device.CanDecommission())
{
<button id="Device_Show_Device_Actions_Decommission_Button" type="button" class="button small">Decommission</button>
<div id="Device_Show_Device_Actions_Decommission_Dialog" class="dialog" title="Device Decommissioning">
@using (Html.BeginForm(MVC.API.Device.Decommission(Model.Device.SerialNumber, null, true)))
{
@Html.AntiForgeryToken()
<div class="clearfix" style="margin-bottom: 10px;">
<i class="fa fa-question-circle fa-lg information"></i>&nbsp;Why is this device 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="Device_Show_Device_Actions_Decommission_Reason_@((int)decommissionReason)"
name="Reason" value="@((int)decommissionReason)" @((decommissionReason == DecommissionReasons.EndOfLife) ? "checked=\"checked\"" : string.Empty) />
<label for="Device_Show_Device_Actions_Decommission_Reason_@((int)decommissionReason)">@(decommissionReason.ReasonMessage())</label>
</li>
}
</ul>
</div>
}
</div>
<script type="text/javascript">
$(function () {
var buttonDialog = null;
$('#Device_Show_Device_Actions_Decommission_Button').on('click', function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Device_Actions_Decommission_Dialog')
.dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
"Decommission": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
});
});
</script>
}
@if (Model.Device.CanRecommission())
{
<button id="Device_Show_Device_Actions_Recommission_Button" type="button" class="button small">Recommission</button>
<div id="Device_Show_Device_Actions_Recommission_Dialog" class="dialog" title="Recommission this Device?">
@using (Html.BeginForm(MVC.API.Device.Recommission(Model.Device.SerialNumber, true)))
{
@Html.AntiForgeryToken()
}
<p>
<i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
</p>
</div>
<script type="text/javascript">
$(function () {
let buttonDialog = null;
$('#Device_Show_Device_Actions_Recommission_Button').on('click', function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Device_Actions_Recommission_Dialog').dialog({
resizable: false,
height: 140,
modal: true,
autoOpen: false,
buttons: {
"Recommission": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
});
});
</script>
}
@if (Model.Device.CanDelete())
{
<button id="Device_Show_Device_Actions_Delete_Button" type="button" class="button small">Delete Device</button>
<div id="Device_Show_Device_Actions_Delete_Dialog" class="dialog" title="Delete this Device?">
@using (Html.BeginForm(MVC.API.Device.Delete(Model.Device.SerialNumber, true)))
{
@Html.AntiForgeryToken()
}
<p>
<i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;
This item will be permanently deleted and cannot be recovered.<br />
Jobs linked to this Device (but not to a User) will be deleted also.<br />
Are you sure?
</p>
</div>
<script type="text/javascript">
$(function () {
let buttonDialog = null;
$('#Device_Show_Device_Actions_Delete_Button').on('click', function () {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Device_Actions_Delete_Dialog').dialog({
resizable: false,
height: 200,
modal: true,
autoOpen: false,
buttons: {
"Delete": function () {
$(this)
.dialog("option", "buttons", null)
.find('form').trigger('submit');
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
buttonDialog.dialog('open');
});
});
</script>
}
</td>
</tr>
</table>