feature: pending device enrollment approval

This commit is contained in:
Gary Sharp
2024-01-21 14:06:11 +11:00
parent 6af83cbdb2
commit 37e2e5a08c
33 changed files with 1379 additions and 344 deletions
@@ -0,0 +1,44 @@
using Disco.Services.Authorization;
using Disco.Services.Devices.Enrolment;
using Disco.Services.Web;
using System;
using System.Web.Mvc;
namespace Disco.Web.Areas.API.Controllers
{
public partial class EnrollmentController : AuthorizedDatabaseController
{
[HttpPost]
[ValidateAntiForgeryToken]
[DiscoAuthorize(Claims.Device.Actions.EnrolDevices)]
public virtual ActionResult ResolveSessionPending(string sessionId, bool approve, string reason)
{
WindowsDeviceEnrolment.ResolvePendingEnrollment(sessionId, approve, CurrentUser.UserId, reason);
return new HttpStatusCodeResult(200);
}
[HttpPost]
[DiscoAuthorize(Claims.Config.Enrolment.Configure)]
public virtual ActionResult PendingTimeoutMinutes(int PendingTimeoutMinutes)
{
try
{
if (PendingTimeoutMinutes > 0)
{
Database.DiscoConfiguration.Bootstrapper.PendingTimeout = TimeSpan.FromMinutes(PendingTimeoutMinutes);
Database.SaveChanges();
return Json("OK", JsonRequestBehavior.AllowGet);
}
else
{
throw new Exception("The pending timeout must be greater than zero");
}
}
catch (Exception ex)
{
return Json($"Error: {ex.Message}");
}
}
}
}
@@ -13,7 +13,8 @@ namespace Disco.Web.Areas.Config.Controllers
{
var m = new Models.Enrolment.IndexModel()
{
MacSshUsername = Database.DiscoConfiguration.Bootstrapper.MacSshUsername
MacSshUsername = Database.DiscoConfiguration.Bootstrapper.MacSshUsername,
PendingTimeoutMinutes = (int)Database.DiscoConfiguration.Bootstrapper.PendingTimeout.TotalMinutes,
};
// UI Extensions
@@ -1,13 +1,10 @@
using Disco.Models.UI.Config.Enrolment;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Disco.Web.Areas.Config.Models.Enrolment
{
public class IndexModel : ConfigEnrolmentIndexModel
{
public string MacSshUsername { get; set; }
public int PendingTimeoutMinutes { get; set; }
}
}
@@ -84,9 +84,9 @@
}
@if (Authorization.Has(Claims.Config.Enrolment.Show))
{
<i class="fa fa-cog"></i>@Html.ActionLinkClass("Enrolment", MVC.Config.Enrolment.Index(), "config")
<i class="fa fa-cog"></i>@Html.ActionLinkClass("Enrollment", MVC.Config.Enrolment.Index(), "config")
<div class="pageMenuBlurb">
Configure Enrolment settings including secure credentials.
Configure Enrollment settings including secure credentials.
</div>
}
</div>
@@ -592,14 +592,14 @@ WriteLiteral("></i>");
#line hidden
#line 87 "..\..\Areas\Config\Views\Config\Index.cshtml"
Write(Html.ActionLinkClass("Enrolment", MVC.Config.Enrolment.Index(), "config"));
Write(Html.ActionLinkClass("Enrollment", MVC.Config.Enrolment.Index(), "config"));
#line default
#line hidden
#line 87 "..\..\Areas\Config\Views\Config\Index.cshtml"
#line default
@@ -608,8 +608,8 @@ WriteLiteral(" <div");
WriteLiteral(" class=\"pageMenuBlurb\"");
WriteLiteral(">\r\n Configure Enrolment settings including secure cred" +
"entials.\r\n </div>\r\n");
WriteLiteral(">\r\n Configure Enrollment settings including secure cre" +
"dentials.\r\n </div>\r\n");
#line 91 "..\..\Areas\Config\Views\Config\Index.cshtml"
@@ -961,14 +961,14 @@ WriteLiteral(" class=\"fa fa-cloud-download info\"");
WriteLiteral("></i>\r\n <div>An updated version of Disco is available</div>\r\n <a");
WriteAttribute("href", Tuple.Create(" href=\"", 8211), Tuple.Create("\"", 8247)
WriteAttribute("href", Tuple.Create(" href=\"", 8213), Tuple.Create("\"", 8249)
#line 155 "..\..\Areas\Config\Views\Config\Index.cshtml"
, Tuple.Create(Tuple.Create("", 8218), Tuple.Create<System.Object, System.Int32>(Model.UpdateResponse.UrlLink
, Tuple.Create(Tuple.Create("", 8220), Tuple.Create<System.Object, System.Int32>(Model.UpdateResponse.UrlLink
#line default
#line hidden
, 8218), false)
, 8220), false)
);
WriteLiteral(" class=\"button small alert\"");
@@ -5,20 +5,98 @@
var canConfig = Authorization.Has(Claims.Config.Enrolment.Configure);
var canShowStatus = Authorization.Has(Claims.Config.Enrolment.ShowStatus);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrolment");
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrollment");
}
<div class="form" style="width: 530px;">
<h2>Apple Mac Secure Enrol</h2>
<table>
<tr>
<th>Username:
<th>
Pending Timeout:
</th>
<td>@if (canConfig)
<td>
@if (canConfig)
{
@Html.TextBoxFor(model => model.MacSshUsername)
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
@Html.TextBoxFor(model => model.PendingTimeoutMinutes, new { type = "number", min = "1" })
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<span> minutes <span class="smallText">(default: 30)</span></span>
<script type="text/javascript">
$(function () {
var $DOM = $('#PendingTimeoutMinutes');
var $DOMAjaxSave = $DOM.next('.ajaxSave');
$DOM
.watermark('Minutes')
.focus(function () { $DOM.select() })
.keydown(function (e) {
$DOMAjaxSave.show();
if (e.which == 13) {
$(this).blur();
}
}).blur(function () {
$DOMAjaxSave.hide();
})
.change(function () {
$DOMAjaxSave.hide();
var $ajaxLoading = $DOMAjaxSave.next('.ajaxLoading').show();
var data = { PendingTimeoutMinutes: parseInt($DOM.val()) };
if (data.PendingTimeoutMinutes <= 0) {
alert('Pending Timeout must be greater than zero');
$ajaxLoading.hide();
return;
} else {
$.ajax({
url: '@Url.Action(MVC.API.Enrollment.PendingTimeoutMinutes())',
dataType: 'json',
method: 'POST',
data: data,
success: function (d) {
if (d == 'OK') {
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
} else {
$ajaxLoading.hide();
alert('Unable to update pending timeout: ' + d);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to update pending timeout: ' + textStatus);
$ajaxLoading.hide();
}
});
}
});
});
</script>
}
else
{
@TimeSpan.FromMinutes(Model.PendingTimeoutMinutes)
}
</td>
</tr>
<tr>
<td colspan="2">
<span class="smallText">
If a device enrollment is not automatically approved it will remain pending until the timeout is reached.
Pending enrollments can be approved manually from the Enrollment Status page.
</span>
</td>
</tr>
</table>
</div>
<div class="form" style="width: 530px; margin-top: 15px">
<h2>Apple Mac Secure Enroll</h2>
<table>
<tr>
<th>
Username:
</th>
<td>
@if (canConfig)
{
@Html.TextBoxFor(model => model.MacSshUsername)
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
$(function () {
var $DOM = $('#MacSshUsername');
var $DOMAjaxSave = $DOM.next('.ajaxSave');
@@ -56,31 +134,33 @@
});
});
});
</script>
</script>
}
else
{
if (string.IsNullOrEmpty(Model.MacSshUsername))
{
<span class="smallMessage">&lt;None Specified&gt;</span>
<span class="smallMessage">&lt;None Specified&gt;</span>
}
else
{
@Model.MacSshUsername
@Model.MacSshUsername
}
}
</td>
</tr>
<tr>
<th>Password:
<th>
Password:
</th>
<td>@if (canConfig)
<td>
@if (canConfig)
{
<input id="MacSshPassword" type="password" />
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
<input id="MacSshPassword" type="password" />
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
$(function () {
var $DOM = $('#MacSshPassword');
var $DOMAjaxSave = $DOM.next('.ajaxSave');
@@ -118,32 +198,36 @@
});
});
});
</script>
</script>
}
else
{
<text>********</text>
<text>********</text>
}
</td>
</tr>
<tr>
<td colspan="2">
<span class="smallText"><strong>Instructions:</strong> The above credentials must be
able to connect to the requesting Apple Mac client via <a target="_blank" href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a>. Enter/Script the following command:</span>
<span class="smallText">
<strong>Instructions:</strong> The above credentials must be
able to connect to the requesting Apple Mac client via <a target="_blank" href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a>. Enter/Script the following command:
</span>
<div class="code">
curl&nbsp;<a target="_blank" href="http://disco:9292/Services/Client/Unauthenticated/MacSecureEnrol">http://disco:9292/Services/Client/Unauthenticated/MacSecureEnrol</a>
</div>
<span class="smallText">This url will return a <a target="_blank" href="http://json.org/">JSON</a> response containing basic information about the enrolment.</span><br />
<span class="smallMessage">This command makes use of <a target="_blank" href="http://curl.haxx.se/">cURL</a> (bundled with OSX). Other methods can also trigger a Mac Secure Enrol,
<span class="smallText">This url will return a <a target="_blank" href="http://json.org/">JSON</a> response containing basic information about the enrollment.</span><br />
<span class="smallMessage">
This command makes use of <a target="_blank" href="http://curl.haxx.se/">cURL</a> (bundled with OSX). Other methods can also trigger a Mac Secure Enroll,
such as an anchor (<span class="code">&lt;a&gt;</span>) or <span class="code">&lt;script&gt;</span>
tag embedded on the organisation's intranet.</span>
tag embedded on the organisation's intranet.
</span>
</td>
</tr>
</table>
</div>
@if (canShowStatus && Authorization.Has(Claims.Config.Logging.Show))
{
<h2>Live Enrolment Logging</h2>
<h2>Live Enrollment Logging</h2>
@Html.Partial(MVC.Config.Shared.Views.LogEvents, new Disco.Web.Areas.Config.Models.Shared.LogEventsModel()
{
IsLive = true,
@@ -160,6 +244,6 @@
}
@if (canShowStatus)
{
@Html.ActionLinkButton("Enrolment Status", MVC.Config.Enrolment.Status())
@Html.ActionLinkButton("Enrollment Status", MVC.Config.Enrolment.Status())
}
</div>
@@ -51,7 +51,7 @@ namespace Disco.Web.Areas.Config.Views.Enrolment
var canConfig = Authorization.Has(Claims.Config.Enrolment.Configure);
var canShowStatus = Authorization.Has(Claims.Config.Enrolment.ShowStatus);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrolment");
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrollment");
#line default
@@ -62,60 +62,238 @@ WriteLiteral(" class=\"form\"");
WriteLiteral(" style=\"width: 530px;\"");
WriteLiteral(">\r\n <h2>Apple Mac Secure Enrol</h2>\r\n <table>\r\n <tr>\r\n <t" +
"h>Username:\r\n </th>\r\n <td>");
WriteLiteral(">\r\n <table>\r\n <tr>\r\n <th>\r\n Pending Timeout:\r" +
"\n </th>\r\n <td>\r\n");
#line 16 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 17 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 17 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (canConfig)
{
#line default
#line hidden
#line 18 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.TextBoxFor(model => model.MacSshUsername));
#line default
#line hidden
#line 18 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 19 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxSave());
Write(Html.TextBoxFor(model => model.PendingTimeoutMinutes, new { type = "number", min = "1" }));
#line default
#line hidden
#line 19 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 20 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxSave());
#line default
#line hidden
#line 20 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 21 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxLoader());
#line default
#line hidden
#line 21 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
WriteLiteral(" <span> minutes <span");
WriteLiteral(" class=\"smallText\"");
WriteLiteral(">(default: 30)</span></span>\r\n");
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
var $DOM = $('#PendingTimeoutMinutes');
var $DOMAjaxSave = $DOM.next('.ajaxSave');
$DOM
.watermark('Minutes')
.focus(function () { $DOM.select() })
.keydown(function (e) {
$DOMAjaxSave.show();
if (e.which == 13) {
$(this).blur();
}
}).blur(function () {
$DOMAjaxSave.hide();
})
.change(function () {
$DOMAjaxSave.hide();
var $ajaxLoading = $DOMAjaxSave.next('.ajaxLoading').show();
var data = { PendingTimeoutMinutes: parseInt($DOM.val()) };
if (data.PendingTimeoutMinutes <= 0) {
alert('Pending Timeout must be greater than zero');
$ajaxLoading.hide();
return;
} else {
$.ajax({
url: '");
#line 48 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Url.Action(MVC.API.Enrollment.PendingTimeoutMinutes()));
#line default
#line hidden
WriteLiteral(@"',
dataType: 'json',
method: 'POST',
data: data,
success: function (d) {
if (d == 'OK') {
$ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
} else {
$ajaxLoading.hide();
alert('Unable to update pending timeout: ' + d);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to update pending timeout: ' + textStatus);
$ajaxLoading.hide();
}
});
}
});
});
</script>
");
#line 69 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
else
{
#line default
#line hidden
#line 72 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(TimeSpan.FromMinutes(Model.PendingTimeoutMinutes));
#line default
#line hidden
#line 72 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
#line default
#line hidden
WriteLiteral(" </td>\r\n </tr>\r\n <tr>\r\n <td");
WriteLiteral(" colspan=\"2\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"smallText\"");
WriteLiteral(@">
If a device enrollment is not automatically approved it will remain pending until the timeout is reached.
Pending enrollments can be approved manually from the Enrollment Status page.
</span>
</td>
</tr>
</table>
</div>
<div");
WriteLiteral(" class=\"form\"");
WriteLiteral(" style=\"width: 530px; margin-top: 15px\"");
WriteLiteral(">\r\n <h2>Apple Mac Secure Enroll</h2>\r\n <table>\r\n <tr>\r\n <" +
"th>\r\n Username:\r\n </th>\r\n <td>\r\n");
#line 94 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 20 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxLoader());
#line 94 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (canConfig)
{
#line default
#line hidden
#line 96 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.TextBoxFor(model => model.MacSshUsername));
#line default
#line hidden
#line 20 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 96 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 97 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxSave());
#line default
#line hidden
WriteLiteral(" <script");
#line 97 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 98 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxLoader());
#line default
#line hidden
#line 98 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
@@ -142,7 +320,7 @@ WriteLiteral(@">
url: '");
#line 41 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 119 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Url.Action(MVC.API.Bootstrapper.MacSshUsername()));
@@ -166,11 +344,11 @@ WriteLiteral(@"',
});
});
});
</script>
</script>
");
#line 60 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 138 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
else
{
@@ -180,49 +358,55 @@ WriteLiteral(@"',
#line default
#line hidden
WriteLiteral(" <span");
WriteLiteral(" <span");
WriteLiteral(" class=\"smallMessage\"");
WriteLiteral(">&lt;None Specified&gt;</span>\r\n");
#line 66 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 144 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
else
{
#line default
#line hidden
#line 69 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Model.MacSshUsername);
#line 147 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Model.MacSshUsername);
#line default
#line hidden
#line 69 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 147 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
}
#line default
#line hidden
WriteLiteral(" </td>\r\n </tr>\r\n\r\n <tr>\r\n <th>Password:\r\n " +
" </th>\r\n <td>");
WriteLiteral(" </td>\r\n </tr>\r\n\r\n <tr>\r\n <th>\r\n " +
" Password:\r\n </th>\r\n <td>\r\n");
#line 78 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 158 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 158 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (canConfig)
{
#line default
#line hidden
WriteLiteral(" <input");
WriteLiteral(" <input");
WriteLiteral(" id=\"MacSshPassword\"");
@@ -231,40 +415,40 @@ WriteLiteral(" type=\"password\"");
WriteLiteral(" />\r\n");
#line 81 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 161 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 81 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxSave());
#line 161 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxSave());
#line default
#line hidden
#line 81 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 161 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 82 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxLoader());
#line 162 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(AjaxHelpers.AjaxLoader());
#line default
#line hidden
#line 82 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 162 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
WriteLiteral(" <script");
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
@@ -291,7 +475,7 @@ WriteLiteral(@">
url: '");
#line 103 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 183 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Url.Action(MVC.API.Bootstrapper.MacSshPassword()));
@@ -315,11 +499,11 @@ WriteLiteral(@"',
});
});
});
</script>
</script>
");
#line 122 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 202 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
else
{
@@ -327,14 +511,14 @@ WriteLiteral(@"',
#line default
#line hidden
WriteLiteral(" ");
WriteLiteral(" ");
WriteLiteral("********");
WriteLiteral("\r\n");
#line 126 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 206 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
@@ -348,14 +532,16 @@ WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"smallText\"");
WriteLiteral("><strong>Instructions:</strong> The above credentials must be\r\n " +
" able to connect to the requesting Apple Mac client via <a");
WriteLiteral(">\r\n <strong>Instructions:</strong> The above credentials must " +
"be\r\n able to connect to the requesting Apple Mac client via <" +
"a");
WriteLiteral(" target=\"_blank\"");
WriteLiteral(" href=\"http://en.wikipedia.org/wiki/Secure_Shell\"");
WriteLiteral(">SSH</a>. Enter/Script the following command:</span>\r\n <div");
WriteLiteral(">SSH</a>. Enter/Script the following command:\r\n </span>\r\n " +
" <div");
WriteLiteral(" class=\"code\"");
@@ -376,19 +562,19 @@ WriteLiteral(" target=\"_blank\"");
WriteLiteral(" href=\"http://json.org/\"");
WriteLiteral(">JSON</a> response containing basic information about the enrolment.</span><br />" +
"\r\n <span");
WriteLiteral(">JSON</a> response containing basic information about the enrollment.</span><br /" +
">\r\n <span");
WriteLiteral(" class=\"smallMessage\"");
WriteLiteral(">This command makes use of <a");
WriteLiteral(">\r\n This command makes use of <a");
WriteLiteral(" target=\"_blank\"");
WriteLiteral(" href=\"http://curl.haxx.se/\"");
WriteLiteral(">cURL</a> (bundled with OSX). Other methods can also trigger a Mac Secure Enrol,\r" +
"\n such as an anchor (<span");
WriteLiteral(">cURL</a> (bundled with OSX). Other methods can also trigger a Mac Secure Enroll," +
"\r\n such as an anchor (<span");
WriteLiteral(" class=\"code\"");
@@ -397,26 +583,27 @@ WriteLiteral(">&lt;a&gt;</span>) or <span");
WriteLiteral(" class=\"code\"");
WriteLiteral(">&lt;script&gt;</span>\r\n tag embedded on the organisation\'s in" +
"tranet.</span>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n");
"tranet.\r\n </span>\r\n </td>\r\n </tr>\r\n </table>" +
"\r\n</div>\r\n");
#line 144 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 228 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (canShowStatus && Authorization.Has(Claims.Config.Logging.Show))
{
#line default
#line hidden
WriteLiteral(" <h2>Live Enrolment Logging</h2>\r\n");
WriteLiteral(" <h2>Live Enrollment Logging</h2>\r\n");
#line 147 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 231 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 147 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 231 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.Partial(MVC.Config.Shared.Views.LogEvents, new Disco.Web.Areas.Config.Models.Shared.LogEventsModel()
{
IsLive = true,
@@ -430,7 +617,7 @@ Write(Html.Partial(MVC.Config.Shared.Views.LogEvents, new Disco.Web.Areas.Config
#line default
#line hidden
#line 154 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 238 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
@@ -444,13 +631,13 @@ WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
#line 157 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 241 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line default
#line hidden
#line 157 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 241 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (Authorization.Has(Claims.Config.Enrolment.DownloadBootstrapper))
{
@@ -458,14 +645,14 @@ WriteLiteral(">\r\n");
#line default
#line hidden
#line 159 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 243 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.ActionLinkButton("Download Bootstrapper", MVC.Services.Client.Bootstrapper()));
#line default
#line hidden
#line 159 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 243 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
@@ -475,7 +662,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 161 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 245 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
if (canShowStatus)
{
@@ -483,15 +670,15 @@ WriteLiteral(" ");
#line default
#line hidden
#line 163 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.ActionLinkButton("Enrolment Status", MVC.Config.Enrolment.Status()));
#line 247 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
Write(Html.ActionLinkButton("Enrollment Status", MVC.Config.Enrolment.Status()));
#line default
#line hidden
#line 163 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
#line 247 "..\..\Areas\Config\Views\Enrolment\Index.cshtml"
}
@@ -1,27 +1,47 @@
@{
Authorization.Require(Claims.Config.Enrolment.ShowStatus);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrolment", MVC.Config.Enrolment.Index(), "Status");
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrollment", MVC.Config.Enrolment.Index(), "Status");
Html.BundleDeferred("~/ClientScripts/Modules/Knockout");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-SignalR");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-Isotope");
}
<div id="enrolStatus">
<div id="noSessions" data-bind="visible: noSessions">
<h2>No enrolment sessions today</h2>
<h2>No enrollment sessions today</h2>
</div>
<div id="sessions" data-bind="visible: !noSessions(), foreach: { data: sessions, afterRender: sessionRendered, afterAdd: sessionAdded }" style="display: none">
<div class="session" data-bind="style: { backgroundImage: deviceModelImageUrl }, click: select">
<h3>
<span data-bind="text: title"></span>
<span class="details" data-bind="text: '(' + deviceModelDescription() + ')'"></span>
<i class="fa fa-exclamation-circle" data-bind="visible: isPending"></i>
</h3>
<p class="sessionStart" data-bind="text: startTime"></p>
<p class="sessionStatus" data-bind="text: progressStatus"></p>
<div data-bind="visible: !sessionEnded(), progressValue: progressValue" class="sessionProgress"></div>
<div data-bind="visible: !sessionEnded() && progressValue >= 0, progressValue: progressValue" class="sessionProgress"></div>
</div>
</div>
<div id="dialogSession" data-bind="with: currentSession">
<div class="sessionProgress clearfix">
<p class="sessionStart" data-bind="text: startTime"></p>
<p class="sessionStatus" data-bind="text: progressStatus"></p>
<div data-bind="visible: !sessionEnded() && progressValue >= 0, progressValue: progressValue"></div>
<div id="formResolveSessionPending" data-bind="visible: isPending">
@using (Html.BeginForm(MVC.API.Enrollment.ResolveSessionPending(), FormMethod.Post))
{
@Html.AntiForgeryToken();
<input type="hidden" name="sessionId" data-bind="value: id" />
<div class="reason">
<input type="text" name="reason" placeholder="Reason (optional)" />
</div>
<div class="buttons">
<button type="button" value="True" class="button">Approve</button>
<button type="button" value="False" class="button">Reject</button>
</div>
}
</div>
</div>
<div class="sessionHeader clearfix" data-bind="style: { backgroundImage: deviceModelImageUrl }">
<h2><a href="" target="_blank" data-bind="text: title, attr: { href: deviceUrl }"></a></h2>
<h3 data-bind="text: deviceModelDescription"></h3>
@@ -48,11 +68,6 @@
</tr>
</table>
</div>
<div class="sessionProgress clearfix">
<p class="sessionStart" data-bind="text: startTime"></p>
<p class="sessionStatus" data-bind="text: progressStatus"></p>
<div data-bind="visible: !sessionEnded(), progressValue: progressValue"></div>
</div>
<div class="sessionInfoContainer clearfix">
<div class="sessionInfoMessages">
<table class="logEventsViewport">
@@ -134,7 +149,9 @@
function sessionViewModel(id) {
var self = this;
self.id = id;
self.title = ko.observable(id);
self.isPending = ko.observable(false);
self.messages = ko.observableArray();
self.console = ko.observableArray();
self.serialNumber = ko.observable();
@@ -187,7 +204,7 @@
self.select = function (e, d) {
vm.currentSession(self);
hostDialogSessions.dialog('open');
hostDialogSessions.dialog('option', 'title', 'Device Enrolment: ' + self.title());
hostDialogSessions.dialog('option', 'title', 'Device Enrollment: ' + self.title());
}
}
@@ -228,15 +245,38 @@
if (log.Arguments.length >= 10 && log.Arguments[9])
session.deviceModelId(log.Arguments[9]);
break;
case 14: // SessionPending
session.isPending(true);
session.messages.unshift(log);
session.progressValue(-1);
session.progressStatus('Pending enrollment approval');
break;
case 15: // SessionPendingApproved
session.isPending(false);
session.messages.unshift(log);
session.progressValue(-1);
session.progressStatus('Enrollment approval, waiting for client');
break;
case 16: // SessionPendingRejected
session.isPending(false);
session.messages.unshift(log);
session.progressValue(-1);
session.progressStatus('Enrollment rejected, waiting for client');
break;
case 17: // SessionContinuing
session.isPending(false);
session.messages.unshift(log);
break;
case 20: // SessionFinished
session.sessionEnded(true);
session.isPending(false);
if (session.hasError())
session.progressStatus('Enrolment Finished with an Error');
session.progressStatus('Enrollment Finished with an Error');
else
if (session.hasWarning())
session.progressStatus('Enrolment Finished with a Warning');
session.progressStatus('Enrollment Finished with a Warning');
else
session.progressStatus('Enrolment Finished Successfully');
session.progressStatus('Enrollment Finished Successfully');
session.messages.unshift(log);
break;
case 21: // SessionDiagnosticInformation
@@ -357,6 +397,20 @@
}
}
}
$('#dialogSession').on('click', '#formResolveSessionPending button', function (e) {
const $button = $(this);
const $form = $button.closest('form');
const body = new FormData($form[0]);
body.append('approve', $button.val());
fetch($form.attr('action'), {
method: 'POST',
body: body
}).then(function (response) {
if (!response.ok) {
alert('Failed to resolve pending session: ' + response.statusText);
}
});
});
init();
});
</script>
@@ -48,7 +48,7 @@ namespace Disco.Web.Areas.Config.Views.Enrolment
Authorization.Require(Claims.Config.Enrolment.ShowStatus);
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrolment", MVC.Config.Enrolment.Index(), "Status");
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Enrollment", MVC.Config.Enrolment.Index(), "Status");
Html.BundleDeferred("~/ClientScripts/Modules/Knockout");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-SignalR");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-Isotope");
@@ -66,7 +66,7 @@ WriteLiteral(" id=\"noSessions\"");
WriteLiteral(" data-bind=\"visible: noSessions\"");
WriteLiteral(">\r\n <h2>No enrolment sessions today</h2>\r\n </div>\r\n <div");
WriteLiteral(">\r\n <h2>No enrollment sessions today</h2>\r\n </div>\r\n <div");
WriteLiteral(" id=\"sessions\"");
@@ -91,7 +91,13 @@ WriteLiteral(" class=\"details\"");
WriteLiteral(" data-bind=\"text: \'(\' + deviceModelDescription() + \')\'\"");
WriteLiteral("></span>\r\n </h3>\r\n <p");
WriteLiteral("></span>\r\n <i");
WriteLiteral(" class=\"fa fa-exclamation-circle\"");
WriteLiteral(" data-bind=\"visible: isPending\"");
WriteLiteral("></i>\r\n </h3>\r\n <p");
WriteLiteral(" class=\"sessionStart\"");
@@ -105,7 +111,8 @@ WriteLiteral(" data-bind=\"text: progressStatus\"");
WriteLiteral("></p>\r\n <div");
WriteLiteral(" data-bind=\"visible: !sessionEnded(), progressValue: progressValue\"");
WriteLiteral(" data-bind=\"visible: !sessionEnded() && progressValue >= 0, progressValue: progre" +
"ssValue\"");
WriteLiteral(" class=\"sessionProgress\"");
@@ -117,6 +124,116 @@ WriteLiteral(" data-bind=\"with: currentSession\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" class=\"sessionProgress clearfix\"");
WriteLiteral(">\r\n <p");
WriteLiteral(" class=\"sessionStart\"");
WriteLiteral(" data-bind=\"text: startTime\"");
WriteLiteral("></p>\r\n <p");
WriteLiteral(" class=\"sessionStatus\"");
WriteLiteral(" data-bind=\"text: progressStatus\"");
WriteLiteral("></p>\r\n <div");
WriteLiteral(" data-bind=\"visible: !sessionEnded() && progressValue >= 0, progressValue: progre" +
"ssValue\"");
WriteLiteral("></div>\r\n <div");
WriteLiteral(" id=\"formResolveSessionPending\"");
WriteLiteral(" data-bind=\"visible: isPending\"");
WriteLiteral(">\r\n");
#line 31 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line default
#line hidden
#line 31 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
using (Html.BeginForm(MVC.API.Enrollment.ResolveSessionPending(), FormMethod.Post))
{
#line default
#line hidden
#line 33 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 33 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
;
#line default
#line hidden
WriteLiteral(" <input");
WriteLiteral(" type=\"hidden\"");
WriteLiteral(" name=\"sessionId\"");
WriteLiteral(" data-bind=\"value: id\"");
WriteLiteral(" />\r\n");
WriteLiteral(" <div");
WriteLiteral(" class=\"reason\"");
WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"text\"");
WriteLiteral(" name=\"reason\"");
WriteLiteral(" placeholder=\"Reason (optional)\"");
WriteLiteral(" />\r\n </div>\r\n");
WriteLiteral(" <div");
WriteLiteral(" class=\"buttons\"");
WriteLiteral(">\r\n <button");
WriteLiteral(" type=\"button\"");
WriteLiteral(" value=\"True\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Approve</button>\r\n <button");
WriteLiteral(" type=\"button\"");
WriteLiteral(" value=\"False\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Reject</button>\r\n </div>\r\n");
#line 42 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n </div>\r\n <div");
WriteLiteral(" class=\"sessionHeader clearfix\"");
WriteLiteral(" data-bind=\"style: { backgroundImage: deviceModelImageUrl }\"");
@@ -181,26 +298,6 @@ WriteLiteral(" data-bind=\"text: sessionDeviceInfo().Arguments[6] + \' \' + sess
WriteLiteral("></td>\r\n </tr>\r\n </table>\r\n </div>\r\n <div" +
"");
WriteLiteral(" class=\"sessionProgress clearfix\"");
WriteLiteral(">\r\n <p");
WriteLiteral(" class=\"sessionStart\"");
WriteLiteral(" data-bind=\"text: startTime\"");
WriteLiteral("></p>\r\n <p");
WriteLiteral(" class=\"sessionStatus\"");
WriteLiteral(" data-bind=\"text: progressStatus\"");
WriteLiteral("></p>\r\n <div");
WriteLiteral(" data-bind=\"visible: !sessionEnded(), progressValue: progressValue\"");
WriteLiteral("></div>\r\n </div>\r\n <div");
WriteLiteral(" class=\"sessionInfoContainer clearfix\"");
WriteLiteral(">\r\n <div");
@@ -309,7 +406,7 @@ WriteLiteral(@">
var deviceBaseUrl = '");
#line 107 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 122 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Url.Action(MVC.Device.Show()));
@@ -318,7 +415,7 @@ WriteLiteral(@">
WriteLiteral("/\'\r\n var deviceModelImageUrl = \'");
#line 108 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 123 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Url.Action(MVC.API.DeviceModel.Image()));
@@ -327,7 +424,7 @@ WriteLiteral("/\'\r\n var deviceModelImageUrl = \'");
WriteLiteral("/\'\r\n var iconWarningUrl = \'url(");
#line 109 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 124 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Links.ClientSource.Style.Images.Status.warning32_png);
@@ -336,7 +433,7 @@ WriteLiteral("/\'\r\n var iconWarningUrl = \'url(");
WriteLiteral(")\';\r\n var iconErrorUrl = \'url(");
#line 110 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 125 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Links.ClientSource.Style.Images.Status.fail32_png);
@@ -352,39 +449,40 @@ WriteLiteral(")\';\r\n\r\n function pageViewModel() {\r\n var
"nction (e, d) {\r\n if (self.isotopeInited) {\r\n " +
"hostSessions.isotope(\'reloadItems\').isotope({ sortBy: \'original-order\' });\r\n " +
" }\r\n };\r\n }\r\n function sessionViewModel(id) " +
"{\r\n var self = this;\r\n\r\n self.title = ko.observable(id);\r\n" +
" self.messages = ko.observableArray();\r\n self.console = ko" +
".observableArray();\r\n self.serialNumber = ko.observable();\r\n " +
" self.sessionDeviceInfo = ko.observable();\r\n self.progressStatus = " +
"ko.observable();\r\n self.progressValue = ko.observable();\r\n " +
" self.startTime = ko.observable();\r\n self.sessionEnded = ko.observabl" +
"e(false);\r\n self.progressbar = null;\r\n self.hasError = ko." +
"observable(false);\r\n self.hasWarning = ko.observable(false);\r\n " +
" self.deviceModelId = ko.observable();\r\n self.deviceModelDescript" +
"ion = ko.computed(function () {\r\n var deviceModelId = self.device" +
"ModelId();\r\n var sessionDeviceInfo = self.sessionDeviceInfo();\r\n " +
" if (deviceModelId) {\r\n var dm = deviceModels[d" +
"eviceModelId];\r\n if (dm) {\r\n if (dm.De" +
"scription)\r\n return dm.Description;\r\n " +
" else\r\n return dm.Manufacturer + \' \' + dm.Mode" +
"l;\r\n }\r\n }\r\n if (sessionDeviceI" +
"nfo) {\r\n return sessionDeviceInfo.Arguments[6] + \' \' + sessio" +
"nDeviceInfo.Arguments[7];\r\n }\r\n });\r\n self." +
"deviceUrl = ko.computed(function () {\r\n var serialNumber = self.s" +
"erialNumber();\r\n if (serialNumber)\r\n return de" +
"viceBaseUrl + serialNumber;\r\n else\r\n return nu" +
"ll;\r\n });\r\n self.deviceModelImageUrl = ko.computed(functio" +
"n () {\r\n var deviceModelImage;\r\n if (self.deviceMo" +
"delId())\r\n deviceModelImage = \'url(\' + deviceModelImageUrl + " +
"self.deviceModelId() + \')\';\r\n else\r\n deviceMod" +
"elImage = \'url(\' + deviceModelImageUrl + \')\';\r\n if (self.hasError" +
"())\r\n return iconErrorUrl + \', \' + deviceModelImage;\r\n " +
" else\r\n if (self.hasWarning())\r\n " +
" return iconWarningUrl + \', \' + deviceModelImage;\r\n else\r\n " +
" return \'none, \' + deviceModelImage;\r\n });\r\n " +
" self.select = function (e, d) {\r\n vm.currentSession(self" +
");\r\n hostDialogSessions.dialog(\'open\');\r\n hostDial" +
"ogSessions.dialog(\'option\', \'title\', \'Device Enrolment: \' + self.title());\r\n " +
"{\r\n var self = this;\r\n\r\n self.id = id;\r\n self.t" +
"itle = ko.observable(id);\r\n self.isPending = ko.observable(false);\r\n " +
" self.messages = ko.observableArray();\r\n self.console = ko." +
"observableArray();\r\n self.serialNumber = ko.observable();\r\n " +
" self.sessionDeviceInfo = ko.observable();\r\n self.progressStatus = k" +
"o.observable();\r\n self.progressValue = ko.observable();\r\n " +
"self.startTime = ko.observable();\r\n self.sessionEnded = ko.observable" +
"(false);\r\n self.progressbar = null;\r\n self.hasError = ko.o" +
"bservable(false);\r\n self.hasWarning = ko.observable(false);\r\n " +
" self.deviceModelId = ko.observable();\r\n self.deviceModelDescripti" +
"on = ko.computed(function () {\r\n var deviceModelId = self.deviceM" +
"odelId();\r\n var sessionDeviceInfo = self.sessionDeviceInfo();\r\n " +
" if (deviceModelId) {\r\n var dm = deviceModels[de" +
"viceModelId];\r\n if (dm) {\r\n if (dm.Des" +
"cription)\r\n return dm.Description;\r\n " +
" else\r\n return dm.Manufacturer + \' \' + dm.Model" +
";\r\n }\r\n }\r\n if (sessionDeviceIn" +
"fo) {\r\n return sessionDeviceInfo.Arguments[6] + \' \' + session" +
"DeviceInfo.Arguments[7];\r\n }\r\n });\r\n self.d" +
"eviceUrl = ko.computed(function () {\r\n var serialNumber = self.se" +
"rialNumber();\r\n if (serialNumber)\r\n return dev" +
"iceBaseUrl + serialNumber;\r\n else\r\n return nul" +
"l;\r\n });\r\n self.deviceModelImageUrl = ko.computed(function" +
" () {\r\n var deviceModelImage;\r\n if (self.deviceMod" +
"elId())\r\n deviceModelImage = \'url(\' + deviceModelImageUrl + s" +
"elf.deviceModelId() + \')\';\r\n else\r\n deviceMode" +
"lImage = \'url(\' + deviceModelImageUrl + \')\';\r\n if (self.hasError(" +
"))\r\n return iconErrorUrl + \', \' + deviceModelImage;\r\n " +
" else\r\n if (self.hasWarning())\r\n " +
" return iconWarningUrl + \', \' + deviceModelImage;\r\n else\r\n " +
" return \'none, \' + deviceModelImage;\r\n });\r\n " +
" self.select = function (e, d) {\r\n vm.currentSession(self)" +
";\r\n hostDialogSessions.dialog(\'open\');\r\n hostDialo" +
"gSessions.dialog(\'option\', \'title\', \'Device Enrollment: \' + self.title());\r\n " +
" }\r\n }\r\n\r\n function parseLog(log) {\r\n if (log.Mo" +
"duleId === 50 && log.Arguments && log.Arguments.length > 0) {\r\n /" +
"/ find session\r\n var sessionId = log.Arguments[0];\r\n " +
@@ -413,33 +511,50 @@ WriteLiteral(")\';\r\n\r\n function pageViewModel() {\r\n var
"ion.sessionDeviceInfo(log);\r\n if (log.Arguments.lengt" +
"h >= 10 && log.Arguments[9])\r\n session.deviceMode" +
"lId(log.Arguments[9]);\r\n break;\r\n " +
" case 20: // SessionFinished\r\n session.sessionEnde" +
"d(true);\r\n if (session.hasError())\r\n " +
" session.progressStatus(\'Enrolment Finished with an Error\');\r\n " +
" else\r\n if (session.hasWar" +
"ning())\r\n session.progressStatus(\'Enrolment F" +
"inished with a Warning\');\r\n else\r\n " +
" session.progressStatus(\'Enrolment Finished Successfully\');\r" +
"\n session.messages.unshift(log);\r\n " +
" break;\r\n case 21: // SessionDiagnosticInformatio" +
"n\r\n session.console.push(log);\r\n " +
" break;\r\n case 22: // SessionWarning\r\n " +
" session.hasWarning(true);\r\n session.me" +
"ssages.unshift(log);\r\n break;\r\n " +
" case 23: // SessionError\r\n case 24: // SessionErrorWith" +
"Inner\r\n case 25: // SessionClientError\r\n " +
" session.hasError(true);\r\n session.messages" +
".unshift(log);\r\n break;\r\n defa" +
"ult:\r\n session.messages.unshift(log);\r\n " +
" }\r\n }\r\n }\r\n }\r\n function init() {\r" +
"\n hostDialogSessions.dialog({\r\n modal: true,\r\n " +
" height: 574,\r\n width: 900,\r\n resizable: fa" +
"lse,\r\n autoOpen: false\r\n });\r\n //hostDialog" +
"SessionsProgress.progressbar();\r\n\r\n // Create View Model\r\n " +
" vm = new pageViewModel();\r\n $.ajax({\r\n url: \'");
" case 14: // SessionPending\r\n session.isPending(tr" +
"ue);\r\n session.messages.unshift(log);\r\n " +
" session.progressValue(-1);\r\n session.pr" +
"ogressStatus(\'Pending enrollment approval\');\r\n break;" +
"\r\n case 15: // SessionPendingApproved\r\n " +
" session.isPending(false);\r\n session.message" +
"s.unshift(log);\r\n session.progressValue(-1);\r\n " +
" session.progressStatus(\'Enrollment approval, waiting for cl" +
"ient\');\r\n break;\r\n case 16: //" +
" SessionPendingRejected\r\n session.isPending(false);\r\n" +
" session.messages.unshift(log);\r\n " +
" session.progressValue(-1);\r\n session.progress" +
"Status(\'Enrollment rejected, waiting for client\');\r\n " +
"break;\r\n case 17: // SessionContinuing\r\n " +
" session.isPending(false);\r\n session.messag" +
"es.unshift(log);\r\n break;\r\n ca" +
"se 20: // SessionFinished\r\n session.sessionEnded(true" +
");\r\n session.isPending(false);\r\n " +
" if (session.hasError())\r\n session.progress" +
"Status(\'Enrollment Finished with an Error\');\r\n else\r\n" +
" if (session.hasWarning())\r\n " +
" session.progressStatus(\'Enrollment Finished with a Warning\');\r\n " +
" else\r\n session." +
"progressStatus(\'Enrollment Finished Successfully\');\r\n " +
" session.messages.unshift(log);\r\n break;\r\n " +
" case 21: // SessionDiagnosticInformation\r\n " +
" session.console.push(log);\r\n break;\r\n " +
" case 22: // SessionWarning\r\n session.hasWa" +
"rning(true);\r\n session.messages.unshift(log);\r\n " +
" break;\r\n case 23: // SessionError\r\n" +
" case 24: // SessionErrorWithInner\r\n " +
" case 25: // SessionClientError\r\n session.hasError(" +
"true);\r\n session.messages.unshift(log);\r\n " +
" break;\r\n default:\r\n " +
" session.messages.unshift(log);\r\n }\r\n }\r\n" +
" }\r\n }\r\n function init() {\r\n hostDialogSessi" +
"ons.dialog({\r\n modal: true,\r\n height: 574,\r\n " +
" width: 900,\r\n resizable: false,\r\n autoOp" +
"en: false\r\n });\r\n //hostDialogSessionsProgress.progressbar" +
"();\r\n\r\n // Create View Model\r\n vm = new pageViewModel();\r\n" +
" $.ajax({\r\n url: \'");
#line 274 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 314 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Url.Action(MVC.API.DeviceModel.Index()));
@@ -473,7 +588,7 @@ WriteLiteral(@"',
url: '");
#line 299 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 339 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Url.Action(MVC.API.Logging.RetrieveEvents()));
@@ -512,7 +627,7 @@ WriteLiteral(@"',
$.connection.hub.qs = { LogModules: '");
#line 329 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
#line 369 "..\..\Areas\Config\Views\Enrolment\Status.cshtml"
Write(Disco.Services.Devices.Enrolment.EnrolmentLog.Current.LiveLogGroupName);
@@ -537,7 +652,15 @@ WriteLiteral("\' };\r\n $.connection.hub.error(onHubFailed);\r\n\r\n
" \'Close\': function () {\r\n " +
" $(this).dialog(\'destroy\');\r\n }\r\n " +
" }\r\n });\r\n }\r\n }" +
"\r\n }\r\n init();\r\n });\r\n</script>\r\n");
"\r\n }\r\n $(\'#dialogSession\').on(\'click\', \'#formResolveSessionPending" +
" button\', function (e) {\r\n const $button = $(this);\r\n cons" +
"t $form = $button.closest(\'form\');\r\n const body = new FormData($form[" +
"0]);\r\n body.append(\'approve\', $button.val());\r\n fetch($for" +
"m.attr(\'action\'), {\r\n method: \'POST\',\r\n body: body" +
"\r\n }).then(function (response) {\r\n if (!response.ok) {" +
"\r\n alert(\'Failed to resolve pending session: \' + response.sta" +
"tusText);\r\n }\r\n });\r\n });\r\n init();\r\n " +
" });\r\n</script>\r\n");
}
}
+9 -2
View File
@@ -473,6 +473,10 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.message {
#enrolStatus #sessions .session > h3 span.details {
font-size: 0.8em;
}
#enrolStatus #sessions .session > h3 i {
float: right;
color: #F0A30A;
}
#enrolStatus #sessions .session > p.sessionStart {
color: #888;
font-size: 0.8em;
@@ -489,7 +493,6 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.message {
background-color: #DFE1F8;
}
#dialogSession .sessionHeader {
width: 400px;
float: left;
padding: 0 0 0 134px;
background-repeat: no-repeat, no-repeat;
@@ -516,7 +519,8 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.message {
}
#dialogSession .sessionProgress {
width: 320px;
float: right;
position: absolute;
right: 1em;
text-align: right;
}
#dialogSession .sessionProgress > p.sessionStart {
@@ -528,6 +532,9 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.message {
overflow: hidden;
margin-bottom: 3px;
}
#dialogSession .sessionProgress div.reason {
margin-bottom: 3px;
}
#dialogSession .sessionInfoContainer > div {
float: left;
width: 428px;
+11 -2
View File
@@ -479,6 +479,11 @@ div.logEventsViewport {
span.details {
font-size: .8em;
}
i {
float: right;
color: @ThemeAmber;
}
}
& > p.sessionStart {
@@ -504,7 +509,6 @@ div.logEventsViewport {
#dialogSession {
.sessionHeader {
width: 400px;
float: left;
padding: 0 0 0 134px;
background-repeat: no-repeat, no-repeat;
@@ -535,7 +539,8 @@ div.logEventsViewport {
.sessionProgress {
width: 320px;
float: right;
position: absolute;
right: 1em;
text-align: right;
& > p.sessionStart {
@@ -548,6 +553,10 @@ div.logEventsViewport {
overflow: hidden;
margin-bottom: 3px;
}
& div.reason {
margin-bottom: 3px;
}
}
.sessionInfoContainer {
File diff suppressed because one or more lines are too long
+26
View File
@@ -97,6 +97,32 @@
height: 50px;
font-size: 0.6em;
}
#layout_PageHeading #pendingEnrollments {
position: relative;
float: right;
border: 1px dashed #ddd;
background-color: #fff;
font-size: 0.6em;
line-height: 1em;
padding: 10px 10px 4px 70px;
text-align: right;
height: 50px;
}
#layout_PageHeading #pendingEnrollments i {
position: absolute;
display: block;
height: 64px;
width: 64px;
vertical-align: middle;
margin-left: -75px;
top: 8px;
font-size: 50px;
color: #e51400;
}
#layout_PageHeading #pendingEnrollments a.button {
font-size: 12px;
margin-top: 8px;
}
#Jobs_Index_MyJobs {
margin-bottom: 10px;
}
+29
View File
@@ -25,6 +25,35 @@
height: 50px;
font-size: 0.6em;
}
#pendingEnrollments {
position: relative;
float: right;
border: 1px dashed #ddd;
background-color: @white;
font-size: 0.6em;
line-height: 1em;
padding: 10px 10px 4px 70px;
text-align: right;
height: 50px;
i {
position: absolute;
display: block;
height: 64px;
width: 64px;
vertical-align: middle;
margin-left: -75px;
top: 8px;
font-size: 50px;
color: @ButtonAlertColour;
}
a.button {
font-size: @FontSizeDefault;
margin-top: 8px;
}
}
}
#Jobs_Index_MyJobs {
File diff suppressed because one or more lines are too long
+4
View File
@@ -4,6 +4,7 @@ using Disco.Models.Services.Jobs.JobLists;
using Disco.Models.UI.Job;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Devices.Enrolment;
using Disco.Services.Jobs;
using Disco.Services.Jobs.JobLists;
using Disco.Services.Jobs.JobQueues;
@@ -46,6 +47,9 @@ namespace Disco.Web.Controllers
if (Authorization.Has(Claims.Job.ShowDailyChart))
m.DailyOpenedClosedStatistics = DailyOpenedClosed.Data(Database, true);
if (Authorization.Has(Claims.Device.Actions.EnrolDevices))
m.PendingEnrollments = WindowsDeviceEnrolment.GetPendingEnrolments();
// UI Extensions
UIExtensions.ExecuteExtensions<JobIndexModel>(this.ControllerContext, m);
+17 -13
View File
@@ -208,6 +208,7 @@
<Compile Include="Areas\API\Controllers\AuthorizationRoleController.cs" />
<Compile Include="Areas\API\Controllers\DocumentTemplatePackageController.cs" />
<Compile Include="Areas\API\Controllers\DeviceFlagAssignmentController.cs" />
<Compile Include="Areas\API\Controllers\EnrollmentController.cs" />
<Compile Include="Areas\API\Controllers\UserFlagAssignmentController.cs" />
<Compile Include="Areas\API\Controllers\DeviceFlagController.cs" />
<Compile Include="Areas\API\Controllers\UserFlagController.cs" />
@@ -678,6 +679,9 @@
<Compile Include="Extensions\T4MVC\API.DocumentTemplatePackageController.generated.cs">
<DependentUpon>T4MVC.tt</DependentUpon>
</Compile>
<Compile Include="Extensions\T4MVC\API.EnrollmentController.generated.cs">
<DependentUpon>T4MVC.tt</DependentUpon>
</Compile>
<Compile Include="Extensions\T4MVC\Config.DeviceFlagController.generated.cs">
<DependentUpon>T4MVC.tt</DependentUpon>
</Compile>
@@ -1339,30 +1343,30 @@
<Generator>RazorGenerator</Generator>
<LastGenOutput>_DeviceGroupDocumentBulkGenerate.generated.cs</LastGenOutput>
</None>
<Content Include="Areas\Config\Views\DeviceFlag\Create.cshtml">
<None Include="Areas\Config\Views\DeviceFlag\Create.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Create.generated.cs</LastGenOutput>
</Content>
<Content Include="Areas\Config\Views\DeviceFlag\Export.cshtml">
</None>
<None Include="Areas\Config\Views\DeviceFlag\Export.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Export.generated.cs</LastGenOutput>
</Content>
<Content Include="Areas\Config\Views\DeviceFlag\Index.cshtml">
</None>
<None Include="Areas\Config\Views\DeviceFlag\Index.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Index.generated.cs</LastGenOutput>
</Content>
<Content Include="Areas\Config\Views\DeviceFlag\Show.cshtml">
</None>
<None Include="Areas\Config\Views\DeviceFlag\Show.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Show.generated.cs</LastGenOutput>
</Content>
</None>
<None Include="Areas\Config\Views\UserFlag\Create.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Create.generated.cs</LastGenOutput>
</None>
<Content Include="Areas\Config\Views\UserFlag\Export.cshtml">
<None Include="Areas\Config\Views\UserFlag\Export.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Export.generated.cs</LastGenOutput>
</Content>
</None>
<None Include="Areas\Config\Views\UserFlag\Index.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Index.generated.cs</LastGenOutput>
@@ -1505,7 +1509,7 @@
<DependentUpon>Disco-DataTableHelpers.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Scripts\Modules\Disco-DocumentGenerator\disco.documentgenerator.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-DocumentGenerator\disco.documentgenerator.js" Condition=" '$(Configuration)' == 'Debug' " />
<None Include="ClientSource\Scripts\Modules\Disco-DocumentGenerator.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-DocumentGenerator.js" Condition=" '$(Configuration)' == 'Debug' " />
<Content Include="ClientSource\Scripts\Modules\Disco-DocumentGenerator.min.js">
@@ -1941,10 +1945,10 @@
<Generator>RazorGenerator</Generator>
<LastGenOutput>AddOffline.generated.cs</LastGenOutput>
</None>
<Content Include="Views\Device\DeviceParts\_Flags.cshtml">
<None Include="Views\Device\DeviceParts\_Flags.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_Flags.generated.cs</LastGenOutput>
</Content>
</None>
<None Include="Views\Device\ImportHeaders.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>ImportHeaders.generated.cs</LastGenOutput>
@@ -0,0 +1,169 @@
// <auto-generated />
// This file was generated by a T4 template.
// Don't change it directly as your change would get overwritten. Instead, make changes
// to the .tt file (i.e. the T4 template) and save it to regenerate this file.
// Make sure the compiler doesn't complain about missing Xml comments and CLS compliance
// 0108: suppress "Foo hides inherited member Foo. Use the new keyword if hiding was intended." when a controller and its abstract parent are both processed
// 0114: suppress "Foo.BarController.Baz()' hides inherited member 'Qux.BarController.Baz()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword." when an action (with an argument) overrides an action in a parent controller
#pragma warning disable 1591, 3008, 3009, 0108, 0114
#region T4MVC
using System;
using System.Diagnostics;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Mvc.Html;
using System.Web.Routing;
using T4MVC;
namespace Disco.Web.Areas.API.Controllers
{
public partial class EnrollmentController
{
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public EnrollmentController() { }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
protected EnrollmentController(Dummy d) { }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
protected RedirectToRouteResult RedirectToAction(ActionResult result)
{
var callInfo = result.GetT4MVCResult();
return RedirectToRoute(callInfo.RouteValueDictionary);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
protected RedirectToRouteResult RedirectToAction(Task<ActionResult> taskResult)
{
return RedirectToAction(taskResult.Result);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
protected RedirectToRouteResult RedirectToActionPermanent(ActionResult result)
{
var callInfo = result.GetT4MVCResult();
return RedirectToRoutePermanent(callInfo.RouteValueDictionary);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
protected RedirectToRouteResult RedirectToActionPermanent(Task<ActionResult> taskResult)
{
return RedirectToActionPermanent(taskResult.Result);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult ResolveSessionPending()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.ResolveSessionPending);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult PendingTimeoutMinutes()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.PendingTimeoutMinutes);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public EnrollmentController Actions { get { return MVC.API.Enrollment; } }
[GeneratedCode("T4MVC", "2.0")]
public readonly string Area = "API";
[GeneratedCode("T4MVC", "2.0")]
public readonly string Name = "Enrollment";
[GeneratedCode("T4MVC", "2.0")]
public const string NameConst = "Enrollment";
[GeneratedCode("T4MVC", "2.0")]
static readonly ActionNamesClass s_actions = new ActionNamesClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionNamesClass ActionNames { get { return s_actions; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNamesClass
{
public readonly string ResolveSessionPending = "ResolveSessionPending";
public readonly string PendingTimeoutMinutes = "PendingTimeoutMinutes";
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNameConstants
{
public const string ResolveSessionPending = "ResolveSessionPending";
public const string PendingTimeoutMinutes = "PendingTimeoutMinutes";
}
static readonly ActionParamsClass_ResolveSessionPending s_params_ResolveSessionPending = new ActionParamsClass_ResolveSessionPending();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_ResolveSessionPending ResolveSessionPendingParams { get { return s_params_ResolveSessionPending; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_ResolveSessionPending
{
public readonly string sessionId = "sessionId";
public readonly string approve = "approve";
public readonly string reason = "reason";
}
static readonly ActionParamsClass_PendingTimeoutMinutes s_params_PendingTimeoutMinutes = new ActionParamsClass_PendingTimeoutMinutes();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_PendingTimeoutMinutes PendingTimeoutMinutesParams { get { return s_params_PendingTimeoutMinutes; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_PendingTimeoutMinutes
{
public readonly string PendingTimeoutMinutes = "PendingTimeoutMinutes";
}
static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ViewsClass
{
static readonly _ViewNamesClass s_ViewNames = new _ViewNamesClass();
public _ViewNamesClass ViewNames { get { return s_ViewNames; } }
public class _ViewNamesClass
{
}
}
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public partial class T4MVC_EnrollmentController : Disco.Web.Areas.API.Controllers.EnrollmentController
{
public T4MVC_EnrollmentController() : base(Dummy.Instance) { }
[NonAction]
partial void ResolveSessionPendingOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string sessionId, bool approve, string reason);
[NonAction]
public override System.Web.Mvc.ActionResult ResolveSessionPending(string sessionId, bool approve, string reason)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.ResolveSessionPending);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "sessionId", sessionId);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "approve", approve);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "reason", reason);
ResolveSessionPendingOverride(callInfo, sessionId, approve, reason);
return callInfo;
}
[NonAction]
partial void PendingTimeoutMinutesOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int PendingTimeoutMinutes);
[NonAction]
public override System.Web.Mvc.ActionResult PendingTimeoutMinutes(int PendingTimeoutMinutes)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.PendingTimeoutMinutes);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "PendingTimeoutMinutes", PendingTimeoutMinutes);
PendingTimeoutMinutesOverride(callInfo, PendingTimeoutMinutes);
return callInfo;
}
}
}
#endregion T4MVC
#pragma warning restore 1591, 3008, 3009, 0108, 0114
+1
View File
@@ -62,6 +62,7 @@ namespace T4MVC
public Disco.Web.Areas.API.Controllers.DeviceProfileController DeviceProfile = new Disco.Web.Areas.API.Controllers.T4MVC_DeviceProfileController();
public Disco.Web.Areas.API.Controllers.DocumentTemplateController DocumentTemplate = new Disco.Web.Areas.API.Controllers.T4MVC_DocumentTemplateController();
public Disco.Web.Areas.API.Controllers.DocumentTemplatePackageController DocumentTemplatePackage = new Disco.Web.Areas.API.Controllers.T4MVC_DocumentTemplatePackageController();
public Disco.Web.Areas.API.Controllers.EnrollmentController Enrollment = new Disco.Web.Areas.API.Controllers.T4MVC_EnrollmentController();
public Disco.Web.Areas.API.Controllers.ExpressionsController Expressions = new Disco.Web.Areas.API.Controllers.T4MVC_ExpressionsController();
public Disco.Web.Areas.API.Controllers.JobController Job = new Disco.Web.Areas.API.Controllers.T4MVC_JobController();
public Disco.Web.Areas.API.Controllers.JobPreferencesController JobPreferences = new Disco.Web.Areas.API.Controllers.T4MVC_JobPreferencesController();
+3 -1
View File
@@ -1,4 +1,5 @@
using Disco.Models.Services.Job.Statistics;
using Disco.Models.ClientServices;
using Disco.Models.Services.Job.Statistics;
using Disco.Models.Services.Jobs.JobLists;
using Disco.Models.UI.Job;
using System.Collections.Generic;
@@ -9,6 +10,7 @@ namespace Disco.Web.Models.Job
{
public JobTableModel MyJobs { get; set; }
public JobTableModel StaleJobs { get; set; }
public List<EnrolResponse> PendingEnrollments { get; set; }
public List<DailyOpenedClosedItem> DailyOpenedClosedStatistics { get; set; }
}
+17 -1
View File
@@ -22,7 +22,7 @@
<div id="chartHostJobDailyOpenedClosed" style="height: 175px;">
</div>
@{
var jsonData = new HtmlString(Json.Encode(Model.DailyOpenedClosedStatistics));
var jsonData = new HtmlString(Json.Encode(Model.DailyOpenedClosedStatistics));
}
<script type="text/javascript">
(function () {
@@ -144,4 +144,20 @@
<h2>Stale Jobs (@Model.StaleJobs.Items.Count())</h2>
@Html.Partial(MVC.Shared.Views._JobTable, Model.StaleJobs, new ViewDataDictionary())
</div>
}
@if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices))
{
<div id="pendingEnrollments">
<i class="fa fa-exclamation-circle info"></i>
<div>There are device enrollments pending approval.</div>
<a href="@Url.Action(MVC.Config.Enrolment.Status())" class="button small alert" target="_blank">View Enrollments</a>
</div>
<script>
$(function () {
var layout_PageHeading = $('#layout_PageHeading').height(80);
$('#pendingEnrollments')
.detach()
.appendTo(layout_PageHeading);
});
</script>
}
+76 -29
View File
@@ -131,7 +131,7 @@ WriteLiteral(">\r\n </div>\r\n");
#line 24 "..\..\Views\Job\Index.cshtml"
var jsonData = new HtmlString(Json.Encode(Model.DailyOpenedClosedStatistics));
var jsonData = new HtmlString(Json.Encode(Model.DailyOpenedClosedStatistics));
#line default
@@ -174,34 +174,34 @@ WriteLiteral(">\r\n (function () {\r\n var cha
"top\',\r\n y: 0,\r\n " +
" floating: true,\r\n borderWidth: 0,\r\n " +
" itemStyle: {\r\n " +
" color: \'#333\',\n fontWeight: \'normal" +
"\'\r\n }\r\n },\r\n " +
" xAxis: {\r\n type" +
": \'datetime\',\r\n tickInterval: 7 * 24 * 3600 *" +
" 1000, // week\r\n tickWidth: 1,\r\n " +
" gridLineWidth: 1,\r\n da" +
"teTimeLabelFormats: {\r\n week: \'%e %b\'\r\n " +
" }\r\n },\r\n " +
" yAxis: [{\r\n title: {" +
"\r\n text: null\r\n " +
" },\r\n labels: {\r\n " +
" enabled: false\r\n },\r\n " +
" min: 0\r\n }, {\r\n " +
" title: {\r\n " +
" text: null\r\n },\r\n " +
" labels: {\r\n enabled: false\r\n" +
" },\r\n min:" +
" 0\r\n }],\r\n series:" +
" [{\r\n name: \'Total Open Jobs\',\r\n " +
" data: dataTotalOpenJobs,\r\n " +
" yAxis: 1\r\n }, {\r\n " +
" name: \'Closed Jobs\',\r\n data: dataClo" +
"sedJobs\r\n }, {\r\n " +
" name: \'Opened Jobs\',\r\n data: dataOpenedJob" +
"s\r\n }],\r\n credits:" +
" {\r\n enabled: false\r\n " +
" }\r\n });\r\n });\r\n " +
" }\r\n chartData = $.parseJSON(\'");
" color: \'#333\',\r\n fontWeight: \'norma" +
"l\'\r\n }\r\n },\r\n " +
" xAxis: {\r\n typ" +
"e: \'datetime\',\r\n tickInterval: 7 * 24 * 3600 " +
"* 1000, // week\r\n tickWidth: 1,\r\n " +
" gridLineWidth: 1,\r\n d" +
"ateTimeLabelFormats: {\r\n week: \'%e %b\'\r\n " +
" }\r\n },\r\n " +
" yAxis: [{\r\n title: " +
"{\r\n text: null\r\n " +
" },\r\n labels: {\r\n " +
" enabled: false\r\n },\r\n " +
" min: 0\r\n }, {\r\n" +
" title: {\r\n " +
" text: null\r\n },\r\n " +
" labels: {\r\n enabled: false\r" +
"\n },\r\n min" +
": 0\r\n }],\r\n series" +
": [{\r\n name: \'Total Open Jobs\',\r\n " +
" data: dataTotalOpenJobs,\r\n " +
" yAxis: 1\r\n }, {\r\n " +
" name: \'Closed Jobs\',\r\n data: dataCl" +
"osedJobs\r\n }, {\r\n " +
" name: \'Opened Jobs\',\r\n data: dataOpenedJo" +
"bs\r\n }],\r\n credits" +
": {\r\n enabled: false\r\n " +
" }\r\n });\r\n });\r\n " +
" }\r\n chartData = $.parseJSON(\'");
#line 126 "..\..\Views\Job\Index.cshtml"
@@ -300,6 +300,53 @@ WriteLiteral("\r\n </div>\r\n");
#line 147 "..\..\Views\Job\Index.cshtml"
}
#line default
#line hidden
#line 148 "..\..\Views\Job\Index.cshtml"
if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices))
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" id=\"pendingEnrollments\"");
WriteLiteral(">\r\n <i");
WriteLiteral(" class=\"fa fa-exclamation-circle info\"");
WriteLiteral("></i>\r\n <div>There are device enrollments pending approval.</div>\r\n " +
" <a");
WriteAttribute("href", Tuple.Create(" href=\"", 6766), Tuple.Create("\"", 6815)
#line 153 "..\..\Views\Job\Index.cshtml"
, Tuple.Create(Tuple.Create("", 6773), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Config.Enrolment.Status())
#line default
#line hidden
, 6773), false)
);
WriteLiteral(" class=\"button small alert\"");
WriteLiteral(" target=\"_blank\"");
WriteLiteral(">View Enrollments</a>\r\n </div>\r\n");
WriteLiteral(" <script>\r\n $(function () {\r\n var layout_PageHeading = $(\'#l" +
"ayout_PageHeading\').height(80);\r\n $(\'#pendingEnrollments\')\r\n " +
" .detach()\r\n .appendTo(layout_PageHeading);\r\n });\r\n " +
" </script>\r\n");
#line 163 "..\..\Views\Job\Index.cshtml"
}
#line default
#line hidden