1022 lines
54 KiB
Plaintext
1022 lines
54 KiB
Plaintext
@model Disco.Web.Areas.Config.Models.DeviceProfile.ShowModel
|
|
@using Disco.Services.Devices.ManagedGroups;
|
|
@using Disco.Web.Areas.Config.Models.Shared;
|
|
@{
|
|
Authorization.Require(Claims.Config.DeviceProfile.Show);
|
|
|
|
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Device Profiles", MVC.Config.DeviceProfile.Index(null), Model.DeviceProfile.ToString());
|
|
|
|
var canConfig = Authorization.Has(Claims.Config.DeviceProfile.Configure);
|
|
var canConfigExpression = Authorization.Has(Claims.Config.DeviceProfile.ConfigureComputerNameTemplate);
|
|
var canDelete = (Authorization.Has(Claims.Config.DeviceProfile.Delete) && Model.CanDelete);
|
|
var canViewPlugins = Authorization.Has(Claims.Config.Plugin.Install);
|
|
|
|
var hideAdvanced =
|
|
Model.DeviceProfile.AssignedUsersLinkedGroup == null &&
|
|
Model.DeviceProfile.DevicesLinkedGroup == null;
|
|
|
|
if (canConfig)
|
|
{
|
|
Html.BundleDeferred("~/Style/Fancytree");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-Fancytree");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers");
|
|
}
|
|
}
|
|
<div id="configurationDeviceProfileShow" class="form@(hideAdvanced ? " Config_HideAdvanced" : null)" style="width: 640px">
|
|
<table>
|
|
<tr>
|
|
<th style="width: 170px;">
|
|
Id:
|
|
</th>
|
|
<td>
|
|
@Html.DisplayFor(model => model.DeviceProfile.Id)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Name:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
@Html.TextBoxFor(model => model.DeviceProfile.Name)
|
|
@AjaxHelpers.AjaxSave()
|
|
@AjaxHelpers.AjaxLoader()
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_Name'),
|
|
'Name',
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateName(Model.DeviceProfile.Id))',
|
|
'ProfileName'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
@Model.DeviceProfile.Name
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Short Name:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
@Html.TextBoxFor(model => model.DeviceProfile.ShortName)
|
|
@AjaxHelpers.AjaxSave()
|
|
@AjaxHelpers.AjaxLoader()
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_ShortName'),
|
|
'Short Name',
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateShortName(Model.DeviceProfile.Id))',
|
|
'ShortName'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
@Model.DeviceProfile.ShortName
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Description:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
@Html.EditorFor(model => model.DeviceProfile.Description)
|
|
@AjaxHelpers.AjaxSave()
|
|
@AjaxHelpers.AjaxLoader()
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_Description'),
|
|
'Description',
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateDescription(Model.DeviceProfile.Id))',
|
|
'Description'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
@Model.DeviceProfile.Description
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Members</th>
|
|
<td>
|
|
<div><strong>@Model.DeviceCount.ToString("n0")</strong> @(Model.DeviceCount == 1 ? "devices is a member" : "devices are members") of this profile.</div>
|
|
@if (Model.DeviceDecommissionedCount > 0)
|
|
{
|
|
<div class="smallMessage">@Model.DeviceDecommissionedCount.ToString("n0") @(Model.DeviceDecommissionedCount == 1 ? "device is" : "devices are") decommissioned.</div>
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Distribution Type:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
@Html.DropDownList("DeviceProfile_DistributionType", Model.DeviceProfileDistributionTypes)
|
|
@AjaxHelpers.AjaxLoader()
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_DistributionType'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateDistributionType(Model.DeviceProfile.Id))',
|
|
'DistributionType'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
@Model.DeviceProfile.DistributionType.ToString()
|
|
}
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>One-to-many devices are typically shared.
|
|
One-to-one devices are typically assigned to a user;
|
|
enrolment with a one-to-one device isn't considered complete until it is assigned.
|
|
</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Address:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
@Html.DropDownListFor(m => m.DeviceProfile.DefaultOrganisationAddress, Model.OrganisationAddresses.ToSelectListItems(Model.DeviceProfile.DefaultOrganisationAddress, true, "None"))
|
|
@AjaxHelpers.AjaxLoader()
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_DefaultOrganisationAddress'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateDefaultOrganisationAddress(Model.DeviceProfile.Id))',
|
|
'DefaultOrganisationAddress'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
if (Model.DefaultOrganisationAddress == null)
|
|
{
|
|
<span class="smallMessage"><None Specified></span>
|
|
}
|
|
else
|
|
{
|
|
@Model.DefaultOrganisationAddress.ToString()
|
|
}
|
|
}
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>The profile address is used to separate jobs for <a href="@Url.Action(MVC.Config.Organisation.Index())">multi-site mode</a>.
|
|
It is also suggested as the default address for warranty/repair actions.
|
|
</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Policies</th>
|
|
<td>
|
|
<div>
|
|
@if (canConfig)
|
|
{
|
|
<input id="DeviceProfile_ProvisionADAccount" type="checkbox" @(Model.DeviceProfile.ProvisionADAccount ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) />
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_ProvisionADAccount'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateProvisionADAccount(Model.DeviceProfile.Id))',
|
|
'ProvisionADAccount'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<input id="DeviceProfile_ProvisionADAccount" type="checkbox" @(Model.DeviceProfile.ProvisionADAccount ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) disabled="disabled" />
|
|
}
|
|
<label for="DeviceProfile_ProvisionADAccount">
|
|
Provision Active Directory Account
|
|
</label>
|
|
@AjaxHelpers.AjaxLoader()
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>When enabled an Active Directory account will be provisioned for the device when enrolment occurs
|
|
and the device will be joined to the domain (refer to the <code>Computer Name Template Expression</code> and the
|
|
<code>Organisational Unit</code> configuration options below).
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 8px;">
|
|
@if (canConfig)
|
|
{
|
|
<input id="DeviceProfile_AssignedUserLocalAdmin" type="checkbox" @(Model.DeviceProfile.AssignedUserLocalAdmin ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) />
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_AssignedUserLocalAdmin'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateAssignedUserLocalAdmin(Model.DeviceProfile.Id))',
|
|
'AssignedUserLocalAdmin'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<input id="DeviceProfile_AssignedUserLocalAdmin" type="checkbox" @(Model.DeviceProfile.AssignedUserLocalAdmin ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) disabled="disabled" />
|
|
}
|
|
<label for="DeviceProfile_AssignedUserLocalAdmin">
|
|
Assigned User is Local Administrator
|
|
</label>
|
|
@AjaxHelpers.AjaxLoader()
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>When enabled the user assigned to the device will be added to the <code>Local Administrators</code> group during device enrolment.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 8px;">
|
|
@if (canConfig)
|
|
{
|
|
<input id="DeviceProfile_AllowUntrustedReimageJobEnrolment" type="checkbox" @(Model.DeviceProfile.AllowUntrustedReimageJobEnrolment ? new MvcHtmlString("checked=\"checked\" ") : null) />
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_AllowUntrustedReimageJobEnrolment'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateAllowUntrustedReimageJobEnrolment(Model.DeviceProfile.Id))',
|
|
'AllowUntrustedReimageJobEnrolment'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<input id="DeviceProfile_AllowUntrustedReimageJobEnrolment" type="checkbox" @(Model.DeviceProfile.AllowUntrustedReimageJobEnrolment ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) disabled="disabled" />
|
|
}
|
|
<label for="DeviceProfile_AllowUntrustedReimageJobEnrolment">
|
|
Allow Untrusted Enrolment Where a <span class="code">'Software - Reimage'</span> Job is Open
|
|
</label>
|
|
@AjaxHelpers.AjaxLoader()
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>When enabled an untrusted device enrolment will be allowed if a <code>Software - Reimage</code> job is open for the device.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Computer Name<br />
|
|
Template Expression:
|
|
</th>
|
|
<td>
|
|
<div id="displayComputerNameTemplate" class="code">
|
|
@if (string.IsNullOrWhiteSpace(Model.DeviceProfile.ComputerNameTemplate))
|
|
{
|
|
<span class="smallMessage"><None Specified></span>
|
|
}
|
|
else
|
|
{
|
|
@Model.DeviceProfile.ComputerNameTemplate
|
|
}
|
|
</div>
|
|
@if (canConfig && canConfigExpression)
|
|
{
|
|
<a id="changeComputerNameTemplate" href="#" class="button small">Change</a>@AjaxHelpers.AjaxLoader()
|
|
<div id="dialogComputerNameTemplate" title="Computer Name Template" class="dialog">
|
|
@using (Html.BeginForm(MVC.API.DeviceProfile.UpdateComputerNameTemplate(Model.DeviceProfile.Id, null, false)))
|
|
{
|
|
@Html.AntiForgeryToken()
|
|
@Html.TextArea("ComputerNameTemplate", Model.DeviceProfile.ComputerNameTemplate, new { spellcheck = "false", required = "required" })
|
|
}
|
|
<div class="hidden info-box error code whitespace-pre-wrap">
|
|
</div>
|
|
<div class="test hidden">
|
|
@using (Html.BeginForm(MVC.API.DeviceProfile.TestComputerNameTemplate(Model.DeviceProfile.Id)))
|
|
{
|
|
@Html.AntiForgeryToken();
|
|
<table class="genericData">
|
|
<thead>
|
|
<tr>
|
|
<th>Serial Number</th>
|
|
<th>Current</th>
|
|
<th>Result</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<input id="ComputerNameTemplateTestSearch" name="UserSpecifiedDeviceSerialNumber" type="text" placeholder="Device Serial Number" spellcheck="false" />
|
|
</td>
|
|
<td> </td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
}
|
|
</div>
|
|
<button id="ComputerNameTemplateTest" class="button small" type="button">Test Template</button>@AjaxHelpers.AjaxLoader()
|
|
</div>
|
|
<script type="text/javascript">
|
|
$(() => {
|
|
let $dialog = null;
|
|
let $textarea = null;
|
|
let currentValue = null;
|
|
|
|
$('#changeComputerNameTemplate').click(e => {
|
|
e.preventDefault();
|
|
|
|
if (!$dialog) {
|
|
$textarea = $('#ComputerNameTemplate');
|
|
currentValue = $textarea.val();
|
|
$dialog = $('#dialogComputerNameTemplate').dialog({
|
|
autoOpen: false,
|
|
buttons: null,
|
|
draggable: false,
|
|
modal: true,
|
|
resizable: false,
|
|
width: 700,
|
|
buttons: {
|
|
"Cancel": () => {
|
|
$textarea.val(currentValue);
|
|
$dialog.find('.error').addClass('hidden');
|
|
$dialog.dialog("close");
|
|
},
|
|
"Expression Browser": () => {
|
|
window.open('@(Url.Action(MVC.Config.Expressions.Browser()))', '_blank');
|
|
},
|
|
"Save": () => {
|
|
const $form = $textarea.closest('form');
|
|
$(this).find('.error').addClass('hidden');
|
|
|
|
if ($form[0].reportValidity()) {
|
|
const body = new FormData($form[0]);
|
|
const url = $form.attr('action');
|
|
|
|
const $ajaxLoading = $('#changeComputerNameTemplate').nextAll('.ajaxLoading').first();
|
|
$ajaxLoading.show();
|
|
$dialog.dialog('close');
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: body
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
currentValue = $textarea.val();
|
|
const $display = $('#displayComputerNameTemplate');
|
|
if (currentValue) {
|
|
$display.text(currentValue);
|
|
} else {
|
|
$display.html('<span class="smallMessage"><None Specified></span>');
|
|
}
|
|
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
} else if (response.status == 400) {
|
|
response.json().then(data => {
|
|
$ajaxLoading.hide();
|
|
$dialog.dialog('open');
|
|
$dialog.find('.error').text(data).removeClass('hidden');
|
|
console.error(data);
|
|
})
|
|
}
|
|
}).catch(error => {
|
|
alert('Unable to save computer name template');
|
|
$ajaxLoading.hide();
|
|
$dialog.dialog('open');
|
|
$dialog.find('.error').text('Unable to save computer name template: ' + error).removeClass('hidden');
|
|
console.error(error);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
const $buttonTest = $dialog.find('#ComputerNameTemplateTest');
|
|
$buttonTest.click(e => {
|
|
e.preventDefault();
|
|
const $test = $dialog.find('.test');
|
|
|
|
const $ajaxLoading = $(e.currentTarget).nextAll('.ajaxLoading').first();
|
|
$ajaxLoading.show();
|
|
|
|
const $form = $test.find('form');
|
|
const url = $form.attr('action');
|
|
const body = new FormData($form[0]);
|
|
body.append('ComputerNameTemplate', $textarea.val());
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: body
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
response.json().then(data => {
|
|
const $table = $test.find('table tbody');
|
|
if (data.UserSpecifiedResult) {
|
|
const result = data.UserSpecifiedResult;
|
|
const row = $table.find('tr').first();
|
|
row.find('input').val(result.DeviceSerialNumber);
|
|
const columns = row.find('td');
|
|
columns.eq(1).html('');
|
|
$('<span class="code">').text(result.DeviceComputerName)
|
|
.appendTo(columns.eq(1))
|
|
columns.eq(2).html('');
|
|
$('<span class="code">').text(result.RenderedComputerName)
|
|
.appendTo(columns.eq(2))
|
|
if (!result.Success) {
|
|
$('<div class="info-box error code whitespace-pre-wrap">').text(result.ErrorMessage).appendTo(columns[2]);
|
|
}
|
|
}
|
|
if (data.RandomDeviceResults) {
|
|
$table.find('tr').slice(1).remove();
|
|
for (var i = 0; i < data.RandomDeviceResults.length; i++) {
|
|
const result = data.RandomDeviceResults[i];
|
|
const row = $('<tr><td></td><td></td><td></td></tr>');
|
|
const columns = row.find('td');
|
|
$('<a>').attr({
|
|
href: result.Url,
|
|
target: '_blank'
|
|
}).text(result.DeviceSerialNumber)
|
|
.appendTo(columns.eq(0));
|
|
$('<span class="code">').text(result.DeviceComputerName)
|
|
.appendTo(columns.eq(1))
|
|
$('<span class="code">').text(result.RenderedComputerName)
|
|
.appendTo(columns.eq(2))
|
|
if (!result.Success) {
|
|
$('<div class="info-box error code whitespace-pre-wrap">').text(result.ErrorMessage).appendTo(columns.eq(2));
|
|
}
|
|
row.appendTo($table);
|
|
}
|
|
}
|
|
$test.removeClass('hidden');
|
|
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
});
|
|
} else if (response.status == 400) {
|
|
response.json().then(data => {
|
|
$ajaxLoading.hide();
|
|
$test.addClass('hidden');
|
|
$dialog.find('.error').text(data).removeClass('hidden');
|
|
console.error(data);
|
|
})
|
|
}
|
|
}).catch(error => {
|
|
$ajaxLoading.hide();
|
|
$test.addClass('hidden');
|
|
$dialog.find('.error').text('Unable to test computer name template: ' + error).removeClass('hidden');
|
|
console.error(error);
|
|
});
|
|
|
|
return false;
|
|
})
|
|
const $testSearchText = $dialog.find('#ComputerNameTemplateTestSearch');
|
|
$testSearchText.autocomplete({
|
|
source: '@(Url.Action(MVC.API.Search.Devices()))',
|
|
minLength: 2,
|
|
focus: function (e, ui) {
|
|
$testSearchText.val(ui.item.Id);
|
|
return false;
|
|
},
|
|
select: function (e, ui) {
|
|
$testSearchText.val(ui.item.Id).blur();
|
|
$buttonTest.click();
|
|
return false;
|
|
}
|
|
}).data('ui-autocomplete')._renderItem = function (ul, item) {
|
|
return $('<li>')
|
|
.data('item.autocomplete', item)
|
|
.append($('<a>').text(item.Description))
|
|
.appendTo(ul);
|
|
};
|
|
}
|
|
$dialog.dialog('open');
|
|
|
|
return false;
|
|
});
|
|
});
|
|
</script>
|
|
}
|
|
<div style="margin-top: 8px;">
|
|
@if (canConfig)
|
|
{
|
|
<input id="DeviceProfile_EnforceComputerNameConvention" type="checkbox" @(Model.DeviceProfile.EnforceComputerNameConvention ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) />
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_EnforceComputerNameConvention'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateEnforceComputerNameConvention(Model.DeviceProfile.Id))',
|
|
'EnforceComputerNameConvention'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<input id="DeviceProfile_EnforceComputerNameConvention" type="checkbox" @(Model.DeviceProfile.EnforceComputerNameConvention ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) disabled="disabled" />
|
|
}
|
|
<label for="DeviceProfile_EnforceComputerNameConvention">
|
|
Enforce Naming Convention
|
|
</label>
|
|
@AjaxHelpers.AjaxLoader()
|
|
</div>
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>Computer names are only changed when Active Directory accounts are provisioned.
|
|
If the device has already joined the domain when enrolment occurs the name will remain the same unless Enforce Naming Convention is enabled.
|
|
</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Organisational Unit:
|
|
</th>
|
|
<td>
|
|
@if (canConfig)
|
|
{
|
|
<div id="DeviceProfile_OrganisationalUnit" class="code" data-value="@Model.DeviceProfile.OrganisationalUnit">
|
|
<span>
|
|
@Model.FriendlyOrganisationalUnitName
|
|
</span>
|
|
</div>
|
|
<a id="changeOrganisationalUnit" href="#" class="button small">Change</a>@AjaxHelpers.AjaxLoader()
|
|
<div id="dialogOrganisationalUnit" title="Organisational Unit" class="dialog">
|
|
<div id="dialogOrganisationalUnit_Loading">
|
|
@AjaxHelpers.AjaxLoader() Loading Organisational Units
|
|
</div>
|
|
<div id="treeOrganisationalUnit" class="organisationalUnitTree">
|
|
</div>
|
|
@using (Html.BeginForm(MVC.API.DeviceProfile.UpdateOrganisationalUnit(Model.DeviceProfile.Id, redirect: true), FormMethod.Post))
|
|
{
|
|
@Html.AntiForgeryToken();
|
|
<input type="hidden" name="OrganisationalUnit" />
|
|
<div class="enforceOrganisationalUnit">
|
|
<input id="enforceOrganisationalUnit" type="checkbox" name="enforce" value="true" /> <label for="enforceOrganisationalUnit">Move all profile devices to this organisational unit</label>
|
|
</div>
|
|
}
|
|
</div>
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
var ouValue = $('#DeviceProfile_OrganisationalUnit').attr('data-value');
|
|
var $ouTree = null;
|
|
var ouTree = null;
|
|
var $dialog = null;
|
|
var $enforceCheckbox;
|
|
var ouSet = function (ou) {
|
|
const $form = $dialog.find('form');
|
|
$form.find('input[name="OrganisationalUnit"]').val(ou);
|
|
$form.submit();
|
|
}
|
|
var expandNodeTree = function (node) {
|
|
var parent = node.parent;
|
|
if (parent) {
|
|
expandNodeTree(parent);
|
|
parent.setExpanded(true, { noAnimation: true, noEvents: false });
|
|
}
|
|
}
|
|
var expandAndFocusNode = function (nodeKey) {
|
|
if (ouTree) {
|
|
var ouNode = ouTree.getNodeByKey(ouValue);
|
|
if (ouNode) {
|
|
expandNodeTree(ouNode);
|
|
ouNode.setFocus(true);
|
|
ouNode.setActive(true);
|
|
|
|
var li = ouNode.li;
|
|
var liOffset = li.offsetParent;
|
|
if (li.offsetTop + li.offsetHeight > liOffset.offsetHeight)
|
|
$(liOffset).animate({ 'scrollTop': li.offsetTop - liOffset.offsetHeight + li.offsetHeight + 4 }, 'fast');
|
|
}
|
|
}
|
|
}
|
|
var ouChange = function () {
|
|
if (!$dialog) {
|
|
$dialog = $('#dialogOrganisationalUnit').dialog({
|
|
autoOpen: false,
|
|
buttons: null,
|
|
draggable: false,
|
|
modal: true,
|
|
resizable: false,
|
|
width: 500,
|
|
height: 500
|
|
});
|
|
$loading = $('#dialogOrganisationalUnit_Loading');
|
|
$loading.find('i.ajaxLoading').show();
|
|
|
|
$ouTree = $('#treeOrganisationalUnit');
|
|
$dialog.css('overflow', 'visible');
|
|
|
|
$enforceCheckbox = $('#enforceOrganisationalUnit');
|
|
|
|
$.getJSON('@(Url.Action(MVC.API.System.DomainOrganisationalUnits()))', null, function (data) {
|
|
$loading.hide();
|
|
|
|
// Make 'Domains' unselectable
|
|
$.each(data, function (i, node) {
|
|
node.unselectable = true;
|
|
});
|
|
|
|
ouTree = $ouTree.fancytree({
|
|
source: data,
|
|
checkbox: false,
|
|
selectMode: 1,
|
|
keyboard: false,
|
|
fx: null
|
|
}).fancytree('getTree');
|
|
|
|
ouTree.$container.css('position', 'relative');
|
|
|
|
// Set Buttons
|
|
$dialog.dialog('option', 'buttons', {
|
|
'Use Default Computers Container': function () {
|
|
var $this = $(this);
|
|
$this.css('overflow', 'hidden');
|
|
$this.dialog("disable");
|
|
$this.dialog("option", "buttons", null);
|
|
ouSet('');
|
|
},
|
|
'Save': function () {
|
|
var node = ouTree.getActiveNode();
|
|
if (node && node.key.substr(0, 3).toLowerCase() == 'ou=') {
|
|
var $this = $(this);
|
|
$this.css('overflow', 'hidden');
|
|
$this.dialog("disable");
|
|
$this.dialog("option", "buttons", null);
|
|
ouSet(node.key);
|
|
} else {
|
|
alert('Select an Organisational Unit to Save')
|
|
}
|
|
}
|
|
});
|
|
|
|
// Expand
|
|
expandAndFocusNode(ouValue);
|
|
|
|
ouTree.options.fx = { height: "toggle", duration: 200 };
|
|
});
|
|
}
|
|
$dialog.dialog('open');
|
|
|
|
$enforceCheckbox.prop('checked', $('#DeviceProfile_EnforceOrganisationalUnit').prop('checked'));
|
|
|
|
if (ouTree) {
|
|
// Expand
|
|
expandAndFocusNode(ouValue);
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
$('#changeOrganisationalUnit').click(ouChange);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<div id="displayOrganisationalUnit" class="code">
|
|
<span>
|
|
@Model.FriendlyOrganisationalUnitName
|
|
</span>
|
|
</div>
|
|
}
|
|
@if (!Model.OrganisationalUnitExists)
|
|
{
|
|
<div class="info-box error">
|
|
<p class="fa-p">
|
|
<i class="fa fa-exclamation-triangle"></i>The Organisational Unit could not be found.
|
|
</p>
|
|
</div>
|
|
}
|
|
<div style="margin-top: 8px;">
|
|
@if (canConfig)
|
|
{
|
|
<input id="DeviceProfile_EnforceOrganisationalUnit" type="checkbox" @(Model.DeviceProfile.EnforceOrganisationalUnit ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) />
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper(
|
|
$('#DeviceProfile_EnforceOrganisationalUnit'),
|
|
null,
|
|
'@Url.Action(MVC.API.DeviceProfile.UpdateEnforceOrganisationalUnit(Model.DeviceProfile.Id))',
|
|
'EnforceOrganisationalUnit'
|
|
);
|
|
});
|
|
</script>
|
|
}
|
|
else
|
|
{
|
|
<input id="DeviceProfile_EnforceOrganisationalUnit" type="checkbox" @(Model.DeviceProfile.EnforceOrganisationalUnit ? new MvcHtmlString("checked=\"checked\" ") : new MvcHtmlString(string.Empty)) disabled="disabled" />
|
|
}
|
|
<label for="DeviceProfile_EnforceOrganisationalUnit">
|
|
Enforce Organisational Unit
|
|
</label>
|
|
@AjaxHelpers.AjaxLoader()
|
|
</div>
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>When an Active Directory account is provisioned it will be placed in this container. This typically occurs
|
|
at device enrolment. If the device has already joined the domain and the <code>Enforce Organisational Unit</code> option is enabled
|
|
the Active Directory account will be moved into this organisational unit during enrolment.
|
|
</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Provision Certificates:
|
|
@if (canConfig && (Model.CertificateProviders.Count > 0 || Model.CertificateAuthorityProviders.Count > 0))
|
|
{
|
|
<br />
|
|
@AjaxHelpers.AjaxLoader("DeviceProfile_CertificateProviders")
|
|
}
|
|
@if (canConfig && Model.CertificateProviders.Count > 0)
|
|
{
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
var $container = $('#DeviceProfile_CertificateProviders');
|
|
|
|
$container.on('change', 'input', function () {
|
|
var $ajaxLoading = $('#DeviceProfile_CertificateProviders_loading').show();
|
|
|
|
var data = {
|
|
CertificateProviders: $('input:checked', $container).map(function () { return $(this).val() }).get().join(',')
|
|
};
|
|
$.getJSON('@(Url.Action(MVC.API.DeviceProfile.UpdateCertificateProviders(Model.DeviceProfile.Id)))', data, function (response, result) {
|
|
if (result != 'success' || response != 'OK') {
|
|
alert('Unable to change property "CertificateProviders":\n' + response);
|
|
$ajaxLoading.hide();
|
|
} else {
|
|
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
}
|
|
})
|
|
})
|
|
});
|
|
</script>
|
|
}
|
|
@if (canConfig && Model.CertificateProviders.Count > 0)
|
|
{
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
var $container = $('#DeviceProfile_CertificateAuthorityProviders');
|
|
|
|
$container.on('change', 'input', function () {
|
|
var $ajaxLoading = $('#DeviceProfile_CertificateProviders_loading').show();
|
|
|
|
var data = {
|
|
CertificateAuthorityProviders: $('input:checked', $container).map(function () { return $(this).val() }).get().join(',')
|
|
};
|
|
$.getJSON('@(Url.Action(MVC.API.DeviceProfile.UpdateCertificateAuthorityProviders(Model.DeviceProfile.Id)))', data, function (response, result) {
|
|
if (result != 'success' || response != 'OK') {
|
|
alert('Unable to change property "CertificateAuthorityProviders":\n' + response);
|
|
$ajaxLoading.hide();
|
|
} else {
|
|
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
}
|
|
})
|
|
})
|
|
});
|
|
</script>
|
|
}
|
|
</th>
|
|
<td>
|
|
<h4>Device/Machine Certificates</h4>
|
|
@if (canConfig && Model.CertificateProviders.Count > 0)
|
|
{
|
|
@CommonHelpers.CheckBoxList("DeviceProfile_CertificateProviders", "DeviceProfile_CertificateProviders", Model.CertificateProviders.ToSelectListItems(Model.DeviceProfile.GetCertificateProviders()))
|
|
}
|
|
else
|
|
{
|
|
var certificateProviders = Model.DeviceProfile.GetCertificateProviders().ToList();
|
|
|
|
if (certificateProviders.Count == 0)
|
|
{
|
|
<span class="smallMessage"><None Allocated></span>
|
|
}
|
|
else
|
|
{
|
|
<ul>
|
|
@foreach (var certificateProvider in certificateProviders)
|
|
{
|
|
<li>@certificateProvider.Name</li>
|
|
}
|
|
</ul>
|
|
}
|
|
}
|
|
<h4 style="margin-top: 4px;">Authority Certificates</h4>
|
|
@if (canConfig && Model.CertificateAuthorityProviders.Count > 0)
|
|
{
|
|
@CommonHelpers.CheckBoxList("DeviceProfile_CertificateAuthorityProviders", "DeviceProfile_CertificateAuthorityProviders", Model.CertificateAuthorityProviders.ToSelectListItems(Model.DeviceProfile.GetCertificateAuthorityProviders()))
|
|
}
|
|
else
|
|
{
|
|
var certificateProviders = Model.DeviceProfile.GetCertificateAuthorityProviders().ToList();
|
|
|
|
if (certificateProviders.Count == 0)
|
|
{
|
|
<span class="smallMessage"><None Allocated></span>
|
|
}
|
|
else
|
|
{
|
|
<ul>
|
|
@foreach (var certificateProvider in certificateProviders)
|
|
{
|
|
<li>@certificateProvider.Name</li>
|
|
}
|
|
</ul>
|
|
}
|
|
}
|
|
@if (canViewPlugins)
|
|
{
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>View the <a href="@(Url.Action(MVC.Config.Plugins.Install()))">Plugin Catalogue</a> to discover and install certificate provider plugins.
|
|
</p>
|
|
</div>
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
Provision Wireless Profiles:
|
|
@if (canConfig && Model.WirelessProfileProviders.Count > 0)
|
|
{
|
|
<br />
|
|
@AjaxHelpers.AjaxLoader("DeviceProfile_WirelessProfileProviders")
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
var $container = $('#DeviceProfile_WirelessProfileProviders');
|
|
|
|
$container.on('change', 'input', function () {
|
|
var $ajaxLoading = $('#DeviceProfile_WirelessProfileProviders_loading').show();
|
|
|
|
var data = {
|
|
WirelessProfileProviders: $('input:checked', $container).map(function () { return $(this).val() }).get().join(',')
|
|
};
|
|
$.getJSON('@(Url.Action(MVC.API.DeviceProfile.UpdateWirelessProfileProviders(Model.DeviceProfile.Id)))', data, function (response, result) {
|
|
if (result != 'success' || response != 'OK') {
|
|
alert('Unable to change property "WirelessProfileProviders":\n' + response);
|
|
$ajaxLoading.hide();
|
|
} else {
|
|
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
}
|
|
})
|
|
})
|
|
});
|
|
</script>
|
|
}
|
|
</th>
|
|
<td>
|
|
@if (canConfig && Model.WirelessProfileProviders.Count > 0)
|
|
{
|
|
@CommonHelpers.CheckBoxList("DeviceProfile_WirelessProfileProviders", "DeviceProfile_WirelessProfileProviders", Model.WirelessProfileProviders.ToSelectListItems(Model.DeviceProfile.GetWirelessProfileProviders()))
|
|
}
|
|
else
|
|
{
|
|
var wirelessProfileProviders = Model.DeviceProfile.GetWirelessProfileProviders().ToList();
|
|
|
|
if (wirelessProfileProviders.Count == 0)
|
|
{
|
|
<span class="smallMessage"><None Allocated></span>
|
|
}
|
|
else
|
|
{
|
|
<ul>
|
|
@foreach (var wirelessProfileProvider in wirelessProfileProviders)
|
|
{
|
|
<li>@wirelessProfileProvider.Name</li>
|
|
}
|
|
</ul>
|
|
}
|
|
}
|
|
@if (canViewPlugins)
|
|
{
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>View the <a href="@(Url.Action(MVC.Config.Plugins.Install()))">Plugin Catalogue</a> to discover and install wireless profile provider plugins.
|
|
</p>
|
|
</div>
|
|
}
|
|
</td>
|
|
</tr>
|
|
@if (hideAdvanced)
|
|
{
|
|
<tr>
|
|
<td colspan="2" style="text-align: right;">
|
|
<button id="Config_HideAdvanced_Show" class="button small">Show Advanced Options</button>
|
|
<script>
|
|
$(function () {
|
|
$('#Config_HideAdvanced_Show').click(function () {
|
|
var $this = $(this);
|
|
$this.closest('.Config_HideAdvanced').removeClass('Config_HideAdvanced');
|
|
$this.closest('tr').remove();
|
|
});
|
|
});
|
|
</script>
|
|
</td>
|
|
</tr>
|
|
}
|
|
<tr class="Config_HideAdvanced_Item">
|
|
<th>
|
|
Linked Groups:
|
|
</th>
|
|
<td>
|
|
<div>
|
|
@Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel()
|
|
{
|
|
CanConfigure = canConfig,
|
|
CategoryDescription = DeviceProfileDevicesManagedGroup.GetCategoryDescription(Model.DeviceProfile),
|
|
Description = DeviceProfileDevicesManagedGroup.GetDescription(Model.DeviceProfile),
|
|
ManagedGroup = Model.DevicesLinkedGroup,
|
|
UpdateUrl = Url.Action(MVC.API.DeviceProfile.UpdateDevicesLinkedGroup(Model.DeviceProfile.Id, redirect: true))
|
|
})
|
|
@Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel()
|
|
{
|
|
CanConfigure = canConfig,
|
|
CategoryDescription = DeviceProfileAssignedUsersManagedGroup.GetCategoryDescription(Model.DeviceProfile),
|
|
Description = DeviceProfileAssignedUsersManagedGroup.GetDescription(Model.DeviceProfile),
|
|
ManagedGroup = Model.AssignedUsersLinkedGroup,
|
|
UpdateUrl = Url.Action(MVC.API.DeviceProfile.UpdateAssignedUsersLinkedGroup(Model.DeviceProfile.Id, redirect: true))
|
|
})
|
|
@if (canConfig)
|
|
{
|
|
@Html.Partial(MVC.Config.Shared.Views.LinkedGroupShared)
|
|
}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
@if (canDelete)
|
|
{
|
|
<div id="dialogConfirmDelete" title="Delete this Device Profile?">
|
|
<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 () {
|
|
|
|
var button = $('#buttonDelete');
|
|
var buttonLink = button.attr('href');
|
|
button.attr('href', '#');
|
|
button.click(function () {
|
|
$("#dialogConfirmDelete").dialog('open');
|
|
});
|
|
|
|
$("#dialogConfirmDelete").dialog({
|
|
resizable: false,
|
|
height: 140,
|
|
modal: true,
|
|
autoOpen: false,
|
|
buttons: {
|
|
"Delete": function () {
|
|
$(this).dialog('disable');
|
|
window.location.href = buttonLink;
|
|
},
|
|
Cancel: function () {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|
|
</script>
|
|
}
|
|
@Html.Partial(MVC.Config.Shared.Views._DeviceGroupDocumentBulkGenerate, Model)
|
|
<div class="actionBar">
|
|
@if (canDelete)
|
|
{
|
|
@Html.ActionLinkButton("Delete", MVC.API.DeviceProfile.Delete(Model.DeviceProfile.Id, true), "buttonDelete")
|
|
}
|
|
@if (Authorization.Has(Claims.Device.Actions.Export))
|
|
{
|
|
@Html.ActionLinkButton("Export Devices", MVC.Device.Export(null, Disco.Models.Services.Devices.DeviceExportTypes.Profile, Model.DeviceProfile.Id))
|
|
}
|
|
@if (Authorization.Has(Claims.Device.Search) && Model.DeviceCount > 0)
|
|
{
|
|
@Html.ActionLinkButton(string.Format("View {0} Device{1}", Model.DeviceCount, (Model.DeviceCount != 1 ? "s" : null)), MVC.Search.Query(Model.DeviceProfile.Id.ToString(), "DeviceProfile"))
|
|
}
|
|
</div>
|