feature: document handlers
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// <auto-generated />
|
||||
namespace Disco.Data.Migrations
|
||||
{
|
||||
using System.Data.Entity.Migrations;
|
||||
using System.Data.Entity.Migrations.Infrastructure;
|
||||
using System.Resources;
|
||||
|
||||
public sealed partial class DBv21 : IMigrationMetadata
|
||||
{
|
||||
private readonly ResourceManager Resources = new ResourceManager(typeof(DBv21));
|
||||
|
||||
string IMigrationMetadata.Id
|
||||
{
|
||||
get { return "202102110443550_DBv21"; }
|
||||
}
|
||||
|
||||
string IMigrationMetadata.Source
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
string IMigrationMetadata.Target
|
||||
{
|
||||
get { return Resources.GetString("Target"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace Disco.Data.Migrations
|
||||
{
|
||||
using System;
|
||||
using System.Data.Entity.Migrations;
|
||||
|
||||
public partial class DBv21 : DbMigration
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
AddColumn("dbo.UserAttachments", "HandlerId", c => c.String(maxLength: 30));
|
||||
AddColumn("dbo.UserAttachments", "HandlerReferenceId", c => c.String(maxLength: 50));
|
||||
AddColumn("dbo.UserAttachments", "HandlerData", c => c.String());
|
||||
AddColumn("dbo.JobAttachments", "HandlerId", c => c.String(maxLength: 30));
|
||||
AddColumn("dbo.JobAttachments", "HandlerReferenceId", c => c.String(maxLength: 50));
|
||||
AddColumn("dbo.JobAttachments", "HandlerData", c => c.String());
|
||||
AddColumn("dbo.DeviceAttachments", "HandlerId", c => c.String(maxLength: 30));
|
||||
AddColumn("dbo.DeviceAttachments", "HandlerReferenceId", c => c.String(maxLength: 50));
|
||||
AddColumn("dbo.DeviceAttachments", "HandlerData", c => c.String());
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
DropColumn("dbo.DeviceAttachments", "HandlerData");
|
||||
DropColumn("dbo.DeviceAttachments", "HandlerReferenceId");
|
||||
DropColumn("dbo.DeviceAttachments", "HandlerId");
|
||||
DropColumn("dbo.JobAttachments", "HandlerData");
|
||||
DropColumn("dbo.JobAttachments", "HandlerReferenceId");
|
||||
DropColumn("dbo.JobAttachments", "HandlerId");
|
||||
DropColumn("dbo.UserAttachments", "HandlerData");
|
||||
DropColumn("dbo.UserAttachments", "HandlerReferenceId");
|
||||
DropColumn("dbo.UserAttachments", "HandlerId");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -20,5 +20,9 @@ namespace Disco.Models.Repository
|
||||
string DocumentTemplateId { get; set; }
|
||||
|
||||
AttachmentTypes AttachmentType { get; }
|
||||
|
||||
string HandlerId { get; set; }
|
||||
string HandlerReferenceId { get; set; }
|
||||
string HandlerData { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@ namespace Disco.Models.Repository
|
||||
|
||||
public string DocumentTemplateId { get; set; }
|
||||
|
||||
[StringLength(30)]
|
||||
public string HandlerId { get; set; }
|
||||
[StringLength(50)]
|
||||
public string HandlerReferenceId { get; set; }
|
||||
public string HandlerData { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public object Reference { get { return DeviceSerialNumber; } }
|
||||
|
||||
|
||||
@@ -19,6 +19,13 @@ namespace Disco.Models.Repository
|
||||
[Required, StringLength(500)]
|
||||
public string Comments { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string HandlerId { get => null; set { } }
|
||||
[NotMapped]
|
||||
public string HandlerReferenceId { get => null; set { } }
|
||||
[NotMapped]
|
||||
public string HandlerData { get => null; set { } }
|
||||
|
||||
[NotMapped]
|
||||
public object Reference => DeviceBatchId;
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ namespace Disco.Models.Repository
|
||||
|
||||
public string DocumentTemplateId { get; set; }
|
||||
|
||||
[StringLength(30)]
|
||||
public string HandlerId { get; set; }
|
||||
[StringLength(50)]
|
||||
public string HandlerReferenceId { get; set; }
|
||||
public string HandlerData { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public object Reference { get { return JobId; } }
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ namespace Disco.Models.Repository
|
||||
|
||||
public string DocumentTemplateId { get; set; }
|
||||
|
||||
[StringLength(30)]
|
||||
public string HandlerId { get; set; }
|
||||
[StringLength(50)]
|
||||
public string HandlerReferenceId { get; set; }
|
||||
public string HandlerData { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public object Reference { get { return UserId; } }
|
||||
|
||||
|
||||
@@ -105,6 +105,9 @@ namespace Disco.Services
|
||||
#endregion
|
||||
|
||||
public static DeviceAttachment CreateAttachment(this Device Device, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null)
|
||||
=> Device.CreateAttachment(Database, CreatorUser, Filename, DateTime.Now, MimeType, Comments, Content, DocumentTemplate, PdfThumbnail);
|
||||
|
||||
public static DeviceAttachment CreateAttachment(this Device Device, DiscoDataContext Database, User CreatorUser, string Filename, DateTime timestamp, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null, string HandlerId = null, string HandlerReferenceId = null, string HandlerData = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
|
||||
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
|
||||
@@ -115,8 +118,11 @@ namespace Disco.Services
|
||||
TechUserId = CreatorUser.UserId,
|
||||
Filename = Filename,
|
||||
MimeType = MimeType,
|
||||
Timestamp = DateTime.Now,
|
||||
Comments = Comments
|
||||
Timestamp = timestamp,
|
||||
Comments = Comments,
|
||||
HandlerId = HandlerId,
|
||||
HandlerReferenceId = HandlerReferenceId,
|
||||
HandlerData = HandlerData,
|
||||
};
|
||||
|
||||
if (DocumentTemplate != null)
|
||||
@@ -136,6 +142,9 @@ namespace Disco.Services
|
||||
}
|
||||
|
||||
public static JobAttachment CreateAttachment(this Job Job, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null)
|
||||
=> Job.CreateAttachment(Database, CreatorUser, Filename, DateTime.Now, MimeType, Comments, Content, DocumentTemplate, PdfThumbnail);
|
||||
|
||||
public static JobAttachment CreateAttachment(this Job Job, DiscoDataContext Database, User CreatorUser, string Filename, DateTime Timestamp, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null, string HandlerId = null, string HandlerReferenceId = null, string HandlerData = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
|
||||
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
|
||||
@@ -146,8 +155,11 @@ namespace Disco.Services
|
||||
TechUserId = CreatorUser.UserId,
|
||||
Filename = Filename,
|
||||
MimeType = MimeType,
|
||||
Timestamp = DateTime.Now,
|
||||
Comments = Comments
|
||||
Timestamp = Timestamp,
|
||||
Comments = Comments,
|
||||
HandlerId = HandlerId,
|
||||
HandlerReferenceId = HandlerReferenceId,
|
||||
HandlerData = HandlerData,
|
||||
};
|
||||
|
||||
if (DocumentTemplate != null)
|
||||
@@ -167,6 +179,9 @@ namespace Disco.Services
|
||||
}
|
||||
|
||||
public static UserAttachment CreateAttachment(this User User, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null)
|
||||
=> User.CreateAttachment(Database, CreatorUser, Filename, DateTime.Now, MimeType, Comments, Content, DocumentTemplate, PdfThumbnail);
|
||||
|
||||
public static UserAttachment CreateAttachment(this User User, DiscoDataContext Database, User CreatorUser, string Filename, DateTime Timestamp, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, Image PdfThumbnail = null, string HandlerId = null, string HandlerReferenceId = null, string HandlerData = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
|
||||
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
|
||||
@@ -177,8 +192,11 @@ namespace Disco.Services
|
||||
TechUserId = CreatorUser.UserId,
|
||||
Filename = Filename,
|
||||
MimeType = MimeType,
|
||||
Timestamp = DateTime.Now,
|
||||
Comments = Comments
|
||||
Timestamp = Timestamp,
|
||||
Comments = Comments,
|
||||
HandlerId = HandlerId,
|
||||
HandlerReferenceId = HandlerReferenceId,
|
||||
HandlerData = HandlerData,
|
||||
};
|
||||
|
||||
if (DocumentTemplate != null)
|
||||
|
||||
@@ -165,12 +165,12 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, string PdfFilename)
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, string PdfFilename)
|
||||
{
|
||||
return ImportPdfAttachment(Identifier, Database, PdfFilename, null);
|
||||
}
|
||||
|
||||
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, string PdfFilename, Image Thumbnail)
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, string PdfFilename, Image Thumbnail)
|
||||
{
|
||||
using (var pdfStream = File.OpenRead(PdfFilename))
|
||||
{
|
||||
@@ -178,17 +178,20 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent)
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent)
|
||||
{
|
||||
return ImportPdfAttachment(Identifier, Database, PdfContent, null, new List<DocumentUniqueIdentifier>() { Identifier });
|
||||
}
|
||||
|
||||
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent, Image Thumbnail)
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent, Image Thumbnail)
|
||||
{
|
||||
return ImportPdfAttachment(Identifier, Database, PdfContent, Thumbnail, new List<DocumentUniqueIdentifier>() { Identifier });
|
||||
}
|
||||
|
||||
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent, Image Thumbnail, List<DocumentUniqueIdentifier> PageIdentifiers)
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent, Image Thumbnail, List<DocumentUniqueIdentifier> PageIdentifiers)
|
||||
=> Identifier.ImportPdfAttachment(Database, PdfContent, Thumbnail, PageIdentifiers, null, null, null, null);
|
||||
|
||||
public static IAttachment ImportPdfAttachment(this DocumentUniqueIdentifier Identifier, DiscoDataContext Database, Stream PdfContent, Image Thumbnail, List<DocumentUniqueIdentifier> PageIdentifiers, DateTime? Timestamp, string HandlerId, string HandlerReferenceId, string HandlerData)
|
||||
{
|
||||
string filename;
|
||||
string comments;
|
||||
@@ -196,16 +199,32 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
|
||||
if (Identifier.DocumentTemplate == null)
|
||||
{
|
||||
filename = $"{Identifier.Target.AttachmentReferenceId.Replace('\\', '_')}_{Identifier.TimeStamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = $"Uploaded: {Identifier.TimeStamp:s}";
|
||||
if (Timestamp.HasValue)
|
||||
{
|
||||
filename = $"{Identifier.Target.AttachmentReferenceId.Replace('\\', '_')}_{Timestamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = $"Completed: {Timestamp:s}";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = $"{Identifier.Target.AttachmentReferenceId.Replace('\\', '_')}_{Identifier.TimeStamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = $"Uploaded: {Identifier.TimeStamp:s}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = $"{Identifier.DocumentTemplateId}_{Identifier.TimeStamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = string.Format("Generated: {0:s}", Identifier.TimeStamp);
|
||||
if (Timestamp.HasValue)
|
||||
{
|
||||
filename = $"{Identifier.DocumentTemplateId}_{Timestamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = $"Generated: {Identifier.TimeStamp:s}; Completed: {Timestamp:s}";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = $"{Identifier.DocumentTemplateId}_{Identifier.TimeStamp:yyyyMMdd-HHmmss}.pdf";
|
||||
comments = $"Generated: {Identifier.TimeStamp:s}";
|
||||
}
|
||||
}
|
||||
|
||||
User creatorUser = UserService.GetUser(Identifier.CreatorId, Database, true);
|
||||
User creatorUser = UserService.GetUser(Identifier.CreatorId, Database, false);
|
||||
if (creatorUser == null)
|
||||
{
|
||||
// No Creator User (or Username invalid)
|
||||
@@ -216,18 +235,18 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
{
|
||||
case AttachmentTypes.Device:
|
||||
Device d = (Device)Identifier.Target;
|
||||
attachment = d.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail);
|
||||
attachment = d.CreateAttachment(Database, creatorUser, filename, Timestamp ?? DateTime.Now, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail, HandlerId, HandlerReferenceId, HandlerData);
|
||||
break;
|
||||
case AttachmentTypes.Job:
|
||||
Job j = (Job)Identifier.Target;
|
||||
attachment = j.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail);
|
||||
attachment = j.CreateAttachment(Database, creatorUser, filename, Timestamp ?? DateTime.Now, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail, HandlerId, HandlerReferenceId, HandlerData);
|
||||
break;
|
||||
case AttachmentTypes.User:
|
||||
User u = (User)Identifier.Target;
|
||||
attachment = u.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail);
|
||||
attachment = u.CreateAttachment(Database, creatorUser, filename, Timestamp ?? DateTime.Now, DocumentTemplate.PdfMimeType, comments, PdfContent, Identifier.DocumentTemplate, Thumbnail, HandlerId, HandlerReferenceId, HandlerData);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Identifier.DocumentTemplate != null && !string.IsNullOrWhiteSpace(Identifier.DocumentTemplate.OnImportAttachmentExpression))
|
||||
@@ -242,7 +261,8 @@ namespace Disco.Services.Documents.AttachmentImport
|
||||
SystemLog.LogException("Document Importer - OnImportAttachmentExpression", ex);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco
|
||||
{
|
||||
@@ -26,4 +28,61 @@ namespace Disco
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class OneOf
|
||||
{
|
||||
public static OneOf<T> Create<T>(T instance)
|
||||
=> OneOf<T>.Create(instance);
|
||||
}
|
||||
public struct OneOf<T> : IEnumerable<T>
|
||||
{
|
||||
private readonly T instance;
|
||||
|
||||
private OneOf(T instance)
|
||||
{
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public static OneOf<T> Create(T instance)
|
||||
=> new OneOf<T>(instance);
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
=> new OneOfEnumerator(instance);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> new OneOfEnumerator(instance);
|
||||
|
||||
private struct OneOfEnumerator : IEnumerator<T>
|
||||
{
|
||||
private readonly T instance;
|
||||
private bool moved;
|
||||
|
||||
public OneOfEnumerator(T instance)
|
||||
{
|
||||
this.instance = instance;
|
||||
moved = false;
|
||||
}
|
||||
|
||||
public T Current => instance;
|
||||
|
||||
object IEnumerator.Current => instance;
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (!moved)
|
||||
{
|
||||
moved = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
moved = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Models.Services.Documents;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.DocumentHandlerProvider
|
||||
{
|
||||
[PluginFeatureCategory(DisplayName = "Document Handler")]
|
||||
public abstract class DocumentHandlerProviderFeature : PluginFeature
|
||||
{
|
||||
public abstract string HandlerTitle { get; }
|
||||
public abstract string HandlerDescription { get; }
|
||||
|
||||
public abstract bool CanHandle(DocumentTemplate template);
|
||||
public abstract bool CanHandle(DocumentTemplatePackage templatePackage);
|
||||
public abstract bool CanHandle(DocumentTemplate template, IAttachmentTarget target);
|
||||
public abstract bool CanHandle(DocumentTemplatePackage templatePackage, IAttachmentTarget target);
|
||||
public abstract bool CanHandleBulk(DocumentTemplate template);
|
||||
public abstract bool CanHandleBulk(DocumentTemplatePackage templatePackage);
|
||||
|
||||
public abstract Type GenerationOptionsUi { get; }
|
||||
public virtual string GenerationOptionsIcon => "file-text-o";
|
||||
public abstract object GetGenerationOptionsUiModel(DocumentTemplate template, IAttachmentTarget target, User targetUser, User techUser);
|
||||
public abstract object GetGenerationOptionsUiModel(DocumentTemplatePackage templatePackage, IAttachmentTarget target, User targetUser, User techUser);
|
||||
|
||||
public abstract ActionResult Handle(DocumentTemplate template, IAttachmentTarget target, User targetUser, User techUser);
|
||||
public abstract ActionResult Handle(DocumentTemplatePackage templatePackage, IAttachmentTarget target, User targetUser, User techUser);
|
||||
public abstract ActionResult HandleBulk(DocumentTemplate template, IList<IAttachmentTarget> targets, User targetUser, User techUser);
|
||||
public abstract ActionResult HandleBulk(DocumentTemplatePackage templatePackage, IList<IAttachmentTarget> targets, User targetUser, User techUser);
|
||||
}
|
||||
}
|
||||
@@ -765,5 +765,66 @@ namespace Disco.Web.Areas.API.Controllers
|
||||
|
||||
#endregion
|
||||
|
||||
#region Handlers
|
||||
[HttpPost]
|
||||
public virtual ActionResult GenerateDocumentHandlerUi(string templateId, string targetId, string handlerId)
|
||||
{
|
||||
Disco.Services.DocumentTemplateExtensions.GetTemplateAndTarget(Database, Authorization, templateId, targetId, out var template, out var target, out var targetUser);
|
||||
|
||||
var handlerManifest = Plugins.GetPluginFeature(handlerId, typeof(DocumentHandlerProviderFeature));
|
||||
|
||||
using (var handler = handlerManifest.CreateInstance<DocumentHandlerProviderFeature>())
|
||||
{
|
||||
if (!handler.CanHandle(template, target))
|
||||
throw new NotSupportedException("Handler does not support this Document Template and Target");
|
||||
|
||||
var handlerPartialView = handler.GenerationOptionsUi;
|
||||
|
||||
if (handlerPartialView == null)
|
||||
throw new NotSupportedException("Handler does not have a Generation Options UI");
|
||||
|
||||
|
||||
|
||||
var model = handler.GetGenerationOptionsUiModel(template, target, targetUser, CurrentUser);
|
||||
|
||||
return this.PrecompiledPartialView(handlerPartialView, model);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public virtual ActionResult DocumentHandlers(string templateId, string targetId)
|
||||
{
|
||||
Disco.Services.DocumentTemplateExtensions.GetTemplateAndTarget(Database, Authorization, templateId, targetId, out var template, out var target, out _);
|
||||
|
||||
var handlers = Plugins.GetPluginFeatures(typeof(DocumentHandlerProviderFeature))
|
||||
.SelectMany(f =>
|
||||
{
|
||||
using (var handler = f.CreateInstance<DocumentHandlerProviderFeature>())
|
||||
{
|
||||
if (handler.CanHandle(template, target))
|
||||
return OneOf.Create(new DocumentHandlerModel()
|
||||
{
|
||||
Id = f.Id,
|
||||
Title = handler.HandlerTitle,
|
||||
Description = handler.HandlerDescription,
|
||||
UiUrl = handler.GenerationOptionsUi == null ? null : Url.Action(MVC.API.DocumentTemplate.GenerateDocumentHandlerUi(template.Id, target.AttachmentReferenceId, f.Id)),
|
||||
Icon = handler.GenerationOptionsIcon,
|
||||
});
|
||||
};
|
||||
return Enumerable.Empty<DocumentHandlerModel>();
|
||||
}).ToList();
|
||||
|
||||
var model = new DocumentHandlersModel()
|
||||
{
|
||||
TemplateId = template.Id,
|
||||
TemplateName = template.Description,
|
||||
TargetId = target.AttachmentReferenceId,
|
||||
TargetName = target.ToString(),
|
||||
Handlers = handlers,
|
||||
};
|
||||
|
||||
return Json(model);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Disco.Web.Areas.API.Models.DocumentTemplate
|
||||
{
|
||||
public class DocumentHandlersModel
|
||||
{
|
||||
public string TemplateId { get; set; }
|
||||
public string TemplateName { get; set; }
|
||||
public string TargetId { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
|
||||
public List<DocumentHandlerModel> Handlers { get; set; }
|
||||
}
|
||||
|
||||
public class DocumentHandlerModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string UiUrl { get; set; }
|
||||
public string Icon { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
(function (window, document, $) {
|
||||
$(function () {
|
||||
let $generationHost = null;
|
||||
const $container = $('#Document_Generation_Container');
|
||||
const $control = $container.find('#Document_Generate');
|
||||
const targetId = $container.attr('data-targetid');
|
||||
const targetType = $container.attr('data-targettype');
|
||||
const generatePdfUrl = $container.attr('data-generatepdfurl');
|
||||
const generatePackageUrl = $container.attr('data-generatepackageurl');
|
||||
const handlersPresent = $container.attr('data-handlerspresent') === 'true';
|
||||
const handlersUrl = $container.attr('data-handlersurl');
|
||||
let $handlersDialog = null;
|
||||
|
||||
const downloadPdf = function (templateId) {
|
||||
|
||||
let url;
|
||||
if (templateId.lastIndexOf('Package:', 0) === 0)
|
||||
url = generatePackageUrl + templateId.substring(8);
|
||||
else
|
||||
url = generatePdfUrl + templateId;
|
||||
url = url + '?TargetId=' + targetId;
|
||||
|
||||
if ($.connection && $.connection.hub && $.connection.hub.transport &&
|
||||
$.connection.hub.transport.name == 'foreverFrame') {
|
||||
// SignalR active with foreverFrame transport - use popup window
|
||||
window.open(url, '_blank', 'height=150,width=250,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
|
||||
} else {
|
||||
// use iFrame
|
||||
if (!$generationHost) {
|
||||
$generationHost = $('<iframe>')
|
||||
.attr({ 'src': url, 'title': 'Document Generation Host' })
|
||||
.addClass('hidden')
|
||||
.appendTo('body')
|
||||
.contents();
|
||||
} else {
|
||||
$generationHost[0].location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateHandlers = function (templateId) {
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $loadingUi = $handlersDialog.find('#Document_Generation_Dialog_Handlers_Loading');
|
||||
|
||||
$handlerPicker.find('div.handler').remove();
|
||||
$loadingUi.show();
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append('templateId', decodeURI(templateId));
|
||||
formData.append('targetId', decodeURI(targetId));
|
||||
fetch(handlersUrl, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
}).then(r => r.json())
|
||||
.then(data => {
|
||||
$loadingUi.hide();
|
||||
$.each(data.Handlers, (i, h) => {
|
||||
$('<div class="handler">').text(h.Title).attr({
|
||||
'data-id': h.Id,
|
||||
'data-uiurl': h.UiUrl
|
||||
}).prepend($('<i class="fa fa-fw fa-lg">').addClass('fa-'+h.Icon)).appendTo($handlerPicker);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$control.change(function () {
|
||||
var templateId = $control.val();
|
||||
if (templateId) {
|
||||
if (handlersPresent) {
|
||||
if (!$handlersDialog) {
|
||||
$handlersDialog = $container.find('#Document_Generation_Dialog');
|
||||
$handlersDialog.dialog({
|
||||
width: 750,
|
||||
height: 500,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
buttons: {
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
$handlersDialog.find('#Document_Generation_Dialog_Download').click(e => {
|
||||
e.preventDefault();
|
||||
downloadPdf(templateId);
|
||||
$handlersDialog.dialog('close');
|
||||
return false;
|
||||
})
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $Document_Generation_Dialog_Download_Container = $handlersDialog.find('#Document_Generation_Dialog_Download_Container');
|
||||
const $Document_Generation_Dialog_HandlerUI = $handlersDialog.find('#Document_Generation_Dialog_HandlerUI');
|
||||
$handlerPicker.on('click', 'div[data-id]', e => {
|
||||
$handlerPicker.find('div').removeClass('selected');
|
||||
const $this = $(e.currentTarget);
|
||||
$this.addClass('selected');
|
||||
const handlerId = $this.attr('data-id');
|
||||
if (handlerId === 'download') {
|
||||
$Document_Generation_Dialog_Download_Container.show();
|
||||
$Document_Generation_Dialog_HandlerUI.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
} else {
|
||||
$Document_Generation_Dialog_Download_Container.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
$Document_Generation_Dialog_HandlerUI.show();
|
||||
const uiurl = $this.attr('data-uiurl');
|
||||
fetch(uiurl, { method: 'POST' })
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
$Document_Generation_Dialog_HandlerUI.html(html);
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $Document_Generation_Dialog_Download_Container = $handlersDialog.find('#Document_Generation_Dialog_Download_Container');
|
||||
const $Document_Generation_Dialog_HandlerUI = $handlersDialog.find('#Document_Generation_Dialog_HandlerUI');
|
||||
$handlerPicker.find('div').removeClass('selected');
|
||||
$handlerPicker.find('div[data-id=download]').addClass('selected');
|
||||
$Document_Generation_Dialog_Download_Container.show();
|
||||
$Document_Generation_Dialog_HandlerUI.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
|
||||
$handlersDialog.dialog('option', 'title', 'Generate Document: ' + $control[0].selectedOptions[0].label);
|
||||
$handlersDialog.dialog('open');
|
||||
updateHandlers(templateId);
|
||||
} else {
|
||||
downloadPdf(templateId);
|
||||
}
|
||||
$control.val('').blur();
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
})(window, document, $);
|
||||
@@ -0,0 +1 @@
|
||||
(function(n,t,i){i(function(){let f=null;const r=i("#Document_Generation_Container"),u=r.find("#Document_Generate"),e=r.attr("data-targetid"),v=r.attr("data-targettype"),s=r.attr("data-generatepdfurl"),h=r.attr("data-generatepackageurl"),c=r.attr("data-handlerspresent")==="true",l=r.attr("data-handlersurl");let t=null;const o=function(t){let r;r=t.lastIndexOf("Package:",0)===0?h+t.substring(8):s+t;r=r+"?TargetId="+e;i.connection&&i.connection.hub&&i.connection.hub.transport&&i.connection.hub.transport.name=="foreverFrame"?n.open(r,"_blank","height=150,width=250,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no"):f?f[0].location.href=r:f=i("<iframe>").attr({src:r,title:"Document Generation Host"}).addClass("hidden").appendTo("body").contents()},a=function(n){const u=t.find(".handlerPicker"),f=t.find("#Document_Generation_Dialog_Handlers_Loading");u.find("div.handler").remove();f.show();var r=new FormData;r.append("templateId",decodeURI(n));r.append("targetId",decodeURI(e));fetch(l,{method:"POST",body:r}).then(n=>n.json()).then(n=>{f.hide(),i.each(n.Handlers,(n,t)=>{i('<div class="handler">').text(t.Title).attr({"data-id":t.Id,"data-uiurl":t.UiUrl}).prepend(i('<i class="fa fa-fw fa-lg">').addClass("fa-"+t.Icon)).appendTo(u)})})};u.change(function(){var n=u.val();if(n){if(c){if(!t){t=r.find("#Document_Generation_Dialog");t.dialog({width:750,height:500,resizable:!1,modal:!0,autoOpen:!1,buttons:{Cancel:function(){i(this).dialog("close")}}});t.find("#Document_Generation_Dialog_Download").click(i=>(i.preventDefault(),o(n),t.dialog("close"),!1));const f=t.find(".handlerPicker"),e=t.find("#Document_Generation_Dialog_Download_Container"),u=t.find("#Document_Generation_Dialog_HandlerUI");f.on("click","div[data-id]",n=>{f.find("div").removeClass("selected");const t=i(n.currentTarget);t.addClass("selected");const r=t.attr("data-id");if(r==="download")e.show(),u.hide(),u.empty();else{e.hide();u.empty();u.show();const n=t.attr("data-uiurl");fetch(n,{method:"POST"}).then(n=>n.text()).then(n=>{u.html(n)})}})}const f=t.find(".handlerPicker"),s=t.find("#Document_Generation_Dialog_Download_Container"),e=t.find("#Document_Generation_Dialog_HandlerUI");f.find("div").removeClass("selected");f.find("div[data-id=download]").addClass("selected");s.show();e.hide();e.empty();t.dialog("option","title","Generate Document: "+u[0].selectedOptions[0].label);t.dialog("open");a(n)}else o(n);u.val("").blur()}})})})(window,document,$);
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
(function (window, document, $) {
|
||||
$(function () {
|
||||
let $generationHost = null;
|
||||
const $container = $('#Document_Generation_Container');
|
||||
const $control = $container.find('#Document_Generate');
|
||||
const targetId = $container.attr('data-targetid');
|
||||
const targetType = $container.attr('data-targettype');
|
||||
const generatePdfUrl = $container.attr('data-generatepdfurl');
|
||||
const generatePackageUrl = $container.attr('data-generatepackageurl');
|
||||
const handlersPresent = $container.attr('data-handlerspresent') === 'true';
|
||||
const handlersUrl = $container.attr('data-handlersurl');
|
||||
let $handlersDialog = null;
|
||||
|
||||
const downloadPdf = function (templateId) {
|
||||
|
||||
let url;
|
||||
if (templateId.lastIndexOf('Package:', 0) === 0)
|
||||
url = generatePackageUrl + templateId.substring(8);
|
||||
else
|
||||
url = generatePdfUrl + templateId;
|
||||
url = url + '?TargetId=' + targetId;
|
||||
|
||||
if ($.connection && $.connection.hub && $.connection.hub.transport &&
|
||||
$.connection.hub.transport.name == 'foreverFrame') {
|
||||
// SignalR active with foreverFrame transport - use popup window
|
||||
window.open(url, '_blank', 'height=150,width=250,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
|
||||
} else {
|
||||
// use iFrame
|
||||
if (!$generationHost) {
|
||||
$generationHost = $('<iframe>')
|
||||
.attr({ 'src': url, 'title': 'Document Generation Host' })
|
||||
.addClass('hidden')
|
||||
.appendTo('body')
|
||||
.contents();
|
||||
} else {
|
||||
$generationHost[0].location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateHandlers = function (templateId) {
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $loadingUi = $handlersDialog.find('#Document_Generation_Dialog_Handlers_Loading');
|
||||
|
||||
$handlerPicker.find('div.handler').remove();
|
||||
$loadingUi.show();
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append('templateId', decodeURI(templateId));
|
||||
formData.append('targetId', decodeURI(targetId));
|
||||
fetch(handlersUrl, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
}).then(r => r.json())
|
||||
.then(data => {
|
||||
$loadingUi.hide();
|
||||
$.each(data.Handlers, (i, h) => {
|
||||
$('<div class="handler">').text(h.Title).attr({
|
||||
'data-id': h.Id,
|
||||
'data-uiurl': h.UiUrl
|
||||
}).prepend($('<i class="fa fa-fw fa-lg">').addClass('fa-'+h.Icon)).appendTo($handlerPicker);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$control.change(function () {
|
||||
var templateId = $control.val();
|
||||
if (templateId) {
|
||||
if (handlersPresent) {
|
||||
if (!$handlersDialog) {
|
||||
$handlersDialog = $container.find('#Document_Generation_Dialog');
|
||||
$handlersDialog.dialog({
|
||||
width: 750,
|
||||
height: 500,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
buttons: {
|
||||
Cancel: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
$handlersDialog.find('#Document_Generation_Dialog_Download').click(e => {
|
||||
e.preventDefault();
|
||||
downloadPdf(templateId);
|
||||
$handlersDialog.dialog('close');
|
||||
return false;
|
||||
})
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $Document_Generation_Dialog_Download_Container = $handlersDialog.find('#Document_Generation_Dialog_Download_Container');
|
||||
const $Document_Generation_Dialog_HandlerUI = $handlersDialog.find('#Document_Generation_Dialog_HandlerUI');
|
||||
$handlerPicker.on('click', 'div[data-id]', e => {
|
||||
$handlerPicker.find('div').removeClass('selected');
|
||||
const $this = $(e.currentTarget);
|
||||
$this.addClass('selected');
|
||||
const handlerId = $this.attr('data-id');
|
||||
if (handlerId === 'download') {
|
||||
$Document_Generation_Dialog_Download_Container.show();
|
||||
$Document_Generation_Dialog_HandlerUI.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
} else {
|
||||
$Document_Generation_Dialog_Download_Container.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
$Document_Generation_Dialog_HandlerUI.show();
|
||||
const uiurl = $this.attr('data-uiurl');
|
||||
fetch(uiurl, { method: 'POST' })
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
$Document_Generation_Dialog_HandlerUI.html(html);
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const $handlerPicker = $handlersDialog.find('.handlerPicker');
|
||||
const $Document_Generation_Dialog_Download_Container = $handlersDialog.find('#Document_Generation_Dialog_Download_Container');
|
||||
const $Document_Generation_Dialog_HandlerUI = $handlersDialog.find('#Document_Generation_Dialog_HandlerUI');
|
||||
$handlerPicker.find('div').removeClass('selected');
|
||||
$handlerPicker.find('div[data-id=download]').addClass('selected');
|
||||
$Document_Generation_Dialog_Download_Container.show();
|
||||
$Document_Generation_Dialog_HandlerUI.hide();
|
||||
$Document_Generation_Dialog_HandlerUI.empty();
|
||||
|
||||
$handlersDialog.dialog('option', 'title', 'Generate Document: ' + $control[0].selectedOptions[0].label);
|
||||
$handlersDialog.dialog('open');
|
||||
updateHandlers(templateId);
|
||||
} else {
|
||||
downloadPdf(templateId);
|
||||
}
|
||||
$control.val('').blur();
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
})(window, document, $);
|
||||
@@ -1509,3 +1509,65 @@ textarea.block {
|
||||
#licence li {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#Document_Generation_Dialog {
|
||||
height: 490px;
|
||||
}
|
||||
#Document_Generation_Dialog .handlerPicker {
|
||||
position: absolute;
|
||||
width: 170px;
|
||||
height: 390px;
|
||||
overflow-y: auto;
|
||||
background-color: #fcfcfc;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
#Document_Generation_Dialog .handlerPicker > div {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 6px 0 6px 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#Document_Generation_Dialog .handlerPicker > div:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
#Document_Generation_Dialog .handlerPicker > div.selected,
|
||||
#Document_Generation_Dialog .handlerPicker > div.selected:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
#Document_Generation_Dialog .handlerPicker #Document_Generation_Dialog_Handlers_Loading {
|
||||
text-align: center;
|
||||
}
|
||||
#Document_Generation_Dialog .details {
|
||||
position: absolute;
|
||||
left: 200px;
|
||||
height: 390px;
|
||||
width: 540px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#Document_Generation_Dialog .details #Document_Generation_Dialog_Download_Container {
|
||||
text-align: center;
|
||||
padding-top: 3em;
|
||||
}
|
||||
#Document_Generation_Dialog .details #Document_Generation_Dialog_HandlerUI {
|
||||
display: none;
|
||||
}
|
||||
ul.list-group {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
ul.list-group li {
|
||||
padding: 6px 0 6px 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
ul.list-group li:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
ul.list-group li.selected,
|
||||
ul.list-group li.selected:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
ul.list-group li:not(:first-child) {
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
@@ -1597,3 +1597,77 @@ textarea.block {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
#Document_Generation_Dialog {
|
||||
height: 490px;
|
||||
|
||||
.handlerPicker {
|
||||
position: absolute;
|
||||
width: 170px;
|
||||
height: 390px;
|
||||
overflow-y: auto;
|
||||
background-color: #fcfcfc;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
& > div {
|
||||
background-color: @white;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 6px 0 6px 6px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: @TableDataBorderColour;
|
||||
}
|
||||
|
||||
&.selected, &.selected:hover {
|
||||
background-color: @TableDataDarkBackgroundColour;
|
||||
}
|
||||
}
|
||||
|
||||
#Document_Generation_Dialog_Handlers_Loading {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
position: absolute;
|
||||
left: 200px;
|
||||
height: 390px;
|
||||
width: 540px;
|
||||
overflow-y: auto;
|
||||
|
||||
#Document_Generation_Dialog_Download_Container {
|
||||
text-align: center;
|
||||
padding-top: 3em;
|
||||
}
|
||||
|
||||
#Document_Generation_Dialog_HandlerUI {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.list-group {
|
||||
background-color: @white;
|
||||
border: 1px solid #ddd;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
padding: 6px 0 6px 6px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: @TableDataBorderColour;
|
||||
}
|
||||
|
||||
&.selected, &.selected:hover {
|
||||
background-color: @TableDataDarkBackgroundColour;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ using Disco.Models.Services.Jobs.JobLists;
|
||||
using Disco.Models.Services.Plugins.Details;
|
||||
using Disco.Models.UI.Device;
|
||||
using Disco.Services.Plugins;
|
||||
using Disco.Services.Plugins.Features.DocumentHandlerProvider;
|
||||
using Disco.Web.Models.Shared;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.Web.Models.Device
|
||||
{
|
||||
@@ -30,6 +32,7 @@ namespace Disco.Web.Models.Device
|
||||
Target = Device,
|
||||
Templates = DocumentTemplates,
|
||||
TemplatePackages = DocumentTemplatePackages,
|
||||
HandlersPresent = Plugins.GetPluginFeatures(typeof(DocumentHandlerProviderFeature)).Any(),
|
||||
};
|
||||
|
||||
public DetailsResult DeviceDetails { get; set; }
|
||||
|
||||
@@ -3,9 +3,12 @@ using Disco.Models.Services.Job;
|
||||
using Disco.Models.Services.Jobs.JobLists;
|
||||
using Disco.Models.Services.Plugins.Details;
|
||||
using Disco.Models.UI.Job;
|
||||
using Disco.Services.Plugins;
|
||||
using Disco.Services.Plugins.Features.DocumentHandlerProvider;
|
||||
using Disco.Web.Models.Shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.Web.Models.Job
|
||||
{
|
||||
@@ -22,6 +25,7 @@ namespace Disco.Web.Models.Job
|
||||
Target = Job,
|
||||
Templates = AvailableDocumentTemplates,
|
||||
TemplatePackages = AvailableDocumentTemplatePackages,
|
||||
HandlersPresent = Plugins.GetPluginFeatures(typeof(DocumentHandlerProviderFeature)).Any(),
|
||||
};
|
||||
|
||||
public List<Disco.Models.Repository.JobSubType> UpdatableJobSubTypes { get; set; }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Models.Services.Documents;
|
||||
using Disco.Services.Plugins.Features.DocumentHandlerProvider;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Disco.Web.Models.Shared
|
||||
@@ -10,5 +9,6 @@ namespace Disco.Web.Models.Shared
|
||||
public IAttachmentTarget Target { get; set; }
|
||||
public List<DocumentTemplate> Templates { get; set; }
|
||||
public List<DocumentTemplatePackage> TemplatePackages { get; set; }
|
||||
public bool HandlersPresent { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using Disco.Models.Services.Documents;
|
||||
using Disco.Models.Services.Jobs.JobLists;
|
||||
using Disco.Models.Services.Plugins.Details;
|
||||
using Disco.Models.UI.User;
|
||||
using Disco.Services.Plugins;
|
||||
using Disco.Services.Plugins.Features.DocumentHandlerProvider;
|
||||
using Disco.Web.Models.Shared;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -21,6 +23,7 @@ namespace Disco.Web.Models.User
|
||||
Target = User,
|
||||
Templates = DocumentTemplates,
|
||||
TemplatePackages = DocumentTemplatePackages,
|
||||
HandlersPresent = Plugins.GetPluginFeatures(typeof(DocumentHandlerProviderFeature)).Any(),
|
||||
};
|
||||
|
||||
public List<UserFlag> AvailableUserFlags { get; set; }
|
||||
|
||||
@@ -5,54 +5,28 @@
|
||||
selectListItems.Add(new SelectListItem() { Selected = true, Value = string.Empty, Text = "Generate Document" });
|
||||
selectListItems.AddRange(Model.Templates.ToSelectListItems());
|
||||
selectListItems.AddRange(Model.TemplatePackages.ToSelectListItems());
|
||||
<div id="Document_Generation_Container">
|
||||
<div id="Document_Generation_Container" data-targetid="@HttpUtility.UrlEncode(Model.Target.AttachmentReferenceId)" data-targettype="@Model.Target.HasAttachmentType" data-generatepdfurl="@Url.Action(MVC.API.DocumentTemplate.Generate())/" data-generatepackageurl="@Url.Action(MVC.API.DocumentTemplatePackage.Generate())/" data-handlerspresent="@(Model.HandlersPresent ? "true" : "false")" data-handlersurl="@Url.Action(MVC.API.DocumentTemplate.DocumentHandlers())">
|
||||
@Html.DropDownList("Document_Generate", selectListItems)
|
||||
<div id="Document_Generation_Dialog" class="dialog" title="Generate Document">
|
||||
</div>
|
||||
@if (Model.HandlersPresent)
|
||||
{
|
||||
<div id="Document_Generation_Dialog" class="dialog" title="Generate Document">
|
||||
<div class="handlerPicker">
|
||||
<div data-id="download" class="selected">
|
||||
<i class="fa fa-download fa-fw fa-lg"></i>Download
|
||||
</div>
|
||||
<div id="Document_Generation_Dialog_Handlers_Loading">
|
||||
<i class="ajaxLoading" title="Loading"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<div id="Document_Generation_Dialog_Download_Container">
|
||||
<a id="Document_Generation_Dialog_Download" href="#" class="button">Download Document</a>
|
||||
</div>
|
||||
<div id="Document_Generation_Dialog_HandlerUI">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var generatePdfUrl = '@Url.Action(MVC.API.DocumentTemplate.Generate())/';
|
||||
var generatePackageUrl = '@Url.Action(MVC.API.DocumentTemplatePackage.Generate())/';
|
||||
var generateTargetId = '@HttpUtility.UrlEncode(Model.Target.AttachmentReferenceId)';
|
||||
var $control = $('#Document_Generate');
|
||||
var $generationHost;
|
||||
|
||||
var downloadDocument = function (templateId) {
|
||||
|
||||
var url;
|
||||
if (templateId.lastIndexOf('Package:', 0) === 0)
|
||||
url = generatePackageUrl + templateId.substring(8);
|
||||
else
|
||||
url = generatePdfUrl + templateId;
|
||||
url = url + '?TargetId=' + generateTargetId;
|
||||
|
||||
if ($.connection && $.connection.hub && $.connection.hub.transport &&
|
||||
$.connection.hub.transport.name == 'foreverFrame') {
|
||||
// SignalR active with foreverFrame transport - use popup window
|
||||
window.open(url, '_blank', 'height=150,width=250,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
|
||||
} else {
|
||||
// use iFrame
|
||||
if (!$generationHost) {
|
||||
$generationHost = $('<iframe>')
|
||||
.attr({ 'src': url, 'title': 'Document Generation Host' })
|
||||
.addClass('hidden')
|
||||
.appendTo('body')
|
||||
.contents();
|
||||
} else {
|
||||
$generationHost[0].location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$control.change(function () {
|
||||
var templateId = $control.val();
|
||||
if (templateId) {
|
||||
downloadDocument(templateId);
|
||||
|
||||
$control.val('').blur();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Html.BundleDeferred("~/ClientScripts/Modules/Disco-DocumentGenerator");
|
||||
}
|
||||
@@ -59,6 +59,72 @@ WriteLiteral(" <div");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Container\"");
|
||||
|
||||
WriteLiteral(" data-targetid=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(HttpUtility.UrlEncode(Model.Target.AttachmentReferenceId));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\"");
|
||||
|
||||
WriteLiteral(" data-targettype=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Model.Target.HasAttachmentType);
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\"");
|
||||
|
||||
WriteLiteral(" data-generatepdfurl=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Url.Action(MVC.API.DocumentTemplate.Generate()));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("/\"");
|
||||
|
||||
WriteLiteral(" data-generatepackageurl=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Url.Action(MVC.API.DocumentTemplatePackage.Generate()));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("/\"");
|
||||
|
||||
WriteLiteral(" data-handlerspresent=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Model.HandlersPresent ? "true" : "false");
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\"");
|
||||
|
||||
WriteLiteral(" data-handlersurl=\"");
|
||||
|
||||
|
||||
#line 8 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Url.Action(MVC.API.DocumentTemplate.DocumentHandlers()));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\"");
|
||||
|
||||
WriteLiteral(">\r\n");
|
||||
|
||||
WriteLiteral(" ");
|
||||
@@ -70,7 +136,23 @@ WriteLiteral(" ");
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\r\n <div");
|
||||
WriteLiteral("\r\n");
|
||||
|
||||
|
||||
#line 10 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 10 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
if (Model.HandlersPresent)
|
||||
{
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <div");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Dialog\"");
|
||||
|
||||
@@ -78,64 +160,64 @@ WriteLiteral(" class=\"dialog\"");
|
||||
|
||||
WriteLiteral(" title=\"Generate Document\"");
|
||||
|
||||
WriteLiteral(">\r\n </div>\r\n </div>\r\n");
|
||||
WriteLiteral(">\r\n <div");
|
||||
|
||||
WriteLiteral(" <script");
|
||||
WriteLiteral(" class=\"handlerPicker\"");
|
||||
|
||||
WriteLiteral(" type=\"text/javascript\"");
|
||||
WriteLiteral(">\r\n <div");
|
||||
|
||||
WriteLiteral(">\r\n $(function () {\r\n var generatePdfUrl = \'");
|
||||
WriteLiteral(" data-id=\"download\"");
|
||||
|
||||
WriteLiteral(" class=\"selected\"");
|
||||
|
||||
WriteLiteral(">\r\n <i");
|
||||
|
||||
WriteLiteral(" class=\"fa fa-download fa-fw fa-lg\"");
|
||||
|
||||
WriteLiteral("></i>Download\r\n </div>\r\n <div");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Dialog_Handlers_Loading\"");
|
||||
|
||||
WriteLiteral(">\r\n <i");
|
||||
|
||||
WriteLiteral(" class=\"ajaxLoading\"");
|
||||
|
||||
WriteLiteral(" title=\"Loading\"");
|
||||
|
||||
WriteLiteral("></i>\r\n </div>\r\n </div>\r\n <div");
|
||||
|
||||
WriteLiteral(" class=\"details\"");
|
||||
|
||||
WriteLiteral(">\r\n <div");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Dialog_Download_Container\"");
|
||||
|
||||
WriteLiteral(">\r\n <a");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Dialog_Download\"");
|
||||
|
||||
WriteLiteral(" href=\"#\"");
|
||||
|
||||
WriteLiteral(" class=\"button\"");
|
||||
|
||||
WriteLiteral(">Download Document</a>\r\n </div>\r\n <div");
|
||||
|
||||
WriteLiteral(" id=\"Document_Generation_Dialog_HandlerUI\"");
|
||||
|
||||
WriteLiteral(">\r\n </div>\r\n </div>\r\n </div>\r\n");
|
||||
|
||||
|
||||
#line 15 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Url.Action(MVC.API.DocumentTemplate.Generate()));
|
||||
#line 29 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
}
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("/\';\r\n var generatePackageUrl = \'");
|
||||
WriteLiteral(" </div>\r\n");
|
||||
|
||||
|
||||
#line 16 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(Url.Action(MVC.API.DocumentTemplatePackage.Generate()));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("/\';\r\n var generateTargetId = \'");
|
||||
|
||||
|
||||
#line 17 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Write(HttpUtility.UrlEncode(Model.Target.AttachmentReferenceId));
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("\';\r\n var $control = $(\'#Document_Generate\');\r\n var $generat" +
|
||||
"ionHost;\r\n\r\n var downloadDocument = function (templateId) {\r\n\r\n " +
|
||||
" var url;\r\n if (templateId.lastIndexOf(\'Package:\', 0) ==" +
|
||||
"= 0)\r\n url = generatePackageUrl + templateId.substring(8);\r\n " +
|
||||
" else\r\n url = generatePdfUrl + templateId;\r\n " +
|
||||
" url = url + \'?TargetId=\' + generateTargetId;\r\n\r\n if " +
|
||||
"($.connection && $.connection.hub && $.connection.hub.transport &&\r\n " +
|
||||
" $.connection.hub.transport.name == \'foreverFrame\') {\r\n " +
|
||||
" // SignalR active with foreverFrame transport - use popup window\r\n " +
|
||||
" window.open(url, \'_blank\', \'height=150,width=250,location=no,menubar=no," +
|
||||
"resizable=no,scrollbars=no,status=no,toolbar=no\');\r\n } else {\r\n " +
|
||||
" // use iFrame\r\n if (!$generationHost) {\r\n " +
|
||||
" $generationHost = $(\'<iframe>\')\r\n " +
|
||||
" .attr({ \'src\': url, \'title\': \'Document Generation Host\' })\r\n " +
|
||||
" .addClass(\'hidden\')\r\n .appendTo(\'body\')\r\n " +
|
||||
" .contents();\r\n } else {\r\n " +
|
||||
" $generationHost[0].location.href = url;\r\n }\r\n " +
|
||||
" }\r\n }\r\n\r\n $control.change(function () {\r\n " +
|
||||
" var templateId = $control.val();\r\n if (templateId) " +
|
||||
"{\r\n downloadDocument(templateId);\r\n\r\n $con" +
|
||||
"trol.val(\'\').blur();\r\n }\r\n });\r\n });\r\n </scr" +
|
||||
"ipt>\r\n");
|
||||
|
||||
|
||||
#line 58 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
#line 31 "..\..\Views\Shared\_GenerateDocumentControl.cshtml"
|
||||
Html.BundleDeferred("~/ClientScripts/Modules/Disco-DocumentGenerator");
|
||||
}
|
||||
|
||||
#line default
|
||||
|
||||
@@ -61,6 +61,12 @@
|
||||
"ClientSource/Scripts/Modules/Disco-PropertyChangeHelpers/disco.propertychangehelpers.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "ClientSource/Scripts/Modules/Disco-DocumentGenerator.js",
|
||||
"inputFiles": [
|
||||
"ClientSource/Scripts/Modules/Disco-DocumentGenerator/disco.documentgenerator.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "ClientSource/Scripts/Modules/Highcharts.js",
|
||||
"inputFiles": [
|
||||
|
||||
Reference in New Issue
Block a user