Files
Disco/Disco.Web/Areas/Config/Views/SystemConfig/Index.cshtml
T

1036 lines
46 KiB
Plaintext

@model Disco.Web.Areas.Config.Models.SystemConfig.IndexModel
@using Disco.Services.Interop.DiscoServices
@{
Authorization.Require(Claims.Config.System.Show);
var canConfigProxy = Authorization.Has(Claims.Config.System.ConfigureProxy);
var canConfigEmail = Authorization.Has(Claims.Config.System.ConfigureEmail);
var canConfigAD = Authorization.Has(Claims.Config.System.ConfigureActiveDirectory);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "System");
if (canConfigAD)
{
Html.BundleDeferred("~/Style/Fancytree");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-Fancytree");
Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers");
}
}
<div class="form" style="width: 450px">
<table>
<tr>
<th style="width: 135px">
Disco ICT Version:
</th>
<td>
<div>
<code>@Model.DiscoVersion.ToString(4)</code>
</div>
<div class="smallMessage">
Built @CommonHelpers.FriendlyDate(Model.DiscoVersionBuilt, "Unknown")
</div>
</td>
</tr>
<tr>
<th style="width: 135px">
Database Connection:
</th>
<td>
<table class="sub">
<tr>
<th>Server:</th>
<td><span class="code">@Model.DatabaseServer</span></td>
</tr>
<tr>
<th>Database:</th>
<td><span class="code">@Model.DatabaseName</span></td>
</tr>
<tr>
<th>Authentication:</th>
<td>@Model.DatabaseAuthentication</td>
</tr>
@{if (Model.DatabaseSqlAuthUsername != null)
{
<tr>
<th>SQL&nbsp;User:</th>
<td><span class="code">@Model.DatabaseSqlAuthUsername</span></td>
</tr>
}
}
</table>
</td>
</tr>
<tr>
<th style="width: 135px">
Data Store Location:
</th>
<td>
<span class="code">@Model.DataStoreLocation</span>
</td>
</tr>
</table>
</div>
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Activation &amp; License</h2>
<table>
<tr>
<th style="width: 135px">
Activation:
</th>
<td>
@if (Model.IsActivated)
{
@CommonHelpers.FriendlyDate(Model.ActivatedOn) <span>by @Model.ActivatedBy</span>
switch (Model.OnlineServicesState)
{
case OnlineServicesConnect.ConnectionState.Disconnected:
<div class="info-box error">
<p class="fa-p"><i class="fa fa-globe"></i> Disconnected from Online Services</p>
@using (Html.BeginForm(MVC.API.System.OnlineServicesConnectStart()))
{
@Html.AntiForgeryToken()
<button type="submit" class="button small">Connect</button>
}
</div>
break;
case OnlineServicesConnect.ConnectionState.Connected:
<div class="info-box success">
<p class="fa-p"><i class="fa fa-globe"></i> Connected to Online Services</p>
</div>
break;
case OnlineServicesConnect.ConnectionState.Connecting:
case OnlineServicesConnect.ConnectionState.Reconnecting:
<div class="info-box warning">
<p class="fa-p"><i class="fa fa-globe"></i> @Model.OnlineServicesState to Online Services</p>
</div>
break;
}
}
else
{
using (Html.BeginForm(MVC.Config.SystemConfig.Activate()))
{
@Html.AntiForgeryToken();
<button type="submit" class="button small">Activate Now</button>
}
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>Activating Disco ICT with Online Services unlocks additional functionality.
</p>
</div>
}
</td>
</tr>
<tr>
<th style="width: 135px">
License:
</th>
<td>
@using (Html.BeginForm(MVC.API.System.LicenseCheck()))
{
@Html.AntiForgeryToken();
<input id="license" type="text" name="license" value="@Model.License" />
<button type="submit" class="button small">Apply</button>
}
<script type="text/javascript">
$(function () {
const $element = $('#license');
const original = $element.val();
$element.on('keyup', function (e) {
const $button = $element.next('button');
const value = $element.val();
if (!original) {
$element.prop('required', true);
$button.text('Apply');
} else {
if (original === value) {
$button.text('Validate');
} else {
if (!value) {
$button.text('Clear');
} else {
$button.text('Apply');
}
}
}
}).trigger('keyup');
});
</script>
</td>
</tr>
@if (Model.License != null)
{
<tr>
<th style="width: 135px">
Status:
</th>
<td>
@if (Model.LicenseError != null)
{
<div class="error"><i class="fa fa-exclamation-circle fa-lg"></i> @Model.LicenseError</div>
}
else
{
<span>Expires @CommonHelpers.FriendlyDate(Model.LicenseExpires)</span>
}
</td>
</tr>
}
else
{
<tr>
<td colspan="2">
<strong>Official support is available</strong>
<ul>
<li>Initial implementation assistance.</li>
<li>Commitment to maintaining Disco ICT functionality and associated plugins.</li>
<li>Direct support.</li>
<li>Access to additional functionality.</li>
<li>Ability to suggest additional functionality, with a voice in feature prioritisation.</li>
</ul>
<div style="text-align: right; margin-top: 4px;">
<a href="https://discoict.com.au/support.aspx" target="_blank" class="button small">Request More Information</a>
</div>
</td>
</tr>
}
</table>
</div>
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Updates</h2>
<table>
@{
if (Model.UpdateLatestResponse == null)
{
<tr>
<th style="width: 135px">
Last Check:
</th>
<td>
<div class="error"><i class="fa fa-exclamation-circle fa-lg"></i>&nbsp;Never</div>
</td>
</tr>
}
else
{
<tr>
<th style="width: 135px">
Last Run:
</th>
<td>
<span>@CommonHelpers.FriendlyDate(Model.UpdateLatestResponse.UpdateResponseDate.ToLocalTime())</span>
</td>
</tr>
if (Model.UpdateAvailable)
{
<tr>
<th style="width: 135px">
Update Available:
</th>
<td>
<div>
<i class="fa fa-info-circle fa-lg information"></i>&nbsp;Version @(Model.UpdateLatestResponse.LatestVersion) is available
</div>
<div class="smallMessage">
[Released @(CommonHelpers.FriendlyDate(Model.UpdateLatestResponse.ReleasedDate))]
</div>
<div class="smallMessage">@(new HtmlString(Model.UpdateLatestResponse.Description))</div>
<a href="@(Model.UpdateLatestResponse.UrlLink)" target="_blank">Download Now</a>
</td>
</tr>
}
else
{
<tr>
<th style="width: 135px">
Status:
</th>
<td>
<i class="fa fa-check-square fa-lg success"></i>&nbsp;<span>The latest version is installed</span>
</td>
</tr>
}
}
}
<tr>
<th style="width: 135px">Check for Update:</th>
<td>
@{
if (Model.UpdateRunningStatus == null)
{
<span>
@using (Html.BeginForm(MVC.API.System.UpdateCheck()))
{
@Html.AntiForgeryToken();
<button type="submit" class="button small">Check Now</button>
}
</span>
<span class="smallMessage">[Will run automatically <strong>@CommonHelpers.FriendlyDate(Model.UpdateNextScheduled, "Unknown")</strong>]</span>
}
else
{
<span>@Html.ActionLink("View Status", MVC.Config.Logging.TaskStatus(Model.UpdateRunningStatus.SessionId))</span>
<span class="smallMessage">[Running Now]</span>
}
}
@if (Model.UpdateBetaDeployment)
{
<hr />
<span class="alert"><i class="fa fa-info-circle fa-lg"></i>&nbsp;Beta Deployment</span>
}
</td>
</tr>
</table>
</div>
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Active Directory</h2>
<table>
<tr>
<th style="width: 135px">
Primary Domain:
</th>
<td>
<code><strong>@Model.ADPrimaryDomain.Name</strong> <span>[@Model.ADPrimaryDomain.NetBiosName]</span></code>
</td>
</tr>
<tr>
<th style="width: 135px">
Additional Domains:
</th>
<td>
@if (Model.ADDomains.Count > 1)
{
var adAdditionalDomains = Model.ADDomains.Where(d => d != Model.ADPrimaryDomain).OrderBy(d => d.Name).ToList();
var adDomainFirst = adAdditionalDomains.First();
<code>@adDomainFirst.Name <span>[@adDomainFirst.NetBiosName]</span></code>
foreach (var adDomain in adAdditionalDomains.Skip(1))
{
<hr />
<div>
<code>@adDomain.Name <span>[@adDomain.NetBiosName]</span></code>
</div>
}
}
else
{
<span class="smallMessage">&lt;None&gt;</span>
}
</td>
</tr>
<tr>
<th style="width: 135px">
Site:
</th>
<td>
<code><strong>@Model.ADSite.Name</strong></code>
</td>
</tr>
<tr>
<th style="width: 135px">
Servers:
</th>
<td>
<div>
@if (Model.ADServers.Count > 0)
{
<ul class="none">
@foreach (var server in Model.ADServers)
{
var serverDescription = string.Format("{0} [{1}]", server.Name.EndsWith(server.Domain.Name, StringComparison.OrdinalIgnoreCase) ? server.Name.Substring(0, server.Name.Length - server.Domain.Name.Length - 1) : server.Name, server.Domain.NetBiosName);
var reachable = server.IsAvailable;
<li>
@if (server.IsAvailable)
{
<i class="fa fa-check success fa-fw fa-lg" title="Available"></i>
}
else
{
<i class="fa fa-exclamation warning fa-fw fa-lg" title="Unavailable, will retry at @(server.AvailableWhen.Value.ToLongTimeString())"></i>
}
<code>@(serverDescription)</code>
@if (server.IsSiteServer)
{
<i class="fa fa-building-o information fa-fw" title="Site Server"></i>
}
else
{
<i class="fa fa-globe warning fa-fw" title="Not a Site Server"></i>
}
@if (server.IsWritable)
{
<i class="fa fa-pencil information fa-fw" title="Writable Domain Controller"></i>
}
</li>
}
</ul>
}
else
{
<div class="error">
<i class="fa fa-exclamation-circle fa-lg"></i>&nbsp;<span>None Found</span>
</div>
}
</div>
</td>
</tr>
<tr>
<th style="width: 135px">
Directory:
</th>
<td>
@if (Model.ADAllServers == null)
{
<div>
@Html.CheckBoxFor(m => m.ADSearchAllServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllServers)
</div>
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>Directory servers are currently being retrieved.<br />
Try refreshing this page in a moment.
</p>
</div>
}
else
{
if (canConfigAD)
{
var canSearchEntireDirectory = (Model.ADAllServers.Count <= Disco.Services.Interop.ActiveDirectory.ActiveDirectory.MaxAllServerSearch);
<div>
@if (!canSearchEntireDirectory)
{
@Html.CheckBoxFor(m => m.ADSearchAllServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllServers)
<div class="info-box">
<p class="fa-p">
<i class="fa fa-exclamation-circle warning"></i>Disco ICT will not search the entire directory which consists of more than @(Disco.Services.Interop.ActiveDirectory.ActiveDirectory.MaxAllServerSearch) servers. Only servers within this site will be searched.
</p>
</div>
}
else
{
@Html.CheckBoxFor(m => m.ADSearchAllServers) @Html.LabelFor(m => m.ADSearchAllServers) @AjaxHelpers.AjaxLoader()
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco ICT will query all servers within the directory rather than only servers within this site.
</p>
</div>
<script>
$(function () {
document.DiscoFunctions.PropertyChangeHelper($('#ADSearchAllServers'), null, '@(Url.Action(MVC.API.System.UpdateActiveDirectorySearchAllServers()))', 'SearchAllServers');
});
</script>
}
</div>
}
else
{
<div>
@Html.CheckBoxFor(m => m.ADSearchAllServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllServers)
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco ICT will query all servers within the directory rather than only servers within this site.
</p>
</div>
</div>
}
<div>
<hr />
<span>All Servers:</span>
<ul id="Config_System_AD_AllServers" class="none">
@{
var domainIndex = Model.ADDomains.ToDictionary(d => d.Name, StringComparer.OrdinalIgnoreCase);
var siteServers = Model.ADServers.Where(s => s.IsSiteServer).ToDictionary(s => s.Name, StringComparer.OrdinalIgnoreCase);
foreach (var server in Model.ADAllServers.OrderBy(s => s))
{
var serverDescription = server;
if (server.Contains('.'))
{
Disco.Services.Interop.ActiveDirectory.ADDomain serverDomain;
if (domainIndex.TryGetValue(server.Substring(server.IndexOf('.') + 1), out serverDomain))
{
serverDescription = string.Format("{0} [{1}]", server.Substring(0, server.IndexOf('.')), serverDomain.NetBiosName);
}
}
<li>
<code>@serverDescription</code>@if (siteServers.ContainsKey(server))
{<i class="fa fa-building-o information fa-fw" title="Site Server"></i>}
</li>
}
}
</ul>
<script>
$(function () {
var toManyServers = 5;
var ul = $('#Config_System_AD_AllServers');
var ulLi = ul.find('li');
if (ulLi.length > toManyServers) {
var liMore = $('<li>').append(
$('<a>').attr('href', '#')
.text('Show All Servers (' + (ulLi.length - toManyServers) + ' more)')
.click(function () {
$(this).closest('li').remove();
ul.find('li').show();
return false;
}))
.insertAfter(ulLi[(toManyServers - 1)]);
ulLi.each(function (i) {
if (i > (toManyServers - 1))
$(this).hide();
});
}
});
</script>
</div>
}
</td>
</tr>
<tr>
<th style="width: 135px">
Searching:
</th>
<td>
@{
object ADSearchWildcardSuffixOnlyAttributes = null;
if (!canConfigAD)
{
ADSearchWildcardSuffixOnlyAttributes = new
{
disabled = "disabled"
};
}
}
@Html.CheckBoxFor(m => m.ADSearchWildcardSuffixOnly, ADSearchWildcardSuffixOnlyAttributes) @Html.LabelFor(m => m.ADSearchWildcardSuffixOnly) @AjaxHelpers.AjaxLoader()
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco ICT will utilize Active Directory indexes to greatly improve search performance.
If disabled, more results may be returned however performance will be reduced especially in large Active Directory domains.
</p>
</div>
@if (canConfigAD)
{
<script>
$(function () {
document.DiscoFunctions.PropertyChangeHelper($('#ADSearchWildcardSuffixOnly'), null, '@(Url.Action(MVC.API.System.UpdateActiveDirectorySearchWildcardSuffixOnly()))', 'SearchWildcardSuffixOnly');
});
</script>
}
</td>
</tr>
<tr>
<th style="width: 135px">
Search Scope:
</th>
<td>
@if (Model.ADSearchContainers != null && Model.ADSearchContainers.Count > 0)
{
<div>Searching is restricted to the following Organisational&nbsp;Unit containers</div>
<ul id="Config_System_AD_SearchScope_DistinguishedNames">
@foreach (var adContainer in Model.ADSearchContainers)
{
<li data-distinguishedname="@adContainer.Item1"><code>@adContainer.Item3</code></li>
}
</ul>
}
else
{
<div>No Organisational&nbsp;Unit restrictions are in effect.</div>
<div class="info-box">
<p class="fa-p">
<i class="fa fa-info-circle"></i>When searching, the entire domain will be queried. This is suitable for most single-domain deployments.
</p>
</div>
}
@if (canConfigAD)
{
<div>
<hr />
<button id="Config_System_AD_SearchScope_Update" type="button" class="button small">Update</button>
</div>
<div id="Config_System_AD_SearchScope_Dialog" class="dialog" title="Search Scope" data-url="@(Url.Action(MVC.API.System.DomainOrganisationalUnits()))">
<div id="Config_System_AD_SearchScope_Dialog_Loading">
@AjaxHelpers.AjaxLoader() Loading Organisational Units
</div>
<div id="Config_System_AD_SearchScope_Tree" class="organisationalUnitTree">
</div>
@using (Html.BeginForm(MVC.API.System.UpdateActiveDirectorySearchScope(null, redirect: true)))
{
@Html.AntiForgeryToken()
}
</div>
<script>
$(function () {
var $dialog, $tree, tree, distinguishedNames;
function expandNodeTree(node) {
var parent = node.parent;
if (parent) {
expandNodeTree(parent);
if (!parent.isExpanded())
parent.setExpanded(true, { noAnimation: true, noEvents: false });
}
}
function selectDistinguishedNames() {
if (!distinguishedNames) {
distinguishedNames = $('#Config_System_AD_SearchScope_DistinguishedNames')
.find('li')
.map(function () { return $(this).attr('data-distinguishedname'); }).get();
}
if (tree) {
tree.visit(function (node) {
if ($.inArray(node.key, distinguishedNames) >= 0) {
node.setSelected(true);
expandNodeTree(node);
} else if (node.isSelected()) {
node.setSelected(false);
}
});
}
}
async function update() {
if (!$dialog) {
$dialog = $('#Config_System_AD_SearchScope_Dialog').dialog({
autoOpen: false,
buttons: null,
draggable: false,
modal: true,
resizable: false,
width: 500,
height: 500
});
$loading = $('#Config_System_AD_SearchScope_Dialog_Loading');
$loading.find('i.ajaxLoading').show();
$tree = $('#Config_System_AD_SearchScope_Tree');
$dialog.css('overflow', 'visible');
$tree.css('height', '100%');
const body = new FormData();
body.append('__RequestVerificationToken', document.body.dataset.antiforgery);
const response = await fetch($dialog.attr('data-url'), {
method: 'POST',
body: body
});
const data = await response.json();
$loading.hide();
tree = $tree.fancytree({
source: data,
checkbox: true,
selectMode: 2,
keyboard: false,
fx: null
}).fancytree('getTree');
tree.$container.css('position', 'relative');
// Set Buttons
$dialog.dialog('option', 'buttons', {
'Search Entire Directory': function () {
var $this = $(this);
$this.css('overflow', 'hidden');
$this.dialog("disable");
$this.dialog("option", "buttons", null);
var $form = $dialog.find('form');
$form.submit();
},
'Save': function () {
var $this = $(this);
$this.css('overflow', 'hidden');
$this.dialog("disable");
$this.dialog("option", "buttons", null);
var nodes = tree.getSelectedNodes();
var $form = $dialog.find('form');
$.each(nodes, function (i, node) {
$('<input>').attr({ 'type': 'hidden', 'name': 'Containers', 'value': node.key }).appendTo($form);
});
$form.submit();
}
});
// Select & Expand
selectDistinguishedNames();
tree.options.fx = { height: "toggle", duration: 200 };
}
selectDistinguishedNames();
$dialog.dialog('open');
return false;
}
$('#Config_System_AD_SearchScope_Update').click(update);
});
</script>
}
</td>
</tr>
</table>
</div>
@if (canConfigProxy)
{
using (Html.BeginForm(MVC.API.System.UpdateProxySettings()))
{
@Html.AntiForgeryToken()
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Proxy Settings</h2>
<table>
<tr>
<th style="width: 135px">
Address:
</th>
<td>
@Html.EditorFor(m => m.ProxyAddress)<br />
@Html.ValidationMessageFor(m => m.ProxyAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
Port:
</th>
<td>
@Html.EditorFor(m => m.ProxyPort)<br />
@Html.ValidationMessageFor(m => m.ProxyPort)
</td>
</tr>
<tr>
<th style="width: 135px">
Username:
</th>
<td>
@Html.EditorFor(m => m.ProxyUsername)<br />
@Html.ValidationMessageFor(m => m.ProxyUsername)
</td>
</tr>
<tr>
<th style="width: 135px">
Password:
</th>
<td>
@Html.EditorFor(m => m.ProxyPassword)<br />
@Html.ValidationMessageFor(m => m.ProxyPassword)
</td>
</tr>
<tr>
<th style="width: 135px">
&nbsp;
</th>
<td>
<button id="Config_System_Proxy_Save" type="button" class="button small">Save Proxy Settings</button>@AjaxHelpers.AjaxLoader()
<script>
$(function () {
const button = $('#Config_System_Proxy_Save');
async function updateProxySettings(ajaxLoading) {
const $form = $('#ProxyAddress').closest('form');
const body = new FormData($form[0]);
const response = await fetch($form.attr('action'), {
method: 'post',
body: body
});
if (response.ok) {
ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
} else {
alert('Unable to change proxy settings:\nCheck logs for more information');
ajaxLoading.hide();
}
}
button.on('click', function () {
var ajaxLoading = button.next('.ajaxLoading').first().show();
updateProxySettings(ajaxLoading);
});
});
</script>
</td>
</tr>
</table>
</div>
}
}
else
{
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Proxy Settings</h2>
<table>
<tr>
<th style="width: 135px">
Address:
</th>
<td>
@Html.DisplayFor(m => m.ProxyAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
Port:
</th>
<td>
@Html.DisplayFor(m => m.ProxyPort)
</td>
</tr>
<tr>
<th style="width: 135px">
Username:
</th>
<td>
@Html.DisplayFor(m => m.ProxyUsername)
</td>
</tr>
<tr>
<th style="width: 135px">
Password:
</th>
<td>
********
</td>
</tr>
</table>
</div>
}
@if (canConfigEmail)
{
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Email Settings</h2>
<table>
<tr>
<th style="width: 135px">
SMTP Server:
</th>
<td>
@Html.EditorFor(m => m.EmailSmtpServer)<br />
@Html.ValidationMessageFor(m => m.EmailSmtpServer)
</td>
</tr>
<tr>
<th style="width: 135px">
Port:
</th>
<td>
@Html.EditorFor(m => m.EmailSmtpPort)<br />
@Html.ValidationMessageFor(m => m.EmailSmtpPort)
</td>
</tr>
<tr>
<th style="width: 135px">
Default From Address:
</th>
<td>
@Html.EditorFor(m => m.EmailFromAddress)<br />
@Html.ValidationMessageFor(m => m.EmailFromAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
Reply To Address:
</th>
<td>
@Html.EditorFor(m => m.EmailReplyToAddress)<br />
@Html.ValidationMessageFor(m => m.EmailReplyToAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
&nbsp;
</th>
<td>
@Html.CheckBoxFor(m => m.EmailEnableSsl) @Html.LabelFor(m => m.EmailEnableSsl)
</td>
</tr>
<tr>
<th style="width: 135px">
Username:
</th>
<td>
@Html.EditorFor(m => m.EmailUsername)<br />
@Html.ValidationMessageFor(m => m.EmailUsername)
</td>
</tr>
<tr>
<th style="width: 135px">
Password:
</th>
<td>
@Html.EditorFor(m => m.EmailPassword)<br />
@Html.ValidationMessageFor(m => m.EmailPassword)
</td>
</tr>
<tr>
<th style="width: 135px">
&nbsp;
</th>
<td>
<button id="Config_System_Email_Test" type="button" class="button small" @(Model.EmailIsConfigured ? null : "disabled")>Send Test Email</button>
<button id="Config_System_Email_Save" type="button" class="button small">Save Email Settings</button>@AjaxHelpers.AjaxLoader()
<div id="Config_System_Email_Test_Dialog" class="dialog" title="Send Test Email">
<h4><i class="fa fa-envelope information"></i>&nbsp;Recipient Email Address:</h4>
<br />
@using (Html.BeginForm(MVC.API.System.SendTestEmail()))
{
@Html.AntiForgeryToken()
<input type="hidden" name="redirect" value="true" />
<input id="Config_System_Email_Test_Recipient" name="Recipient" type="text" value="@CurrentUser.EmailAddress" />
}
</div>
<script>
$(function () {
var button = $('#Config_System_Email_Save');
var testButton = $('#Config_System_Email_Test');
var testDialog = null;
button.click(function () {
var url = '@(Url.Action(MVC.API.System.UpdateEmailSettings()))';
var data = {
SmtpServer: $('#EmailSmtpServer').val(),
SmtpPort: $('#EmailSmtpPort').val(),
FromAddress: $('#EmailFromAddress').val(),
ReplyToAddress: $('#EmailReplyToAddress').val(),
EnableSsl: $('#EmailEnableSsl').is(':checked'),
Username: $('#EmailUsername').val(),
Password: $('#EmailPassword').val(),
'__RequestVerificationToken': document.body.dataset.antiforgery
}
var ajaxLoading = button.next('.ajaxLoading').first().show();
$.ajax({
type: 'POST',
dataType: 'json',
url: url,
data: data,
complete: function (response) {
if (response.status === 200) {
ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
if (!!$('#EmailSmtpServer').val()) {
testButton.removeAttr('disabled');
} else {
testButton.attr('disabled', 'disabled');
}
} else {
alert('Unable to change email settings:\nCheck logs for more information');
ajaxLoading.hide();
}
}
});
});
testButton.closest('table').find('td>input').change(function () {
testButton.attr('disabled', 'disabled');
});
testButton.click(function () {
if (!testDialog) {
testDialog = $('#Config_System_Email_Test_Dialog')
.dialog({
resizable: false,
height: 180,
modal: true,
autoOpen: false,
buttons: {
Send: function () {
var $this = $(this);
var recipientInput = $('#Config_System_Email_Test_Recipient');
if (!!recipientInput.val()) {
$this.dialog("disable");
$this.dialog("option", "buttons", null);
recipientInput.closest('form').submit()
} else {
alert('Enter the recipient address for the test email');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
testDialog.dialog('open');
});
});
</script>
</td>
</tr>
</table>
</div>
}
else
{
<div class="form" style="width: 450px; margin-top: 15px;">
<h2>Email Settings</h2>
<table>
<tr>
<th style="width: 135px">
SMTP Server:
</th>
<td>
@Html.DisplayFor(m => m.EmailSmtpServer)
</td>
</tr>
<tr>
<th style="width: 135px">
Port:
</th>
<td>
@Html.DisplayFor(m => m.EmailSmtpPort)
</td>
</tr>
<tr>
<th style="width: 135px">
Default From Address:
</th>
<td>
@Html.DisplayFor(m => m.EmailFromAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
Reply To Address:
</th>
<td>
@Html.DisplayFor(m => m.EmailReplyToAddress)
</td>
</tr>
<tr>
<th style="width: 135px">
Enable SSL:
</th>
<td>
@Html.CheckBoxFor(m => m.EmailEnableSsl, new { disabled = "disabled" }) @Html.LabelFor(m => m.EmailEnableSsl)
</td>
</tr>
<tr>
<th style="width: 135px">
Username:
</th>
<td>
@Html.DisplayFor(m => m.EmailUsername)
</td>
</tr>
<tr>
<th style="width: 135px">
Password:
</th>
<td>
********
</td>
</tr>
</table>
</div>
}
<div class="actionBar">
@using (Html.BeginForm(MVC.API.System.UpdateLastNetworkLogonDates()))
{
@Html.AntiForgeryToken();
<button type="submit" class="button">Update Device Last Network Logons</button>
}
</div>