feature: bulk generating user documents
This commit is contained in:
@@ -171,6 +171,7 @@
|
||||
<Compile Include="UI\Config\DeviceProfile\ConfigDeviceProfileIndexModel.cs" />
|
||||
<Compile Include="UI\Config\DeviceProfile\ConfigDeviceProfileIndexModelItem.cs" />
|
||||
<Compile Include="UI\Config\DeviceProfile\ConfigDeviceProfileShowModel.cs" />
|
||||
<Compile Include="UI\Config\DocumentTemplate\ConfigDocumentTemplateBulkGenerate.cs" />
|
||||
<Compile Include="UI\Config\DocumentTemplate\ConfigDocumentTemplateCreatePackageModel.cs" />
|
||||
<Compile Include="UI\Config\DocumentTemplate\ConfigDocumentTemplateCreateModel.cs" />
|
||||
<Compile Include="UI\Config\DocumentTemplate\ConfigDocumentTemplateExpressionBrowserModel.cs" />
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Disco.Models.UI.Config.DocumentTemplate
|
||||
{
|
||||
public interface ConfigDocumentTemplateBulkGenerate : BaseUIModel
|
||||
{
|
||||
Repository.DocumentTemplate DocumentTemplate { get; set; }
|
||||
int TemplatePageCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,21 @@ using Disco.Services.Authorization;
|
||||
using Disco.Services.Documents;
|
||||
using Disco.Services.Documents.ManagedGroups;
|
||||
using Disco.Services.Interop.ActiveDirectory;
|
||||
using Disco.Services.Plugins;
|
||||
using Disco.Services.Plugins.Features.DocumentHandlerProvider;
|
||||
using Disco.Services.Tasks;
|
||||
using Disco.Services.Users;
|
||||
using Disco.Services.Web;
|
||||
using Disco.Web.Areas.API.Models.DocumentTemplate;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
namespace Disco.Web.Areas.API.Controllers
|
||||
{
|
||||
@@ -700,43 +706,416 @@ namespace Disco.Web.Areas.API.Controllers
|
||||
return File(stream, "application/pdf", fileName);
|
||||
}
|
||||
|
||||
public virtual ActionResult Generate(string id, string TargetId)
|
||||
[DiscoAuthorize(Claims.Config.DocumentTemplate.BulkGenerate)]
|
||||
public virtual ActionResult BulkGenerateDownload(string id, string fileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrWhiteSpace(TargetId))
|
||||
throw new ArgumentNullException(nameof(TargetId));
|
||||
var stream = DocumentBulkGenerateTask.GetCached(Database, id);
|
||||
return File(stream, "application/pdf", fileName);
|
||||
}
|
||||
|
||||
// get template
|
||||
var template = Database.DocumentTemplates.Find(id);
|
||||
if (template == null)
|
||||
throw new ArgumentException("Invalid document template id", nameof(id));
|
||||
|
||||
// validate authorization
|
||||
switch (template.Scope)
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddUsers(string userIds)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(userIds))
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var dataIds = userIds.Split(new string[] { Environment.NewLine, ",", ";" }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).Where(d => !string.IsNullOrEmpty(d)).ToList();
|
||||
var results = new List<BulkGenerateUserModel>(dataIds.Count);
|
||||
foreach (var dataId in dataIds)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
Authorization.Require(Claims.Device.Actions.GenerateDocuments);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
Authorization.Require(Claims.Job.Actions.GenerateDocuments);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
Authorization.Require(Claims.User.Actions.GenerateDocuments);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unknown DocumentType Scope");
|
||||
var accountId = ActiveDirectory.ParseDomainAccountId(dataId);
|
||||
|
||||
if (UserService.TryGetUser(accountId, Database, true, out var user))
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = user.UserId,
|
||||
DisplayName = user.DisplayName,
|
||||
Scope = $"Matched '{dataId}'",
|
||||
IsError = false,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var adObject = ActiveDirectory.RetrieveADObject(accountId, true);
|
||||
|
||||
if (adObject == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = dataId,
|
||||
DisplayName = dataId,
|
||||
Scope = $"Unknown User or Security Group '{dataId}'",
|
||||
IsError = true,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (adObject is ADGroup group)
|
||||
{
|
||||
foreach (var adUser in group.GetUserMembersRecursive())
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = adUser.Id,
|
||||
DisplayName = adUser.DisplayName,
|
||||
Scope = $"Group Member '{group.Name}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = dataId,
|
||||
DisplayName = dataId,
|
||||
Scope = $"Unexpected AD Object found at '{adObject.DistinguishedName}'",
|
||||
IsError = true,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resolve target
|
||||
var target = template.ResolveScopeTarget(Database, TargetId);
|
||||
if (target == null)
|
||||
throw new ArgumentException("Target not found", nameof(TargetId));
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddGroupMembers(string groupId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(groupId))
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var results = new List<BulkGenerateUserModel>();
|
||||
var accountId = ActiveDirectory.ParseDomainAccountId(groupId);
|
||||
|
||||
var adObject = ActiveDirectory.RetrieveADObject(accountId, true);
|
||||
|
||||
if (adObject == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = groupId,
|
||||
DisplayName = groupId,
|
||||
Scope = $"Unknown Security Group '{groupId}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else if (adObject is ADGroup group)
|
||||
{
|
||||
foreach (var adUser in group.GetUserMembersRecursive())
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = adUser.Id,
|
||||
DisplayName = adUser.DisplayName,
|
||||
Scope = $"Group Member '{group.Name}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (adObject is ADUserAccount user)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = user.Id,
|
||||
DisplayName = user.DisplayName,
|
||||
Scope = $"Matched '{groupId}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = groupId,
|
||||
DisplayName = groupId,
|
||||
Scope = $"Unexpected AD Object found at '{adObject.DistinguishedName}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddUserFlag(int flagId)
|
||||
{
|
||||
if (flagId <= 0)
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var results = new List<BulkGenerateUserModel>();
|
||||
|
||||
var flag = Database.UserFlags.Include(f => f.UserFlagAssignments.Select(a => a.User)).FirstOrDefault(f => f.Id == flagId);
|
||||
|
||||
if (flag == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = flagId.ToString(),
|
||||
DisplayName = flagId.ToString(),
|
||||
Scope = $"Unknown User Flag '{flagId}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var assignments = flag.UserFlagAssignments.Where(a => a.RemovedDate == null).ToList();
|
||||
|
||||
if (assignments.Count == 0)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = flag.Name,
|
||||
DisplayName = flag.Name,
|
||||
Scope = $"User Flag has no active assignments",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var assignment in assignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.UserId,
|
||||
DisplayName = assignment.User.DisplayName,
|
||||
Scope = $"Assigned User Flag '{flag.Name}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddDeviceProfile(int deviceProfileId)
|
||||
{
|
||||
if (deviceProfileId <= 0)
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var results = new List<BulkGenerateUserModel>();
|
||||
|
||||
var profile = Database.DeviceProfiles.Include(p => p.Devices.Select(a => a.AssignedUser)).FirstOrDefault(f => f.Id == deviceProfileId);
|
||||
|
||||
if (profile == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = deviceProfileId.ToString(),
|
||||
DisplayName = deviceProfileId.ToString(),
|
||||
Scope = $"Unknown Device Profile '{deviceProfileId}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var assignments = profile.Devices.Where(d => d.AssignedUser != null).ToList();
|
||||
|
||||
if (assignments.Count == 0)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = profile.Name,
|
||||
DisplayName = profile.Name,
|
||||
Scope = $"Device Profile has no devices with active assignments",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var assignment in assignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.AssignedUserId,
|
||||
DisplayName = assignment.AssignedUser.DisplayName,
|
||||
Scope = $"Device Profile '{profile.Name}' Matches Assigned Device '{assignment.SerialNumber}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddDeviceBatch(int deviceBatchId)
|
||||
{
|
||||
if (deviceBatchId <= 0)
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var results = new List<BulkGenerateUserModel>();
|
||||
|
||||
var batch = Database.DeviceBatches.Include(p => p.Devices.Select(a => a.AssignedUser)).FirstOrDefault(f => f.Id == deviceBatchId);
|
||||
|
||||
if (batch == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = deviceBatchId.ToString(),
|
||||
DisplayName = deviceBatchId.ToString(),
|
||||
Scope = $"Unknown Device Batch '{deviceBatchId}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var assignments = batch.Devices.Where(d => d.AssignedUser != null).ToList();
|
||||
|
||||
if (assignments.Count == 0)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = batch.Name,
|
||||
DisplayName = batch.Name,
|
||||
Scope = $"Device Batch has no devices with active assignments",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var assignment in assignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.AssignedUserId,
|
||||
DisplayName = assignment.AssignedUser.DisplayName,
|
||||
Scope = $"Device Batch '{batch.Name}' Matches Assigned Device '{assignment.SerialNumber}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public virtual ActionResult BulkGenerateAddDocumentAttachment(string documentTemplateId, DateTime? threshold)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(documentTemplateId))
|
||||
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
var results = new List<BulkGenerateUserModel>();
|
||||
|
||||
var template = Database.DocumentTemplates.FirstOrDefault(f => f.Id == documentTemplateId);
|
||||
|
||||
if (template == null)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = documentTemplateId,
|
||||
DisplayName = documentTemplateId,
|
||||
Scope = $"Unknown Document Template '{documentTemplateId}'",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (template.AttachmentType)
|
||||
{
|
||||
case AttachmentTypes.Device:
|
||||
var deviceAssignments = Database.DeviceAttachments
|
||||
.Include(a => a.Device.AssignedUser)
|
||||
.Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.Device.AssignedUserId != null)
|
||||
.ToList();
|
||||
foreach (var assignment in deviceAssignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.Device.AssignedUserId,
|
||||
DisplayName = assignment.Device.AssignedUser.DisplayName,
|
||||
Scope = $"Document Template '{template.Id}' Attachment Matches Assigned Device '{assignment.Device.SerialNumber}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case AttachmentTypes.Job:
|
||||
var jobAssignments = Database.JobAttachments
|
||||
.Include(a => a.Job.User)
|
||||
.Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.Job.UserId != null)
|
||||
.ToList();
|
||||
foreach (var assignment in jobAssignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.Job.UserId,
|
||||
DisplayName = assignment.Job.User.DisplayName,
|
||||
Scope = $"Document Template '{template.Id}' Attachment Matches Job '{assignment.Job.Id}'",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case AttachmentTypes.User:
|
||||
var userAssignments = Database.UserAttachments
|
||||
.Include(a => a.User)
|
||||
.Where(a => a.DocumentTemplateId == template.Id && (threshold == null || a.Timestamp > threshold) && a.UserId != null)
|
||||
.ToList();
|
||||
foreach (var assignment in userAssignments)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = assignment.UserId,
|
||||
DisplayName = assignment.User.DisplayName,
|
||||
Scope = $"Document Template '{template.Id}' Attachment Matches User",
|
||||
IsError = false,
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
if (results.Count == 0)
|
||||
{
|
||||
if (threshold.HasValue)
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = template.Id,
|
||||
DisplayName = template.Id,
|
||||
Scope = $"Document Template has no attachments with associated users after {threshold:yyyy-MM-dd}",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
results.Add(new BulkGenerateUserModel()
|
||||
{
|
||||
Id = template.Id,
|
||||
DisplayName = template.Id,
|
||||
Scope = $"Document Template has no attachments with associated users",
|
||||
IsError = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var distinctSet = new HashSet<string>(StringComparer.Ordinal);
|
||||
results = results.Where(r => distinctSet.Add(r.Id)).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
return Json(results);
|
||||
}
|
||||
|
||||
public virtual ActionResult Generate(string id, string TargetId)
|
||||
{
|
||||
Disco.Services.DocumentTemplateExtensions.GetTemplateAndTarget(Database, Authorization, id, TargetId, out var template, out var target, out _);
|
||||
|
||||
// generate document
|
||||
var timestamp = DateTime.Now;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Disco.Web.Areas.API.Models.DocumentTemplate
|
||||
{
|
||||
public class BulkGenerateUserModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Scope { get; set; }
|
||||
public bool IsError { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ using Disco.Services.Documents.ManagedGroups;
|
||||
using Disco.Services.Expressions;
|
||||
using Disco.Services.Plugins.Features.UIExtension;
|
||||
using Disco.Services.Web;
|
||||
using Disco.Web.Areas.Config.Models.DocumentTemplate;
|
||||
using Disco.Web.Areas.Config.Views.DocumentTemplate;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -214,6 +216,63 @@ namespace Disco.Web.Areas.Config.Controllers
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments)]
|
||||
public virtual ActionResult BulkGenerate(string id)
|
||||
{
|
||||
var m = new BulkGenerateModel()
|
||||
{
|
||||
DocumentTemplate = Database.DocumentTemplates.FirstOrDefault(at => at.Id == id),
|
||||
};
|
||||
if (m.DocumentTemplate == null)
|
||||
throw new ArgumentException("Invalid Document Template Id", nameof(id));
|
||||
|
||||
if (m.DocumentTemplate.Scope != DocumentTemplate.DocumentTemplateScopes.User)
|
||||
throw new NotSupportedException("Only user-scoped document templates can be bulk generated using this method");
|
||||
|
||||
m.TemplatePageCount = m.DocumentTemplate.PdfPageHasAttachmentId(Database).Count;
|
||||
m.UserFlags = Database.UserFlags.Select(f => new BulkGenerateModel.ItemWithCount<UserFlag>()
|
||||
{
|
||||
Item = f,
|
||||
Count = f.UserFlagAssignments.Where(a => a.RemovedDate == null).Count(),
|
||||
}).ToList();
|
||||
m.DeviceProfiles = Database.DeviceProfiles.Select(p => new BulkGenerateModel.ItemWithCount<DeviceProfile>()
|
||||
{
|
||||
Item = p,
|
||||
Count = p.Devices.Where(d => d.AssignedUserId != null).Count(),
|
||||
}).ToList();
|
||||
m.DeviceBatches = Database.DeviceBatches.Select(p => new BulkGenerateModel.ItemWithCount<DeviceBatch>()
|
||||
{
|
||||
Item = p,
|
||||
Count = p.Devices.Where(d => d.AssignedUserId != null).Count(),
|
||||
}).ToList();
|
||||
m.DocumentTemplates = Database.DocumentTemplates.Select(dt => new BulkGenerateModel.ItemWithCount<DocumentTemplate>()
|
||||
{
|
||||
Item = dt,
|
||||
}).ToList();
|
||||
foreach (var record in m.DocumentTemplates)
|
||||
{
|
||||
switch (record.Item.AttachmentType)
|
||||
{
|
||||
case AttachmentTypes.Device:
|
||||
record.Count = Database.DeviceAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.Device.AssignedUser).Distinct().Count();
|
||||
break;
|
||||
case AttachmentTypes.Job:
|
||||
record.Count = Database.JobAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.Job.User).Distinct().Count();
|
||||
break;
|
||||
case AttachmentTypes.User:
|
||||
record.Count = Database.UserAttachments.Where(a => a.DocumentTemplateId == record.Item.Id).Select(a => a.User).Distinct().Count();
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
// UI Extensions
|
||||
UIExtensions.ExecuteExtensions<ConfigDocumentTemplateBulkGenerate>(ControllerContext, m);
|
||||
|
||||
return View(MVC.Config.DocumentTemplate.Views.BulkGenerate, m);
|
||||
}
|
||||
|
||||
[DiscoAuthorize(Claims.Config.Show)]
|
||||
public virtual ActionResult ExpressionBrowser(string type, bool StaticDeclaredMembersOnly = false)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using Disco.Models.UI.Config.DocumentTemplate;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Disco.Web.Areas.Config.Models.DocumentTemplate
|
||||
{
|
||||
public class BulkGenerateModel : ConfigDocumentTemplateBulkGenerate
|
||||
{
|
||||
public Disco.Models.Repository.DocumentTemplate DocumentTemplate { get; set; }
|
||||
public int TemplatePageCount { get; set; }
|
||||
public List<ItemWithCount<Disco.Models.Repository.UserFlag>> UserFlags { get; set; }
|
||||
public List<ItemWithCount<Disco.Models.Repository.DeviceProfile>> DeviceProfiles { get; set; }
|
||||
public List<ItemWithCount<Disco.Models.Repository.DeviceBatch>> DeviceBatches { get; set; }
|
||||
public List<ItemWithCount<Disco.Models.Repository.DocumentTemplate>> DocumentTemplates { get; set; }
|
||||
|
||||
public class ItemWithCount<T>
|
||||
{
|
||||
public T Item { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
@model Disco.Web.Areas.Config.Models.DocumentTemplate.BulkGenerateModel
|
||||
@using Disco.Services.Interop.ActiveDirectory;
|
||||
@{
|
||||
Authorization.RequireAll(Claims.Config.DocumentTemplate.BulkGenerate, Claims.User.Actions.GenerateDocuments);
|
||||
|
||||
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Document Templates", MVC.Config.DocumentTemplate.Index(null), Model.DocumentTemplate.Description, MVC.Config.DocumentTemplate.Index(Model.DocumentTemplate.Id), "Bulk Generate");
|
||||
Html.BundleDeferred("~/ClientScripts/Modules/Disco-DocumentBulkGenerate");
|
||||
}
|
||||
<div id="DocumentTemplate_BulkGenerate">
|
||||
<div class="actions">
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerate(Model.DocumentTemplate.Id), FormMethod.Post))
|
||||
{
|
||||
if (Model.TemplatePageCount > 1 && Model.TemplatePageCount % 2 != 0)
|
||||
{
|
||||
<input id="DocumentTemplate_BulkGenerate_InsertBlankPage" type="checkbox" name="InsertBlankPage" value="True" checked /><label for="DocumentTemplate_BulkGenerate_InsertBlankPage">Insert Blank Pages for Double-Sided Printing</label>
|
||||
}
|
||||
<input id="DocumentTemplate_BulkGenerate_DataIds" name="DataIds" type="hidden" />
|
||||
<button id="BulkGenerate" class="button" disabled>Bulk Generate</button>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
<br />
|
||||
<button id="AddUsers" class="button small">Add Users</button>
|
||||
<button id="AddGroupMembers" class="button small">Add Group Members</button>
|
||||
@if (Model.UserFlags.Any(f => f.Count > 0))
|
||||
{
|
||||
<button id="AddUserFlag" class="button small">Add With User Flag</button>
|
||||
}
|
||||
@if (Model.DeviceProfiles.Any(b => b.Count > 0))
|
||||
{
|
||||
<button id="AddDeviceProfile" class="button small">Add With Device Profile</button>
|
||||
}
|
||||
@if (Model.DeviceBatches.Any(b => b.Count > 0))
|
||||
{
|
||||
<button id="AddDeviceBatch" class="button small">Add With Device Batch</button>
|
||||
}
|
||||
@if (Model.DocumentTemplates.Any(b => b.Count > 0))
|
||||
{
|
||||
<button id="AddDocumentAttachment" class="button small">Add With Document Attachment</button>
|
||||
}
|
||||
</div>
|
||||
<table class="genericData">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Username</th>
|
||||
<th>Name</th>
|
||||
<th>Scope</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="when-none">
|
||||
<td colspan="4">Add Users</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddUsers" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add Users">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Enter multiple <span class="scopeDescBulkGenerate">User Ids</span> separated by <code><new line></code>, commas (<code>,</code>) or semicolons (<code>;</code>).
|
||||
</div>
|
||||
<div>
|
||||
Security Groups can also be included. Members will be resolved and added.
|
||||
</div>
|
||||
<div class="examples clearfix">
|
||||
<h4>Examples:</h4>
|
||||
<div class="example1 code">
|
||||
user6<br />
|
||||
smi0099<br />
|
||||
@(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith<br />
|
||||
Domain Admins
|
||||
</div>
|
||||
<div class="example2 code">user6,smi0099,@(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith,Domain Admins</div>
|
||||
<div class="example3 code">user6;smi0099;@(ActiveDirectory.Context.PrimaryDomain.NetBiosName)\rsmith;Domain Admins</div>
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddUsers(), FormMethod.Post))
|
||||
{
|
||||
<div class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="userIds"></div>
|
||||
<textarea id="inputBulkGenerateDataIds" name="userIds" data-val="true" data-val-required="Identifiers are required" required></textarea>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddGroupMembers" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add Group Members">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Add all members of a group (including recursive members) to the bulk generation.
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddGroupMembers(), FormMethod.Post))
|
||||
{
|
||||
<table class="input">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
<label for="DocumentTemplate_BulkGenerate_Dialog_AddGroupMembers_Group">Group:</label>
|
||||
</th>
|
||||
<td>
|
||||
<input id="DocumentTemplate_BulkGenerate_Dialog_AddGroupMembers_Group" type="text" name="groupId" data-autocomplete-src="@(Url.Action(MVC.API.System.SearchGroupSubjects()))" required />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (Model.UserFlags.Any(f => f.Count > 0))
|
||||
{
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddUserFlag" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add User Flag Assignments">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Add all users associated with the flag to the bulk generation.
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddUserFlag(), FormMethod.Post))
|
||||
{
|
||||
<input name="flagId" type="hidden" required />
|
||||
<div class="dialog-item-picker">
|
||||
@foreach (var flag in Model.UserFlags)
|
||||
{
|
||||
<div class="item @(flag.Count == 0 ? "disabled" : null)" data-userflagid="@flag.Item.Id">
|
||||
<i class="fa fa-@(flag.Item.Icon) fa-fw fa-lg d-@(flag.Item.IconColour)"></i>@flag.Item.Name <small>(@flag.Count.ToString("N0") user@(flag.Count == 1 ? null : "s"))</small>
|
||||
</div>
|
||||
|
||||
}
|
||||
</div>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.DeviceProfiles.Any(b => b.Count > 0))
|
||||
{
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddDeviceProfile" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add User by Assigned Device Profile">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Add all users associated with a device in the selected profile to the bulk generation.
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDeviceProfile(), FormMethod.Post))
|
||||
{
|
||||
<input name="deviceProfileId" type="hidden" required />
|
||||
<div class="dialog-item-picker">
|
||||
@foreach (var profile in Model.DeviceProfiles)
|
||||
{
|
||||
<div class="item @(profile.Count == 0 ? "disabled" : null)" data-id="@profile.Item.Id">
|
||||
<i class="fa fa-cog fa-fw fa-lg"></i>@profile.Item.Name <small>(@profile.Count.ToString("N0") user@(profile.Count == 1 ? null : "s"))</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.DeviceBatches.Any(b => b.Count > 0))
|
||||
{
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddDeviceBatch" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add User by Assigned Device Batch">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Add all users associated with a device in the selected batch to the bulk generation.
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDeviceBatch(), FormMethod.Post))
|
||||
{
|
||||
<input name="deviceBatchId" type="hidden" required />
|
||||
<div class="dialog-item-picker">
|
||||
@foreach (var batch in Model.DeviceBatches)
|
||||
{
|
||||
<div class="item @(batch.Count == 0 ? "disabled" : null)" data-id="@batch.Item.Id">
|
||||
<i class="fa fa-cog fa-fw fa-lg"></i>@batch.Item.Name <small>(@batch.Count.ToString("N0") user@(batch.Count == 1 ? null : "s"))</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.DocumentTemplates.Any(b => b.Count > 0))
|
||||
{
|
||||
<div id="DocumentTemplate_BulkGenerate_Dialog_AddDocumentAttachment" class="dialog dialog-bulk-generate" title="@(Model.DocumentTemplate.Description): Add User by Assigned Device Batch">
|
||||
<div class="brief">
|
||||
<div>
|
||||
Add all users associated with an attachment of the selected document template to the bulk generation.
|
||||
</div>
|
||||
</div>
|
||||
@using (Html.BeginForm(MVC.API.DocumentTemplate.BulkGenerateAddDocumentAttachment(), FormMethod.Post))
|
||||
{
|
||||
<input name="documentTemplateId" type="hidden" required />
|
||||
<div class="dialog-item-picker">
|
||||
@foreach (var template in Model.DocumentTemplates)
|
||||
{
|
||||
<div class="item @(template.Count == 0 ? "disabled" : null)" data-id="@template.Item.Id">
|
||||
<i class="fa fa-file-text-o fa-fw fa-lg"></i>@template.Item.Id: @template.Item.Description <small>(@template.Count.ToString("N0") user@(template.Count == 1 ? null : "s"))</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="sub">
|
||||
<label for="DocumentTemplate_BulkGenerate_Dialog_AddDocumentAttachment_Threshold">Attachment Added After <small>(optional)</small></label>
|
||||
<input id="DocumentTemplate_BulkGenerate_Dialog_AddDocumentAttachment_Threshold" name="threshold" type="date" />
|
||||
</div>
|
||||
@Html.AntiForgeryToken()
|
||||
}
|
||||
</div>
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,479 @@
|
||||
$(() => {
|
||||
const users = [];
|
||||
const $table = $('#DocumentTemplate_BulkGenerate table');
|
||||
|
||||
function redrawTable() {
|
||||
if (users.length > 0) {
|
||||
$table.find('tbody tr:first-child').hide();
|
||||
}
|
||||
const $tbody = $table.find('tbody');
|
||||
let checkedCount = 0;
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
var user = users[i];
|
||||
if (user.checkbox === undefined) {
|
||||
const tr = $('<tr><td><input id="BulkGenerate_User_' + i.toString() + '" type="checkbox" /></td><td><label for="BulkGenerate_User_' + i.toString() + '"></label></td><td><span class="name"></span></td><td><span class="scope"></span></td></tr>');
|
||||
const checkbox = tr.find('input')[0];
|
||||
const label = tr.find('label');
|
||||
const name = tr.find('span.name');
|
||||
const scope = tr.find('span.scope');
|
||||
label.text(user.Id);
|
||||
scope.text(user.Scope);
|
||||
if (!user.IsError) {
|
||||
checkbox.checked = true;
|
||||
name.text(user.DisplayName);
|
||||
checkedCount++;
|
||||
} else {
|
||||
tr.addClass('error');
|
||||
checkbox.checked = false;
|
||||
checkbox.disabled = true;
|
||||
}
|
||||
user.checkbox = checkbox;
|
||||
$tbody.append(tr);
|
||||
} else {
|
||||
if (!user.IsError && user.checkbox.checked) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkedCount > 0) {
|
||||
$('#BulkGenerate').attr('disabled', null);
|
||||
} else {
|
||||
$('#BulkGenerate').attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function addUsers(r) {
|
||||
let changeCount = 0;
|
||||
for (var i = 0; i < r.length; i++) {
|
||||
const user = r[i];
|
||||
const record = users.find(u => u.Id === user.Id);
|
||||
if (record === undefined || user.IsError) {
|
||||
users.push(user);
|
||||
changeCount++;
|
||||
} else if (record.checkbox !== undefined && !record.checkbox.checked && !record.IsError) {
|
||||
record.checkbox.checked = true;
|
||||
changeCount++;
|
||||
};
|
||||
}
|
||||
if (changeCount) {
|
||||
redrawTable();
|
||||
}
|
||||
}
|
||||
|
||||
function excludeUsers(r) {
|
||||
let changeCount = 0;
|
||||
for (var i = 0; i < r.length; i++) {
|
||||
const user = r[i];
|
||||
const record = users.find(u => u.Id === user.Id);
|
||||
if (record !== undefined && record.checkbox !== undefined) {
|
||||
record.checkbox.checked = false;
|
||||
changeCount++;
|
||||
}
|
||||
}
|
||||
if (changeCount) {
|
||||
redrawTable();
|
||||
}
|
||||
}
|
||||
|
||||
$table.on('change', 'input[type="checkbox"]', e => {
|
||||
redrawTable();
|
||||
});
|
||||
|
||||
$('#BulkGenerate').click(e => {
|
||||
let userIds = [];
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
var user = users[i];
|
||||
if (!user.IsError && user.checkbox !== undefined && user.checkbox.checked) {
|
||||
userIds.push(user.Id);
|
||||
}
|
||||
}
|
||||
if (userIds.length > 0) {
|
||||
$('#DocumentTemplate_BulkGenerate_DataIds').val(userIds.join('\r\n'));
|
||||
$('#BulkGenerate').closest('form').submit();
|
||||
}
|
||||
});
|
||||
|
||||
let dialogAddUsers = null;
|
||||
$('#AddUsers').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddUsers) {
|
||||
dialogAddUsers = $('#DocumentTemplate_BulkGenerate_Dialog_AddUsers').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Users": function () {
|
||||
const form = dialogAddUsers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialogAddUsers.find('textarea').html('').val('');
|
||||
dialogAddUsers.dialog("close");
|
||||
dialogAddUsers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate users: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog("disable");
|
||||
},
|
||||
"Add Users": function () {
|
||||
const form = dialogAddUsers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialogAddUsers.find('textarea').html('').val('');
|
||||
dialogAddUsers.dialog("close");
|
||||
dialogAddUsers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate users: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddGroupMembers = null;
|
||||
$('#AddGroupMembers').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddGroupMembers) {
|
||||
dialogAddGroupMembers = $('#DocumentTemplate_BulkGenerate_Dialog_AddGroupMembers').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Group Members": function () {
|
||||
const form = dialogAddGroupMembers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialogAddGroupMembers.find('input[type="text"]').val('');
|
||||
dialogAddGroupMembers.dialog("close");
|
||||
dialogAddGroupMembers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate group: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddGroupMembers.dialog("disable");
|
||||
},
|
||||
"Add Group Members": function () {
|
||||
const form = dialogAddGroupMembers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialogAddGroupMembers.find('input[type="text"]').val('');
|
||||
dialogAddGroupMembers.dialog("close");
|
||||
dialogAddGroupMembers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate group: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddGroupMembers.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const $input = dialogAddGroupMembers.find('input[type="text"]');
|
||||
$input.autocomplete({
|
||||
source: $input.attr('data-autocomplete-src'),
|
||||
minLength: 2,
|
||||
select: function (e, ui) {
|
||||
$input.val(ui.item.Id);
|
||||
return false;
|
||||
}
|
||||
}).data('ui-autocomplete')._renderItem = function (ul, item) {
|
||||
return $("<li>")
|
||||
.data("item.autocomplete", item)
|
||||
.append("<a><strong>" + item.Name + "</strong><br>" + item.Id + " (" + item.Type + ")</a>")
|
||||
.appendTo(ul);
|
||||
};
|
||||
dialogAddGroupMembers.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddUserFlag = null;
|
||||
$('#AddUserFlag').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddUserFlag) {
|
||||
const dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddUserFlag').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
const form = dialog.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialog.find('input[name="flagId"]').val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate user flag: ' + reason);
|
||||
});
|
||||
}
|
||||
dialog.dialog("disable");
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
const form = dialog.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialog.find('input[name="flagId"]').val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate user flag: ' + reason);
|
||||
});
|
||||
}
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddUserFlag = dialog;
|
||||
}
|
||||
const $input = dialogAddUserFlag.find('input[name="flagId"]');
|
||||
dialogAddUserFlag.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-userflagid'));
|
||||
dialogAddUserFlag.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialogAddUserFlag.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDeviceProfile = null;
|
||||
$('#AddDeviceProfile').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDeviceProfile;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="deviceProfileId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device profile: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDeviceProfile').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDeviceProfile = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="deviceProfileId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDeviceBatch = null;
|
||||
$('#AddDeviceBatch').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDeviceBatch;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="deviceBatchId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device batch: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDeviceBatch').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDeviceBatch = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="deviceBatchId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDocumentAttachment = null;
|
||||
$('#AddDocumentAttachment').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDocumentAttachment;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="documentTemplateId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device batch: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDocumentAttachment').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDocumentAttachment = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="documentTemplateId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
+479
@@ -0,0 +1,479 @@
|
||||
$(() => {
|
||||
const users = [];
|
||||
const $table = $('#DocumentTemplate_BulkGenerate table');
|
||||
|
||||
function redrawTable() {
|
||||
if (users.length > 0) {
|
||||
$table.find('tbody tr:first-child').hide();
|
||||
}
|
||||
const $tbody = $table.find('tbody');
|
||||
let checkedCount = 0;
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
var user = users[i];
|
||||
if (user.checkbox === undefined) {
|
||||
const tr = $('<tr><td><input id="BulkGenerate_User_' + i.toString() + '" type="checkbox" /></td><td><label for="BulkGenerate_User_' + i.toString() + '"></label></td><td><span class="name"></span></td><td><span class="scope"></span></td></tr>');
|
||||
const checkbox = tr.find('input')[0];
|
||||
const label = tr.find('label');
|
||||
const name = tr.find('span.name');
|
||||
const scope = tr.find('span.scope');
|
||||
label.text(user.Id);
|
||||
scope.text(user.Scope);
|
||||
if (!user.IsError) {
|
||||
checkbox.checked = true;
|
||||
name.text(user.DisplayName);
|
||||
checkedCount++;
|
||||
} else {
|
||||
tr.addClass('error');
|
||||
checkbox.checked = false;
|
||||
checkbox.disabled = true;
|
||||
}
|
||||
user.checkbox = checkbox;
|
||||
$tbody.append(tr);
|
||||
} else {
|
||||
if (!user.IsError && user.checkbox.checked) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkedCount > 0) {
|
||||
$('#BulkGenerate').attr('disabled', null);
|
||||
} else {
|
||||
$('#BulkGenerate').attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function addUsers(r) {
|
||||
let changeCount = 0;
|
||||
for (var i = 0; i < r.length; i++) {
|
||||
const user = r[i];
|
||||
const record = users.find(u => u.Id === user.Id);
|
||||
if (record === undefined || user.IsError) {
|
||||
users.push(user);
|
||||
changeCount++;
|
||||
} else if (record.checkbox !== undefined && !record.checkbox.checked && !record.IsError) {
|
||||
record.checkbox.checked = true;
|
||||
changeCount++;
|
||||
};
|
||||
}
|
||||
if (changeCount) {
|
||||
redrawTable();
|
||||
}
|
||||
}
|
||||
|
||||
function excludeUsers(r) {
|
||||
let changeCount = 0;
|
||||
for (var i = 0; i < r.length; i++) {
|
||||
const user = r[i];
|
||||
const record = users.find(u => u.Id === user.Id);
|
||||
if (record !== undefined && record.checkbox !== undefined) {
|
||||
record.checkbox.checked = false;
|
||||
changeCount++;
|
||||
}
|
||||
}
|
||||
if (changeCount) {
|
||||
redrawTable();
|
||||
}
|
||||
}
|
||||
|
||||
$table.on('change', 'input[type="checkbox"]', e => {
|
||||
redrawTable();
|
||||
});
|
||||
|
||||
$('#BulkGenerate').click(e => {
|
||||
let userIds = [];
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
var user = users[i];
|
||||
if (!user.IsError && user.checkbox !== undefined && user.checkbox.checked) {
|
||||
userIds.push(user.Id);
|
||||
}
|
||||
}
|
||||
if (userIds.length > 0) {
|
||||
$('#DocumentTemplate_BulkGenerate_DataIds').val(userIds.join('\r\n'));
|
||||
$('#BulkGenerate').closest('form').submit();
|
||||
}
|
||||
});
|
||||
|
||||
let dialogAddUsers = null;
|
||||
$('#AddUsers').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddUsers) {
|
||||
dialogAddUsers = $('#DocumentTemplate_BulkGenerate_Dialog_AddUsers').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Users": function () {
|
||||
const form = dialogAddUsers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialogAddUsers.find('textarea').html('').val('');
|
||||
dialogAddUsers.dialog("close");
|
||||
dialogAddUsers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate users: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog("disable");
|
||||
},
|
||||
"Add Users": function () {
|
||||
const form = dialogAddUsers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialogAddUsers.find('textarea').html('').val('');
|
||||
dialogAddUsers.dialog("close");
|
||||
dialogAddUsers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate users: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
dialogAddUsers.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddGroupMembers = null;
|
||||
$('#AddGroupMembers').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddGroupMembers) {
|
||||
dialogAddGroupMembers = $('#DocumentTemplate_BulkGenerate_Dialog_AddGroupMembers').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Group Members": function () {
|
||||
const form = dialogAddGroupMembers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialogAddGroupMembers.find('input[type="text"]').val('');
|
||||
dialogAddGroupMembers.dialog("close");
|
||||
dialogAddGroupMembers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate group: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddGroupMembers.dialog("disable");
|
||||
},
|
||||
"Add Group Members": function () {
|
||||
const form = dialogAddGroupMembers.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialogAddGroupMembers.find('input[type="text"]').val('');
|
||||
dialogAddGroupMembers.dialog("close");
|
||||
dialogAddGroupMembers.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate group: ' + reason);
|
||||
});
|
||||
}
|
||||
dialogAddGroupMembers.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const $input = dialogAddGroupMembers.find('input[type="text"]');
|
||||
$input.autocomplete({
|
||||
source: $input.attr('data-autocomplete-src'),
|
||||
minLength: 2,
|
||||
select: function (e, ui) {
|
||||
$input.val(ui.item.Id);
|
||||
return false;
|
||||
}
|
||||
}).data('ui-autocomplete')._renderItem = function (ul, item) {
|
||||
return $("<li>")
|
||||
.data("item.autocomplete", item)
|
||||
.append("<a><strong>" + item.Name + "</strong><br>" + item.Id + " (" + item.Type + ")</a>")
|
||||
.appendTo(ul);
|
||||
};
|
||||
dialogAddGroupMembers.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddUserFlag = null;
|
||||
$('#AddUserFlag').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!dialogAddUserFlag) {
|
||||
const dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddUserFlag').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
const form = dialog.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
excludeUsers(r);
|
||||
dialog.find('input[name="flagId"]').val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate user flag: ' + reason);
|
||||
});
|
||||
}
|
||||
dialog.dialog("disable");
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
const form = dialog.find('form')[0];
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
addUsers(r);
|
||||
dialog.find('input[name="flagId"]').val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate user flag: ' + reason);
|
||||
});
|
||||
}
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddUserFlag = dialog;
|
||||
}
|
||||
const $input = dialogAddUserFlag.find('input[name="flagId"]');
|
||||
dialogAddUserFlag.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-userflagid'));
|
||||
dialogAddUserFlag.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialogAddUserFlag.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDeviceProfile = null;
|
||||
$('#AddDeviceProfile').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDeviceProfile;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="deviceProfileId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device profile: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDeviceProfile').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDeviceProfile = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="deviceProfileId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDeviceBatch = null;
|
||||
$('#AddDeviceBatch').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDeviceBatch;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="deviceBatchId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device batch: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDeviceBatch').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDeviceBatch = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="deviceBatchId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
let dialogAddDocumentAttachment = null;
|
||||
$('#AddDocumentAttachment').click(e => {
|
||||
e.preventDefault();
|
||||
let dialog = dialogAddDocumentAttachment;
|
||||
if (!dialog) {
|
||||
const action = delegate => {
|
||||
const form = dialog.find('form')[0];
|
||||
const input = dialog.find('input[name="documentTemplateId"]');
|
||||
if (input.val()) {
|
||||
if (form.reportValidity()) {
|
||||
const body = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
delegate(r);
|
||||
input.val('');
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
dialog.dialog("close");
|
||||
dialog.dialog("enable");
|
||||
})
|
||||
.catch(reason => {
|
||||
alert('Failed to validate device batch: ' + reason);
|
||||
});
|
||||
dialog.dialog("disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog = $('#DocumentTemplate_BulkGenerate_Dialog_AddDocumentAttachment').dialog({
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 460,
|
||||
buttons: {
|
||||
"Exclude Assigned Users": function () {
|
||||
action(excludeUsers);
|
||||
},
|
||||
"Add Assigned Users": function () {
|
||||
action(addUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogAddDocumentAttachment = dialog;
|
||||
}
|
||||
const $input = dialog.find('input[name="documentTemplateId"]');
|
||||
dialog.on('click', 'div.item:not(.disabled)', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
$input.val($target.attr('data-id'));
|
||||
dialog.find('div.item').removeClass('selected');
|
||||
$target.addClass('selected');
|
||||
return false;
|
||||
});
|
||||
dialog.dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -225,6 +225,7 @@
|
||||
<Compile Include="Areas\Config\Models\AuthorizationRole\IndexModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\AuthorizationRole\ShowModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\Config\IndexModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\DocumentTemplate\BulkGenerateModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\DocumentTemplate\CreatePackageModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\DocumentTemplate\ShowPackageModel.cs" />
|
||||
<Compile Include="Areas\Config\Models\Shared\LinkedGroupModel.cs" />
|
||||
@@ -257,6 +258,11 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="Areas\Config\Views\DocumentTemplate\BulkGenerate.generated.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>BulkGenerate.cshtml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Areas\Config\Views\DocumentTemplate\CreatePackage.generated.cs">
|
||||
<DependentUpon>CreatePackage.cshtml</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
@@ -1212,6 +1218,10 @@
|
||||
<Generator>RazorGenerator</Generator>
|
||||
<LastGenOutput>Show.generated.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Areas\Config\Views\DocumentTemplate\BulkGenerate.cshtml">
|
||||
<Generator>RazorGenerator</Generator>
|
||||
<LastGenOutput>BulkGenerate.generated.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Areas\Config\Views\DocumentTemplate\ShowPackage.cshtml">
|
||||
<Generator>RazorGenerator</Generator>
|
||||
<LastGenOutput>ShowPackage1.generated.cs</LastGenOutput>
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
"ClientSource/Scripts/Modules/Disco-DataTableHelpers/disco.datatablehelpers.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "ClientSource/Scripts/Modules/Disco-DocumentBulkGenerate.js",
|
||||
"inputFiles": [
|
||||
"ClientSource/Scripts/Modules/Disco-DocumentBulkGenerate/disco.documentbulkgenerate.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "ClientSource/Scripts/Modules/Disco-ExpressionEditor.js",
|
||||
"inputFiles": [
|
||||
|
||||
Reference in New Issue
Block a user