Feature: Device Batch Attachments

allows for attachments to be uploaded and associated with Device Batches
This commit is contained in:
Gary Sharp committed 2020-11-29 16:41:56 +11:00
1 parent e531ffe2b7
commit 28e5901929
26 files changed
+2153 -320

No files matched your search

+12
View File
@@ -163,6 +163,10 @@
<Compile Include="Migrations\201611100557315_DBv19.Designer.cs">
<DependentUpon>201611100557315_DBv19.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\202011260525547_DBv20.cs" />
<Compile Include="Migrations\202011260525547_DBv20.Designer.cs">
<DependentUpon>202011260525547_DBv20.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Migrations\DiscoDataMigrator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -235,6 +239,9 @@
<EmbeddedResource Include="Migrations\201611100557315_DBv19.resx">
<DependentUpon>201611100557315_DBv19.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\202011260525547_DBv20.resx">
<DependentUpon>202011260525547_DBv20.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@@ -246,6 +253,11 @@
<None Include="Resources\EmptyLogo.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
+27
View File
@@ -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 DBv20 : IMigrationMetadata
{
private readonly ResourceManager Resources = new ResourceManager(typeof(DBv20));
string IMigrationMetadata.Id
{
get { return "202011260525547_DBv20"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return Resources.GetString("Target"); }
}
}
}
@@ -0,0 +1,39 @@
namespace Disco.Data.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class DBv20 : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.DeviceBatchAttachments",
c => new
{
Id = c.Int(nullable: false, identity: true),
DeviceBatchId = c.Int(nullable: false),
TechUserId = c.String(nullable: false, maxLength: 50),
Filename = c.String(nullable: false, maxLength: 500),
MimeType = c.String(nullable: false, maxLength: 500),
Timestamp = c.DateTime(nullable: false),
Comments = c.String(nullable: false, maxLength: 500),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.DeviceBatches", t => t.DeviceBatchId)
.ForeignKey("dbo.Users", t => t.TechUserId)
.Index(t => t.DeviceBatchId)
.Index(t => t.TechUserId);
}
public override void Down()
{
DropIndex("dbo.DeviceBatchAttachments", new[] { "TechUserId" });
DropIndex("dbo.DeviceBatchAttachments", new[] { "DeviceBatchId" });
DropForeignKey("dbo.DeviceBatchAttachments", "TechUserId", "dbo.Users");
DropForeignKey("dbo.DeviceBatchAttachments", "DeviceBatchId", "dbo.DeviceBatches");
DropTable("dbo.DeviceBatchAttachments");
}
}
}
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Target" xml:space="preserve">
<value>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 truncated
</data>
</root>
@@ -34,6 +34,7 @@ namespace Disco.Data.Repository
public virtual DbSet<DeviceModel> DeviceModels { get; set; }
public virtual DbSet<DeviceProfile> DeviceProfiles { get; set; }
public virtual DbSet<DeviceBatch> DeviceBatches { get; set; }
public virtual DbSet<DeviceBatchAttachment> DeviceBatchAttachments { get; set; }
public virtual DbSet<DeviceComponent> DeviceComponents { get; set; }
public virtual DbSet<DeviceAttachment> DeviceAttachments { get; set; }
@@ -4,6 +4,7 @@
{
Device,
Job,
User
User,
DeviceBatch,
}
}
@@ -50,6 +50,7 @@ namespace Disco.Models.Repository
[ForeignKey("DefaultDeviceModelId")]
public virtual DeviceModel DefaultDeviceModel { get; set; }
public virtual IList<DeviceBatchAttachment> DeviceBatchAttachments { get; set; }
public virtual IList<Device> Devices { get; set; }
public override string ToString()
@@ -0,0 +1,38 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Disco.Models.Repository
{
public class DeviceBatchAttachment : IAttachment
{
[Key]
public int Id { get; set; }
public int DeviceBatchId { get; set; }
[Required]
public string TechUserId { get; set; }
[StringLength(500), Required]
public string Filename { get; set; }
[Required, StringLength(500)]
public string MimeType { get; set; }
public DateTime Timestamp { get; set; }
[Required, StringLength(500)]
public string Comments { get; set; }
[NotMapped]
public object Reference => DeviceBatchId;
[NotMapped]
public AttachmentTypes AttachmentType => AttachmentTypes.DeviceBatch;
[NotMapped]
public string DocumentTemplateId { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
[InverseProperty(nameof(Repository.DeviceBatch.DeviceBatchAttachments)), ForeignKey(nameof(DeviceBatchId))]
public virtual DeviceBatch DeviceBatch { get; set; }
[ForeignKey("TechUserId")]
public virtual User TechUser { get; set; }
}
}
@@ -38,6 +38,21 @@ namespace Disco.Services
DocumentTemplateManagedGroups.TriggerDeviceAttachmentDeleted(Database, attachmentId, documentTemplateId, deviceSerialNumber);
}
public static bool CanDelete(this DeviceBatchAttachment attachment)
{
if (UserService.CurrentAuthorization.Has(Claims.Config.DeviceBatch.Configure))
return true;
return false;
}
public static void OnDelete(this DeviceBatchAttachment attachment, DiscoDataContext Database)
{
if (!attachment.CanDelete())
throw new InvalidOperationException("Deletion of Attachment is Denied");
attachment.RepositoryDelete(Database);
Database.DeviceBatchAttachments.Remove(attachment);
}
public static bool CanDelete(this JobAttachment ja)
{
if (UserService.CurrentAuthorization.Has(Claims.Job.Actions.RemoveAnyAttachments))
@@ -9,39 +9,45 @@ namespace Disco.Services
public static class AttachmentDataStoreExtensions
{
public static string RepositoryFilename(this IAttachment Attachment, DiscoDataContext Database)
public static string RepositoryFilename(this IAttachment attachment, DiscoDataContext database)
{
switch (Attachment.AttachmentType)
switch (attachment.AttachmentType)
{
case AttachmentTypes.Device:
return Path.Combine(DataStore.CreateLocation(Database, "DeviceAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_file", Attachment.Reference, Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "DeviceAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_file");
case AttachmentTypes.DeviceBatch:
return Path.Combine(DataStore.CreateLocation(database, "DeviceBatchAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_file");
case AttachmentTypes.Job:
return Path.Combine(DataStore.CreateLocation(Database, "JobAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_file", Attachment.Reference, Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "JobAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_file");
case AttachmentTypes.User:
return Path.Combine(DataStore.CreateLocation(Database, "UserAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_file", ((string)Attachment.Reference).Replace('\\', '_'), Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "UserAttachments", attachment.Timestamp),
$"{((string)attachment.Reference).Replace('\\', '_')}_{attachment.Id}_file");
default:
throw new ArgumentException("Unknown Attachment Type", nameof(Attachment));
throw new ArgumentException("Unknown Attachment Type", nameof(attachment));
}
}
public static string RepositoryThumbnailFilename(this IAttachment Attachment, DiscoDataContext Database)
public static string RepositoryThumbnailFilename(this IAttachment attachment, DiscoDataContext database)
{
switch (Attachment.AttachmentType)
switch (attachment.AttachmentType)
{
case AttachmentTypes.Device:
return Path.Combine(DataStore.CreateLocation(Database, "DeviceAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_thumb.jpg", Attachment.Reference, Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "DeviceAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_thumb.jpg");
case AttachmentTypes.DeviceBatch:
return Path.Combine(DataStore.CreateLocation(database, "DeviceBatchAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_thumb.jpg");
case AttachmentTypes.Job:
return Path.Combine(DataStore.CreateLocation(Database, "JobAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_thumb.jpg", Attachment.Reference, Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "JobAttachments", attachment.Timestamp),
$"{attachment.Reference}_{attachment.Id}_thumb.jpg");
case AttachmentTypes.User:
return Path.Combine(DataStore.CreateLocation(Database, "UserAttachments", Attachment.Timestamp),
string.Format("{0}_{1}_thumb.jpg", ((string)Attachment.Reference).Replace('\\', '_'), Attachment.Id));
return Path.Combine(DataStore.CreateLocation(database, "UserAttachments", attachment.Timestamp),
$"{((string)attachment.Reference).Replace('\\', '_')}_{attachment.Id}_thumb.jpg");
default:
throw new ArgumentException("Unknown Attachment Type", nameof(Attachment));
throw new ArgumentException("Unknown Attachment Type", nameof(attachment));
}
}
@@ -0,0 +1,72 @@
using Disco.Data.Repository;
using Disco.Data.Repository.Monitor;
using Disco.Models.Repository;
using Disco.Services.Authorization;
using Disco.Services.Web.Signalling;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
namespace Disco.Services.Devices
{
[HubName("deviceBatchUpdates"), DiscoHubAuthorizeAny(Claims.Config.DeviceBatch.Show, Claims.Config.DeviceBatch.Configure)]
public class DeviceBatchUpdatesHub : Hub
{
private const string UserPrefix = "DeviceBatch_";
public static IHubContext HubContext { get; private set; }
private static IDisposable RepositoryBeforeSubscription;
private static IDisposable RepositoryAfterSubscription;
static DeviceBatchUpdatesHub()
{
HubContext = GlobalHost.ConnectionManager.GetHubContext<DeviceBatchUpdatesHub>();
// Subscribe to Repository Monitor for Changes
RepositoryBeforeSubscription = RepositoryMonitor.StreamBeforeCommit
.Where(e => e.EntityType == typeof(DeviceBatchAttachment) && e.EventType == RepositoryMonitorEventType.Deleted)
.Subscribe(RepositoryEventBefore);
RepositoryAfterSubscription = RepositoryMonitor.StreamAfterCommit
.Where(e => e.EntityType == typeof(DeviceBatchAttachment) && e.EventType == RepositoryMonitorEventType.Added)
.Subscribe(RepositoryAfterEvent);
}
private static string GroupName(int deviceBatchId)
{
return $"{UserPrefix}{deviceBatchId}";
}
public override Task OnConnected()
{
if (!int.TryParse(Context.QueryString["DeviceBatchId"], out var deviceBatchId))
throw new ArgumentNullException("DeviceBatchId");
Groups.Add(Context.ConnectionId, GroupName(deviceBatchId));
return base.OnConnected();
}
private static void RepositoryEventBefore(RepositoryMonitorEvent e)
{
if (e.EventType == RepositoryMonitorEventType.Deleted && e.Entity is DeviceBatchAttachment attachment)
{
using (DiscoDataContext Database = new DiscoDataContext())
{
var deviceBatchId = Database.DeviceBatchAttachments.Where(a => a.Id == attachment.Id).Select(a => a.DeviceBatchId).First();
HubContext.Clients.Group(GroupName(deviceBatchId)).removeAttachment(attachment.Id);
}
}
}
private static void RepositoryAfterEvent(RepositoryMonitorEvent e)
{
if (e.EventType == RepositoryMonitorEventType.Added && e.Entity is DeviceBatchAttachment attachment)
{
HubContext.Clients.Group(GroupName(attachment.DeviceBatchId)).addAttachment(attachment.Id);
}
}
}
}
+8 -1
View File
@@ -243,6 +243,7 @@
<Compile Include="Devices\DeviceExtensions.cs" />
<Compile Include="Devices\DeviceModelExtensions.cs" />
<Compile Include="Devices\DeviceProfileExtensions.cs" />
<Compile Include="Devices\DeviceBatchUpdatesHub.cs" />
<Compile Include="Devices\DeviceWirelessProfileExtensions.cs" />
<Compile Include="Devices\Enrolment\DeviceEnrolment.cs" />
<Compile Include="Devices\Enrolment\EnrolmentLog.cs" />
@@ -325,6 +326,7 @@
<Compile Include="Extensions\DateTimeExtensions.cs" />
<Compile Include="Extensions\EnumerableExtensions.cs" />
<Compile Include="Extensions\ImagingExtensions.cs" />
<Compile Include="Extensions\MeasurementUnitExtensions.cs" />
<Compile Include="Extensions\RxExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Extensions\UIHelpers.cs" />
@@ -335,7 +337,7 @@
<Compile Include="Interop\ActiveDirectory\ActiveDirectoryManagedGroups.cs" />
<Compile Include="Interop\ActiveDirectory\ADDeviceDescriptionUpdateTask.cs" />
<Compile Include="Interop\ActiveDirectory\ADDirectoryEntry.cs" />
<Compile Include="Interop\ActiveDirectory\ADDiscoverForestServers.cs" />
<Compile Include="Interop\ActiveDirectory\ADDiscoverServers.cs" />
<Compile Include="Interop\ActiveDirectory\ADDomain.cs" />
<Compile Include="Interop\ActiveDirectory\ADDomainController.cs" />
<Compile Include="Interop\ActiveDirectory\ADGroup.cs" />
@@ -532,6 +534,11 @@
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
@@ -1,7 +1,9 @@
using Disco.Models.Repository;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Devices;
using Disco.Services.Devices.ManagedGroups;
using Disco.Services.Interop;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Tasks;
using Disco.Services.Web;
@@ -607,5 +609,137 @@ namespace Disco.Web.Areas.API.Controllers
}
#endregion
#region Attachements
[DiscoAuthorize(Claims.Config.DeviceBatch.Show)]
[OutputCache(Location = System.Web.UI.OutputCacheLocation.Client, Duration = 172800)]
public virtual ActionResult AttachmentDownload(int id)
{
var attachment = Database.DeviceBatchAttachments.Find(id);
if (attachment != null)
{
var filePath = attachment.RepositoryFilename(Database);
if (System.IO.File.Exists(filePath))
{
return File(filePath, attachment.MimeType, attachment.Filename);
}
else
{
return HttpNotFound("Attachment reference exists, but file not found");
}
}
return HttpNotFound("Invalid Attachment Number");
}
[DiscoAuthorize(Claims.Config.DeviceBatch.Show)]
[OutputCache(Location = System.Web.UI.OutputCacheLocation.Client, Duration = 172800)]
public virtual ActionResult AttachmentThumbnail(int id)
{
var attachment = Database.DeviceBatchAttachments.Find(id);
if (attachment != null)
{
var thumbPath = attachment.RepositoryThumbnailFilename(Database);
if (System.IO.File.Exists(thumbPath))
{
if (thumbPath.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
return File(thumbPath, "image/png");
else
return File(thumbPath, "image/jpg");
}
else
return File(ClientSource.Style.Images.AttachmentTypes.MimeTypeIcons.Icon(attachment.MimeType), "image/png");
}
return HttpNotFound("Invalid Attachment Number");
}
[DiscoAuthorize(Claims.Config.DeviceBatch.Configure)]
public virtual ActionResult AttachmentUpload(int id, string Comments)
{
var batch = Database.DeviceBatches.Find(id);
if (batch != null)
{
if (Request.Files.Count > 0)
{
var file = Request.Files.Get(0);
if (file.ContentLength > 0)
{
var contentType = file.ContentType;
if (string.IsNullOrEmpty(contentType) || contentType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
contentType = MimeTypes.ResolveMimeType(file.FileName);
var attachment = new Disco.Models.Repository.DeviceBatchAttachment()
{
DeviceBatchId = batch.Id,
TechUserId = CurrentUser.UserId,
Filename = file.FileName,
MimeType = contentType,
Timestamp = DateTime.Now,
Comments = Comments
};
Database.DeviceBatchAttachments.Add(attachment);
Database.SaveChanges();
attachment.SaveAttachment(Database, file.InputStream);
attachment.GenerateThumbnail(Database);
return Json(attachment.Id, JsonRequestBehavior.AllowGet);
}
}
throw new Exception("No Attachment Uploaded");
}
throw new Exception("Invalid Device Batch Id");
}
[DiscoAuthorize(Claims.Config.DeviceBatch.Show)]
public virtual ActionResult Attachment(int id)
{
var attachment = Database.DeviceBatchAttachments.Include("TechUser").Where(m => m.Id == id).FirstOrDefault();
if (attachment != null)
{
var m = new Models.Attachment.AttachmentModel()
{
Attachment = Models.Attachment._AttachmentModel.FromAttachment(attachment),
Result = "OK"
};
return Json(m, JsonRequestBehavior.AllowGet);
}
return Json(new Models.Attachment.AttachmentModel() { Result = "Invalid Attachment Number" }, JsonRequestBehavior.AllowGet);
}
[DiscoAuthorize(Claims.Config.DeviceBatch.Show)]
public virtual ActionResult Attachments(int id)
{
var batch = Database.DeviceBatches.Include("DeviceBatchAttachments.TechUser").Where(m => m.Id == id).FirstOrDefault();
if (batch != null)
{
var m = new Models.Attachment.AttachmentsModel()
{
Attachments = batch.DeviceBatchAttachments.Select(a => Models.Attachment._AttachmentModel.FromAttachment(a)).ToList(),
Result = "OK"
};
return Json(m, JsonRequestBehavior.AllowGet);
}
return Json(new Models.Attachment.AttachmentsModel() { Result = "Invalid Device Batch Id" }, JsonRequestBehavior.AllowGet);
}
[DiscoAuthorize(Claims.Config.DeviceBatch.Configure)]
public virtual ActionResult AttachmentRemove(int id)
{
var attachment = Database.DeviceBatchAttachments.Include("TechUser").Where(m => m.Id == id).FirstOrDefault();
if (attachment != null)
{
attachment.OnDelete(Database);
Database.SaveChanges();
return Json("OK", JsonRequestBehavior.AllowGet);
}
return Json("Invalid Attachment Number", JsonRequestBehavior.AllowGet);
}
#endregion
}
}
@@ -76,6 +76,22 @@ namespace Disco.Web.Areas.API.Models.Attachment
MimeType = da.MimeType
};
}
public static _AttachmentModel FromAttachment(Disco.Models.Repository.DeviceBatchAttachment attachment)
{
return new _AttachmentModel
{
ParentId = attachment.DeviceBatchId.ToString(),
Id = attachment.Id,
AuthorId = attachment.TechUserId,
Author = attachment.TechUser.ToStringFriendly(),
Timestamp = attachment.Timestamp,
Comments = attachment.Comments,
DocumentTemplateId = null, // not supported for DeviceBatchAttachment
DocumentTemplateDescription = null, // not supported for DeviceBatchAttachment
Filename = attachment.Filename,
MimeType = attachment.MimeType
};
}
}
}
@@ -1,4 +1,5 @@
using Disco.Models.UI.Config.DeviceBatch;
using Disco.Models.Repository;
using Disco.Models.UI.Config.DeviceBatch;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Devices;
@@ -20,7 +21,9 @@ namespace Disco.Web.Areas.Config.Controllers
if (id.HasValue)
{
var m = Database.DeviceBatches.Where(db => db.Id == id.Value)
var m = Database.DeviceBatches
.Include(nameof(DeviceBatch.DeviceBatchAttachments))
.Where(db => db.Id == id.Value)
.Select(db => new Models.DeviceBatch.ShowModel()
{
DeviceBatch = db,
@@ -13,11 +13,16 @@
Model.DeviceBatch.AssignedUsersLinkedGroup == null &&
Model.DeviceBatch.DevicesLinkedGroup == null;
Html.BundleDeferred("~/Style/Shadowbox");
Html.BundleDeferred("~/ClientScripts/Modules/Shadowbox");
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-SignalR");
if (canConfig)
{
Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers");
Html.BundleDeferred("~/ClientScripts/Modules/Disco-AjaxHelperIcons");
Html.BundleDeferred("~/ClientScripts/Modules/tinymce");
Html.BundleDeferred("~/ClientScripts/Modules/Disco-AttachmentUploader");
}
}
<div class="form deviceBatches@(hideAdvanced ? " Config_HideAdvanced" : null)" style="width: 730px">
@@ -660,6 +665,301 @@
}
</td>
</tr>
<tr>
<th>Attachments:</th>
<td>
<div id="DeviceBatch_Attachments" class="@(canConfig ? "canAddAttachments" : "cannotAddAttachments")">
<div class="Disco-AttachmentUpload-DropTarget">
<h2>Drop Attachments Here</h2>
</div>
<div class="attachmentOutput">
@if (Model.DeviceBatch.DeviceBatchAttachments != null)
{
foreach (var attachment in Model.DeviceBatch.DeviceBatchAttachments)
{
<a href="@Url.Action(MVC.API.DeviceBatch.AttachmentDownload(attachment.Id))" data-attachmentid="@attachment.Id" data-mimetype="@attachment.MimeType">
<span class="icon" title="@attachment.Filename">
<img alt="Attachment Thumbnail" src="@(Url.Action(MVC.API.DeviceBatch.AttachmentThumbnail(attachment.Id)))" />
</span>
<span class="comments" title="@attachment.Comments">
@attachment.Comments
</span><span class="author">@attachment.TechUser.ToString()</span>@if (canConfig)
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" title="@attachment.Timestamp.ToFullDateTime()" data-livestamp="@attachment.Timestamp.ToUnixEpoc()">@attachment.Timestamp.ToFullDateTime()</span>
</a>
}
}
</div>
@if (canConfig)
{
<div class="Disco-AttachmentUpload-Progress"></div>
<div class="attachmentInput clearfix">
<span class="action upload fa fa-upload disabled" title="Attach File"></span><span class="action photo fa fa-camera disabled" title="Capture Image"></span>
</div>
<div id="dialogRemoveAttachment" class="dialog" title="Remove this Attachment?">
<p>
<i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
</p>
</div>
}
<script type="text/javascript">
Shadowbox.init({
skipSetup: true,
modal: true
});
$(function () {
var $Attachments = $('#DeviceBatch_Attachments');
var $attachmentOutput = $Attachments.find('.attachmentOutput');
var $attachmentDownloadHost;
var $dialogRemoveAttachment = null;
// Connect to Hub
var hub = $.connection.deviceBatchUpdates;
// Map Functions
hub.client.addAttachment = onAddAttachment;
hub.client.removeAttachment = onRemoveAttachment;
$.connection.hub.qs = { DeviceBatchId: '@(Model.DeviceBatch.Id)' };
$.connection.hub.error(onHubFailed);
$.connection.hub.disconnected(onHubFailed);
$.connection.hub.reconnecting(function () {
$Attachments.find('span.action').addClass('disabled');
});
$.connection.hub.reconnected(function () {
$Attachments.find('span.action').removeClass('disabled');
});
// Start Connection
$.connection.hub.start(function () {
$Attachments.find('span.action').removeClass('disabled');
}).fail(onHubFailed);
function onHubFailed(error) {
// Disable UI
$Attachments.find('span.action').addClass('disabled');
// Show Dialog Message
if ($('.disconnected-dialog').length == 0) {
$('<div>')
.addClass('dialog disconnected-dialog')
.html('<h3><span class="fa-stack fa-lg"><i class="fa fa-wifi fa-stack-1x"></i><i class="fa fa-ban fa-stack-2x error"></i></span>Disconnected from the Disco ICT Server</h3><div>This page is not receiving live updates. Please ensure you are connected to the server, then refresh this page to enable features.</div>')
.dialog({
resizable: false,
title: 'Disconnected',
width: 400,
modal: true,
buttons: {
'Refresh Now': function () {
$(this).dialog('option', 'buttons', null);
window.location.reload(true);
},
'Close': function () {
$(this).dialog('destroy');
}
}
});
}
}
function onAddAttachment(id, quick) {
var data = { id: id };
$.ajax({
url: '@Url.Action(MVC.API.DeviceBatch.Attachment())',
dataType: 'json',
data: data,
success: function (d) {
if (d.Result == 'OK') {
var a = d.Attachment;
@if (canConfig)
{
<text>buildAttachment(a, true, quick);</text>
}
else
{
<text>buildAttachment(a, false, quick);</text>
}
} else {
alert('Unable to add attachment: ' + d.Result);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to add attachment: ' + textStatus);
}
});
}
function buildAttachment(a, canRemove, quick) {
var t = '<a><span class="icon"><img alt="Attachment Thumbnail" /></span><span class="comments"></span><span class="author"></span>';
if (canRemove)
t += '<span class="remove fa fa-times-circle"></span>';
t += '<span class="timestamp"></span></a>';
var e = $(t);
e.attr('data-attachmentid', a.Id).attr('data-mimetype', a.MimeType).attr('href', '@(Url.Action(MVC.API.DeviceBatch.AttachmentDownload()))/' + a.Id);
e.find('.comments').text(a.Description);
e.find('.author').text(a.Author);
e.find('.timestamp').text(a.TimestampFull).attr('title', a.TimestampFull).livestamp(a.TimestampUnixEpoc);
if (canRemove)
e.find('.remove').click(removeAttachment);
if (!quick)
e.hide();
$attachmentOutput.append(e);
if (!quick)
e.show('slow');
if (a.MimeType.toLowerCase().indexOf('image/') == 0)
e.shadowbox({ gallery: 'attachments', player: 'img', title: a.Description });
else
e.click(onDownload);
// Add Thumbnail
var buildThumbnail = function () {
var retryCount = 0;
var img = e.find('.icon img');
var setThumbnailUrl = function () {
img.attr('src', '@(Url.Action(MVC.API.DeviceBatch.AttachmentThumbnail()))/' + a.Id + '?v=' + retryCount);
};
img.on('error', function () {
img.addClass('loading');
retryCount++;
if (retryCount < 6)
window.setTimeout(setThumbnailUrl, retryCount * 250);
});
img.on('load', function () {
img.removeClass('loading');
});
window.setTimeout(setThumbnailUrl, 100);
};
buildThumbnail();
}
function onRemoveAttachment(id) {
var a = $attachmentOutput.find('a[data-attachmentid=' + id + ']');
a.hide(300).delay(300).queue(function () {
var $this = $(this);
if ($this.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
Shadowbox.removeCache(this);
$this.find('.timestamp').livestamp('destroy');
$this.remove();
});
}
function onDownload() {
var $this = $(this);
var url = $this.attr('href');
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 (!$attachmentDownloadHost) {
$attachmentDownloadHost = $('<iframe>')
.attr({ 'src': url, 'title': 'Attachment Download Host' })
.addClass('hidden')
.appendTo('body')
.contents();
} else {
$attachmentDownloadHost[0].location.href = url;
}
}
return false;
}
@if (canConfig)
{<text>
//#region Add Attachments
var attachmentUploader = new document.Disco.AttachmentUploader(
'@(Url.Action(MVC.API.DeviceBatch.AttachmentUpload(Model.DeviceBatch.Id, null)))',
$Attachments.find('.Disco-AttachmentUpload-DropTarget'),
$Attachments.find('.Disco-AttachmentUpload-Progress'));
var $attachmentInput = $Attachments.find('.attachmentInput');
$attachmentInput.find('.photo').click(function () {
if ($(this).hasClass('disabled'))
alert('Disconnected from the Disco ICT Server, please refresh this page and try again');
else
attachmentUploader.uploadImage();
});
$attachmentInput.find('.upload').click(function () {
if ($(this).hasClass('disabled'))
alert('Disconnected from the Disco ICT Server, please refresh this page and try again');
else
attachmentUploader.uploadFiles();
});
//#endregion
//#region Remove Attachments
$attachmentOutput.find('span.remove').click(removeAttachment);
function removeAttachment() {
$this = $(this).closest('a');
var data = { id: $this.attr('data-attachmentid') };
if (!$dialogRemoveAttachment) {
$dialogRemoveAttachment = $('#dialogRemoveAttachment').dialog({
resizable: false,
height: 140,
modal: true,
autoOpen: false
});
}
$dialogRemoveAttachment.dialog("enable");
$dialogRemoveAttachment.dialog('option', 'buttons', {
"Remove": function () {
$dialogRemoveAttachment.dialog("disable");
$dialogRemoveAttachment.dialog("option", "buttons", null);
$.ajax({
url: '@Url.Action(MVC.API.DeviceBatch.AttachmentRemove())',
dataType: 'json',
data: data,
success: function (d) {
if (d == 'OK') {
// Do nothing, await SignalR notification
} else {
alert('Unable to remove attachment: ' + d);
}
$dialogRemoveAttachment.dialog("close");
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Unable to remove attachment: ' + textStatus);
$dialogRemoveAttachment.dialog("close");
}
});
},
Cancel: function () {
$dialogRemoveAttachment.dialog("close");
}
});
$dialogRemoveAttachment.dialog('open');
return false;
}
//#endregion
</text>}
$attachmentOutput.children('a').each(function () {
$this = $(this);
if ($this.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
$this.shadowbox({ gallery: 'attachments', player: 'img', title: $this.find('.comments').text() });
else
$this.click(onDownload);
});
});
</script>
</div>
</td>
</tr>
@if (hideAdvanced)
{
<tr>
File diff suppressed because it is too large. Load diff
@@ -15,4 +15,4 @@
* https://github.com/SignalR/SignalR/blob/master/LICENSE.md
*
*/
(function(n){"use strict";function r(t,i){return function(){i.apply(t,n.makeArray(arguments))}}function i(t,i){var e,u,f,o,s;for(e in t)if(t.hasOwnProperty(e)){if(u=t[e],!u.hubName)continue;s=i?u.on:u.off;for(f in u.client)if(u.client.hasOwnProperty(f)){if(o=u.client[f],!n.isFunction(o))continue;s.call(u,f,r(u,o))}}}if(typeof n.signalR!="function")throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/js.");var t=n.signalR;n.hubConnection.prototype.createHubProxies=function(){var t={};return this.starting(function(){i(t,!0);this._registerSubscribedHubs()}).disconnected(function(){i(t,!1)}),t.deviceUpdates=this.createHubProxy("deviceUpdates"),t.deviceUpdates.client={},t.deviceUpdates.server={},t.jobUpdates=this.createHubProxy("jobUpdates"),t.jobUpdates.client={},t.jobUpdates.server={},t.logNotifications=this.createHubProxy("logNotifications"),t.logNotifications.client={},t.logNotifications.server={},t.noticeboardUpdates=this.createHubProxy("noticeboardUpdates"),t.noticeboardUpdates.client={},t.noticeboardUpdates.server={},t.scheduledTaskNotifications=this.createHubProxy("scheduledTaskNotifications"),t.scheduledTaskNotifications.client={},t.scheduledTaskNotifications.server={getStatus:function(){return t.scheduledTaskNotifications.invoke.apply(t.scheduledTaskNotifications,n.merge(["GetStatus"],n.makeArray(arguments)))}},t.userUpdates=this.createHubProxy("userUpdates"),t.userUpdates.client={},t.userUpdates.server={},t};t.hub=n.hubConnection("/API/Signalling",{useDefaultPath:!1});n.extend(t,t.hub.createHubProxies())})(window.jQuery,window);
(function(n){"use strict";function r(t,i){return function(){i.apply(t,n.makeArray(arguments))}}function i(t,i){var e,u,f,o,s;for(e in t)if(t.hasOwnProperty(e)){if(u=t[e],!u.hubName)continue;s=i?u.on:u.off;for(f in u.client)if(u.client.hasOwnProperty(f)){if(o=u.client[f],!n.isFunction(o))continue;s.call(u,f,r(u,o))}}}if(typeof n.signalR!="function")throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/js.");var t=n.signalR;n.hubConnection.prototype.createHubProxies=function(){var t={};return this.starting(function(){i(t,!0);this._registerSubscribedHubs()}).disconnected(function(){i(t,!1)}),t.deviceBatchUpdates=this.createHubProxy("deviceBatchUpdates"),t.deviceBatchUpdates.client={},t.deviceBatchUpdates.server={},t.deviceUpdates=this.createHubProxy("deviceUpdates"),t.deviceUpdates.client={},t.deviceUpdates.server={},t.jobUpdates=this.createHubProxy("jobUpdates"),t.jobUpdates.client={},t.jobUpdates.server={},t.logNotifications=this.createHubProxy("logNotifications"),t.logNotifications.client={},t.logNotifications.server={},t.noticeboardUpdates=this.createHubProxy("noticeboardUpdates"),t.noticeboardUpdates.client={},t.noticeboardUpdates.server={},t.scheduledTaskNotifications=this.createHubProxy("scheduledTaskNotifications"),t.scheduledTaskNotifications.client={},t.scheduledTaskNotifications.server={getStatus:function(){return t.scheduledTaskNotifications.invoke.apply(t.scheduledTaskNotifications,n.merge(["GetStatus"],n.makeArray(arguments)))}},t.userUpdates=this.createHubProxy("userUpdates"),t.userUpdates.client={},t.userUpdates.server={},t};t.hub=n.hubConnection("/API/Signalling",{useDefaultPath:!1});n.extend(t,t.hub.createHubProxies())})(window.jQuery,window);
@@ -78,6 +78,11 @@
registerHubProxies(proxies, false);
});
proxies['deviceBatchUpdates'] = this.createHubProxy('deviceBatchUpdates');
proxies['deviceBatchUpdates'].client = {};
proxies['deviceBatchUpdates'].server = {
};
proxies['deviceUpdates'] = this.createHubProxy('deviceUpdates');
proxies['deviceUpdates'].client = { };
proxies['deviceUpdates'].server = {
+145 -41
View File
@@ -7,7 +7,7 @@
background-color: #fff;
}
.tableData > tbody > tr:nth-child(odd) > td {
background-color: #fbfbfb;
background-color: hsl(0, 0%, 98.5%);
}
.tableData > thead > tr > th,
.tableData > tbody > tr > th {
@@ -15,7 +15,7 @@
border: solid 1px #f4f4f4;
}
.tableData > tbody > tr:hover > td {
background-color: #f9f9f9;
background-color: hsl(0, 0%, 97.5%);
}
.tableData > tfoot > tr > th,
.tableData > tfoot > tr > td {
@@ -157,7 +157,7 @@ table.expressionsTable > tbody > tr > td {
background-color: #fff;
}
table.expressionsTable > tbody > tr:nth-child(odd) > td {
background-color: #fbfbfb;
background-color: hsl(0, 0%, 98.5%);
}
table.expressionsTable > thead > tr > th,
table.expressionsTable > tbody > tr > th {
@@ -165,7 +165,7 @@ table.expressionsTable > tbody > tr > th {
border: solid 1px #f4f4f4;
}
table.expressionsTable > tbody > tr:hover > td {
background-color: #f9f9f9;
background-color: hsl(0, 0%, 97.5%);
}
table.expressionsTable > tfoot > tr > th,
table.expressionsTable > tfoot > tr > td {
@@ -186,7 +186,7 @@ table.expressionsTable td.parseError {
background-color: #fff;
}
#deviceComponents > tbody > tr:nth-child(odd) > td {
background-color: #fbfbfb;
background-color: hsl(0, 0%, 98.5%);
}
#deviceComponents > thead > tr > th,
#deviceComponents > tbody > tr > th {
@@ -194,7 +194,7 @@ table.expressionsTable td.parseError {
border: solid 1px #f4f4f4;
}
#deviceComponents > tbody > tr:hover > td {
background-color: #f9f9f9;
background-color: hsl(0, 0%, 97.5%);
}
#deviceComponents > tfoot > tr > th,
#deviceComponents > tfoot > tr > td {
@@ -213,7 +213,7 @@ table.expressionsTable td.parseError {
font-size: 1.6em;
color: #e51400;
cursor: pointer;
opacity: .8;
opacity: 0.8;
}
#deviceComponents tr i.remove:hover {
opacity: 1;
@@ -259,7 +259,7 @@ table.expressionsTable td.parseError {
}
#organisationAddresses i.fa.delete {
color: #e51400;
opacity: .8;
opacity: 0.8;
}
#organisationAddresses i.fa.delete:hover {
opacity: 1;
@@ -472,15 +472,15 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.eventType {
border-bottom: 1px dashed #ccc;
}
#enrolStatus #sessions .session > h3 span.details {
font-size: .8em;
font-size: 0.8em;
}
#enrolStatus #sessions .session > p.sessionStart {
color: #888;
font-size: .8em;
font-size: 0.8em;
margin-bottom: 2px;
}
#enrolStatus #sessions .session > p.sessionStatus {
font-size: .9em;
font-size: 0.9em;
height: 1.6em;
overflow: hidden;
margin-bottom: 3px;
@@ -665,7 +665,7 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.eventType {
margin: 4px 0 0 6px;
}
#Config_DocumentTemplates_JobSubTypes_Update_Dialog .checkboxBulkSelectContainer {
font-size: .8em;
font-size: 0.8em;
}
#dialogBulkGenerate .brief {
margin: 0 0 8px 0;
@@ -750,7 +750,7 @@ h1.Config_DocumentTemplates {
margin: 4px 0 0 6px;
}
#Config_DocumentTemplatePackages_JobSubTypes_Update_Dialog .checkboxBulkSelectContainer {
font-size: .8em;
font-size: 0.8em;
}
#Config_DocumentTemplatePackages_Templates_Dialog h3 {
margin-bottom: 4px;
@@ -789,7 +789,7 @@ h1.Config_DocumentTemplates {
font-family: Consolas, "Courier New", monospace;
color: #888;
float: right;
font-size: .9em;
font-size: 0.9em;
}
#importStatus #sessions .session {
padding: 4px;
@@ -810,7 +810,7 @@ h1.Config_DocumentTemplates {
border-bottom: 1px dashed #ccc;
}
#importStatus #sessions .session .sessionLeftPane > h3 span.details {
font-size: .8em;
font-size: 0.8em;
}
#importStatus #sessions .session .sessionRightPane {
width: 48%;
@@ -819,11 +819,11 @@ h1.Config_DocumentTemplates {
}
#importStatus #sessions .session .sessionRightPane > p.sessionStart {
color: #888;
font-size: .8em;
font-size: 0.8em;
margin-bottom: 2px;
}
#importStatus #sessions .session .sessionRightPane > p.sessionStatus {
font-size: .9em;
font-size: 0.9em;
height: 1.6em;
overflow: hidden;
margin-bottom: 3px;
@@ -848,7 +848,7 @@ h1.Config_DocumentTemplates {
background-color: rgba(255, 255, 255, 0.8);
}
#importStatus #sessions .session .sessionPages > .sessionPage > .sessionPageDetails p.sessionStatus {
font-size: .9em;
font-size: 0.9em;
height: 1.6em;
margin-bottom: 3px;
}
@@ -933,7 +933,7 @@ h1.Config_DocumentTemplates {
float: left;
margin: 4px;
border: 1px solid #f4f4f4;
background-color: #fbfbfb;
background-color: hsl(0, 0%, 98.5%);
height: 256px;
width: 256px;
background-position: top center;
@@ -987,6 +987,110 @@ h1.Config_DocumentTemplates {
width: 570px;
height: 200px;
}
.deviceBatches #DeviceBatch_Attachments {
border: 1px solid #ccc;
background-color: #fff;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput {
position: relative;
height: 200px;
overflow: auto;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a {
display: block;
float: left;
height: 48px;
width: 221px;
padding: 2px;
margin: 2px;
font-size: 0.95em;
border: 1px solid #fff;
color: #000;
text-decoration: none;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.comments,
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.author,
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.timestamp {
display: block;
float: left;
width: 168px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 16px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.author {
color: #888;
width: 150px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.timestamp {
color: #888;
font-style: italic;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.icon {
display: block;
float: left;
height: 48px;
width: 48px;
margin-right: 2px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.icon img {
height: 48px;
width: 48px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.icon img.loading {
display: none;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a:hover {
background-color: #ededed;
border: 1px solid #ccc;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a:hover span.remove {
opacity: 0.5;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.remove {
font-size: 1.2em;
color: #e51400;
margin-left: 2px;
cursor: pointer;
opacity: 0;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentOutput > a span.remove:hover {
opacity: 1;
}
.deviceBatches #DeviceBatch_Attachments.cannotAddAttachments div.attachmentOutput {
height: 250px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentInput {
border-top: 1px solid #ccc;
height: 40px;
background-color: #fff;
padding: 5px;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentInput span.action {
color: #333;
display: block;
margin: 0 4px 0 0;
font-size: 1.5em;
cursor: pointer;
float: right;
border: 1px solid #fff;
padding: 0.5em;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentInput span.action:hover {
color: #335A87;
background-color: #ededed;
border: 1px solid #ccc;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentInput span.action.disabled {
color: rgba(51, 51, 51, 0.2);
cursor: default;
}
.deviceBatches #DeviceBatch_Attachments div.attachmentInput span.action.disabled:hover {
color: rgba(51, 51, 51, 0.2);
background-color: inherit;
border: 1px solid #fff;
}
#plugins .pageMenuArea a > h3 {
display: inline;
color: #335A87;
@@ -998,7 +1102,7 @@ h1.Config_DocumentTemplates {
padding-left: 18px;
}
#plugins .pageMenuArea .pageMenuBlurb i {
font-size: .9em;
font-size: 0.9em;
}
#plugins #pageMenu td .pageMenuArea:not(:last-child) {
padding-bottom: 5px;
@@ -1013,10 +1117,10 @@ h1.Config_DocumentTemplates {
color: #335A87;
}
#dialogUninstallPlugins #uninstallPlugin {
margin: .5em 0;
margin: 0.5em 0;
}
#dialogUninstallPlugins #uninstallPluginData {
margin: .5em 0;
margin: 0.5em 0;
}
#dialogUninstallPluginConfirm #uninstallPluginConfirm {
text-align: center;
@@ -1050,13 +1154,13 @@ h1.Config_DocumentTemplates {
margin: 0;
}
#pluginLibrary .pluginItem .pageMenuBlurb i {
font-size: .9em;
font-size: 0.9em;
}
#pluginLibrary .pluginItem > h2:first-child {
min-height: 22px;
}
#pluginLibrary .pluginItem > h2:first-child i {
font-size: .9em;
font-size: 0.9em;
padding-right: 4px;
color: #333;
}
@@ -1138,7 +1242,7 @@ h1.Config_DocumentTemplates {
background-color: #f4f4f4;
}
#Config_AuthRoles_Subjects_Update_Dialog #Config_AuthRoles_Subjects_Update_Dialog_List li:hover .remove {
opacity: .8;
opacity: 0.8;
}
#Config_AuthRoles_Subjects_Update_Dialog #Config_AuthRoles_Subjects_Update_Dialog_List li .remove {
margin-top: 2px;
@@ -1334,7 +1438,7 @@ h1.Config_DocumentTemplates {
margin-right: 14px;
}
#Config_ReportPrefs_Builder_Buttonpane {
padding-right: .3em;
padding-right: 0.3em;
}
#Config_ReportPrefs_Builder_Buttonpane textarea {
float: left;
@@ -1348,7 +1452,7 @@ h1.Config_DocumentTemplates {
#Config_ReportPrefs_Builder_Buttonpane i {
float: right;
cursor: pointer;
margin: .3em .2em 0 0;
margin: 0.3em 0.2em 0 0;
color: #335A87;
}
#Config_ReportPrefs_Builder_Buttonpane i:hover {
@@ -1393,7 +1497,7 @@ h1.Config_DocumentTemplates {
background-color: #f4f4f4;
}
#Config_Location_List_Dialog #Config_Location_List_Dialog_List li:hover .remove {
opacity: .8;
opacity: 0.8;
}
#Config_Location_List_Dialog #Config_Location_List_Dialog_List li .remove {
margin-top: 2px;
@@ -1429,7 +1533,7 @@ h1.Config_DocumentTemplates {
font-family: Consolas, "Courier New", monospace;
}
#Config_JobQueues_Index i {
width: 1.2857142857142858em;
width: 1.28571429em;
text-align: center;
}
#Config_JobQueues_Icon {
@@ -1446,7 +1550,7 @@ h1.Config_DocumentTemplates {
#Config_JobQueues_Icon_Update_Dialog div.colours i {
cursor: pointer;
padding: 1px;
opacity: .9;
opacity: 0.9;
}
#Config_JobQueues_Icon_Update_Dialog div.colours i:hover {
opacity: 1;
@@ -1462,15 +1566,15 @@ h1.Config_DocumentTemplates {
margin: 6px 0 14px 0;
}
#Config_JobQueues_Icon_Update_Dialog div.icons i {
width: 1.2857142857142858em;
width: 1.28571429em;
text-align: center;
cursor: pointer;
padding: 4px 0px;
color: #333;
opacity: .6;
opacity: 0.6;
}
#Config_JobQueues_Icon_Update_Dialog div.icons i:hover {
opacity: .9;
opacity: 0.9;
color: inherit;
}
#Config_JobQueues_Icon_Update_Dialog div.icons i.selected {
@@ -1493,7 +1597,7 @@ h1.Config_DocumentTemplates {
margin: 4px 0 0 6px;
}
#Config_JobQueues_JobSubTypes_Update_Dialog .checkboxBulkSelectContainer {
font-size: .8em;
font-size: 0.8em;
}
#Config_JobQueues_Subjects li,
#Config_JobQueues_Subjects_Update_Dialog_List li {
@@ -1503,7 +1607,7 @@ h1.Config_DocumentTemplates {
#Config_JobQueues_Subjects_Update_Dialog_List li i.fa-user,
#Config_JobQueues_Subjects li i.fa-users,
#Config_JobQueues_Subjects_Update_Dialog_List li i.fa-users {
width: 1.2857142857142858em;
width: 1.28571429em;
text-align: center;
}
#Config_JobQueues_Subjects_Update_Dialog {
@@ -1531,7 +1635,7 @@ h1.Config_DocumentTemplates {
background-color: #f4f4f4;
}
#Config_JobQueues_Subjects_Update_Dialog #Config_JobQueues_Subjects_Update_Dialog_List li:hover .remove {
opacity: .8;
opacity: 0.8;
}
#Config_JobQueues_Subjects_Update_Dialog #Config_JobQueues_Subjects_Update_Dialog_List li .remove {
margin-top: 2px;
@@ -1553,7 +1657,7 @@ h1.Config_DocumentTemplates {
font-family: Consolas, "Courier New", monospace;
}
#Config_UserFlags_Index i {
width: 1.2857142857142858em;
width: 1.28571429em;
text-align: center;
}
#Config_UserFlags_Icon {
@@ -1570,7 +1674,7 @@ h1.Config_DocumentTemplates {
#Config_UserFlags_Icon_Update_Dialog div.colours i {
cursor: pointer;
padding: 1px;
opacity: .9;
opacity: 0.9;
}
#Config_UserFlags_Icon_Update_Dialog div.colours i:hover {
opacity: 1;
@@ -1586,15 +1690,15 @@ h1.Config_DocumentTemplates {
margin: 6px 0 14px 0;
}
#Config_UserFlags_Icon_Update_Dialog div.icons i {
width: 1.2857142857142858em;
width: 1.28571429em;
text-align: center;
cursor: pointer;
padding: 4px 0px;
color: #333;
opacity: .6;
opacity: 0.6;
}
#Config_UserFlags_Icon_Update_Dialog div.icons i:hover {
opacity: .9;
opacity: 0.9;
color: inherit;
}
#Config_UserFlags_Icon_Update_Dialog div.icons i.selected {
+121
View File
@@ -1146,6 +1146,127 @@ h1.Config_DocumentTemplates {
width: 570px;
height: 200px;
}
#DeviceBatch_Attachments {
border: 1px solid @SubtleBorderColour;
background-color: @white;
div.attachmentOutput {
position: relative;
height: 200px;
overflow: auto;
& > a {
display: block;
float: left;
height: 48px;
width: 221px;
padding: 2px;
margin: 2px;
font-size: 0.95em;
border: 1px solid @white;
color: @black;
text-decoration: none;
span.comments, span.author, span.timestamp {
display: block;
float: left;
width: 168px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 16px;
}
span.author {
color: #888;
width: 150px;
}
span.timestamp {
color: #888;
font-style: italic;
}
span.icon {
display: block;
float: left;
height: 48px;
width: 48px;
margin-right: 2px;
img {
height: 48px;
width: 48px;
&.loading {
display: none;
}
}
}
&:hover {
background-color: @SubtleColour;
border: 1px solid @SubtleBorderColour;
span.remove {
opacity: .5;
}
}
span.remove {
font-size: 1.2em;
color: @StatusRemove;
margin-left: 2px;
cursor: pointer;
opacity: 0;
&:hover {
opacity: 1;
}
}
}
}
&.cannotAddAttachments div.attachmentOutput {
height: 250px;
}
div.attachmentInput {
border-top: 1px solid @SubtleBorderColour;
height: 40px;
background-color: @white;
padding: 5px;
span.action {
color: @HeaderBackgroundColour;
display: block;
margin: 0 4px 0 0;
font-size: 1.5em;
cursor: pointer;
float: right;
border: 1px solid @white;
padding: .5em;
&:hover {
color: @HyperLinkColour;
background-color: @SubtleColour;
border: 1px solid @SubtleBorderColour;
}
&.disabled {
color: fade(@HeaderBackgroundColour, 20%);
cursor: default;
&:hover {
color: fade(@HeaderBackgroundColour, 20%);
background-color: inherit;
border: 1px solid @white;
}
}
}
}
}
}
// Plugins
#plugins {
+1 -1
View File
@@ -1 +1 @@
.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:#fbfbfb;}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:#f9f9f9;}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;margin:0;padding:0;}.tableDataVertical>tbody>tr>th.name{width:170px;text-align:right;}.tableDataVertical table.sub>tbody>tr:not(:first-child)>th,.tableDataVertical table.sub>tbody>tr:not(:first-child)>td{border-top:1px dashed #aaa;}.tableDataVertical table.sub>tbody>tr>th{font-weight:normal;text-align:right;}.tableDataVertical table.sub>tbody>tr>th.name{text-align:right;}.icon16{display:inline-block;height:16px;width:16px;margin-left:2px;cursor:pointer;}.subtleUntilHover{-moz-opacity:.3;opacity:.3;}.subtleUntilHover:hover{-moz-opacity:1;opacity:1;}#updateAvailableContainer{float:right;border:1px dashed #ddd;background-color:#fff;font-size:.6em;line-height:1em;padding:10px 10px 4px 70px;text-align:right;height:50px;}#updateAvailableContainer i{position:absolute;display:block;height:64px;width:64px;vertical-align:middle;margin-left:-70px;font-size:50px;color:#e51400;}#updateAvailableContainer a.button{font-size:12px;margin-top:8px;}.Config_HideAdvanced .Config_HideAdvanced_Item{display:none;}.Config_LinkedGroup_Instance{margin:4px 0 8px 4px;padding:4px 0 4px 6px;border-left:4px solid #ccc;background-color:#fff;}.Config_LinkedGroup_Instance div.code{margin-left:2px;}#Config_LinkedGroup_Dialog h3{margin-bottom:6px;}#Config_LinkedGroup_Dialog table.input{margin-top:12px;}#Config_LinkedGroup_Dialog table.input th{text-align:right;}#expressionEditor #expressionEditorExceptionContainer{display:none;border:1px dashed #ff9696;background-color:#ffd8d8;margin:10px 0;padding:10px;}#expressionEditor #expressionEditorContainer{border:1px solid #1e6dab;background-color:#f4f4f4;height:100px;}.expressionTree span.dynatree-node span.dynatree-icon{background-image:url(data:image/png;base64,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);background-position-y:0;}.expressionTree span.dynatree-node.object span.dynatree-icon{background-position-x:0;}.expressionTree span.dynatree-node.parameter span.dynatree-icon{background-position-x:-16px;}.expressionTree span.dynatree-node.function span.dynatree-icon{background-position-x:-32px;}.expressionTree span.dynatree-node.propertyLine truncated
.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;margin:0;padding:0;}.tableDataVertical>tbody>tr>th.name{width:170px;text-align:right;}.tableDataVertical table.sub>tbody>tr:not(:first-child)>th,.tableDataVertical table.sub>tbody>tr:not(:first-child)>td{border-top:1px dashed #aaa;}.tableDataVertical table.sub>tbody>tr>th{font-weight:normal;text-align:right;}.tableDataVertical table.sub>tbody>tr>th.name{text-align:right;}.icon16{display:inline-block;height:16px;width:16px;margin-left:2px;cursor:pointer;}.subtleUntilHover{-moz-opacity:.3;opacity:.3;}.subtleUntilHover:hover{-moz-opacity:1;opacity:1;}#updateAvailableContainer{float:right;border:1px dashed #ddd;background-color:#fff;font-size:.6em;line-height:1em;padding:10px 10px 4px 70px;text-align:right;height:50px;}#updateAvailableContainer i{position:absolute;display:block;height:64px;width:64px;vertical-align:middle;margin-left:-70px;font-size:50px;color:#e51400;}#updateAvailableContainer a.button{font-size:12px;margin-top:8px;}.Config_HideAdvanced .Config_HideAdvanced_Item{display:none;}.Config_LinkedGroup_Instance{margin:4px 0 8px 4px;padding:4px 0 4px 6px;border-left:4px solid #ccc;background-color:#fff;}.Config_LinkedGroup_Instance div.code{margin-left:2px;}#Config_LinkedGroup_Dialog h3{margin-bottom:6px;}#Config_LinkedGroup_Dialog table.input{margin-top:12px;}#Config_LinkedGroup_Dialog table.input th{text-align:right;}#expressionEditor #expressionEditorExceptionContainer{display:none;border:1px dashed #ff9696;background-color:#ffd8d8;margin:10px 0;padding:10px;}#expressionEditor #expressionEditorContainer{border:1px solid #1e6dab;background-color:#f4f4f4;height:100px;}.expressionTree span.dynatree-node span.dynatree-icon{background-image:url(data:image/png;base64,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);background-position-y:0;}.expressionTree span.dynatree-node.object span.dynatree-icon{background-position-x:0;}.expressionTree span.dynatree-node.parameter span.dynatree-icon{background-position-x:-16px;}.expressionTree span.dynatree-node.function span.dynatree-icon{background-position-x:-32px;}.expressionTree span.dynatrLine truncated
+48 -7
View File
@@ -23,6 +23,7 @@
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<UseGlobalApplicationHostFile />
<Use64BitIISExpress />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -1194,7 +1195,9 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="ClientBin\Disco.ClientBootstrapper.exe" />
<Content Include="ClientBin\Disco.ClientBootstrapper.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="Areas\Config\Views\AuthorizationRole\Create.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Create.generated.cs</LastGenOutput>
@@ -1283,7 +1286,9 @@
<Generator>RazorGenerator</Generator>
<LastGenOutput>Noticeboard.generated.cs</LastGenOutput>
</None>
<Content Include="ClientBin\DiscoServices.InitialPluginLibraryManifest.json" />
<Content Include="ClientBin\DiscoServices.InitialPluginLibraryManifest.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="bundleconfig.json" />
<None Include="ClientSource\Scripts\Core\disco.dataTables.extensions.js" />
<None Include="ClientSource\Scripts\Core\disco.moment.extensions.js" />
@@ -1306,19 +1311,23 @@
<None Include="ClientSource\Scripts\Core.js" />
<Content Include="ClientSource\Scripts\Core.min.js">
<DependentUpon>Core.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-AjaxHelperIcons.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-AjaxHelperIcons.min.js">
<DependentUpon>Disco-AjaxHelperIcons.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-AttachmentUploader.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-AttachmentUploader.min.js">
<DependentUpon>Disco-AttachmentUploader.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Scripts\Modules\Disco-AttachmentUploader\webcam.swf" />
<None Include="ClientSource\Scripts\Modules\Disco-CreateJob.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-CreateJob.min.js">
<DependentUpon>Disco-CreateJob.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-AttachmentUploader\disco-attachmentuploader.js" />
<None Include="ClientSource\Scripts\Modules\jQuery-Fancytree\jquery.fancytree-all.js" />
@@ -1355,68 +1364,87 @@
<None Include="ClientSource\Scripts\Modules\tinymce\skins\lightgray\img\loader.gif" />
<None Include="ClientSource\Scripts\Modules\tinymce\skins\lightgray\img\object.gif" />
<None Include="ClientSource\Scripts\Modules\tinymce\skins\lightgray\img\trans.gif" />
<None Include="ClientSource\Scripts\Modules\Disco-ExpressionEditor.js" />
<None Include="ClientSource\Scripts\Modules\Disco-DataTableHelpers.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-DataTableHelpers.min.js">
<DependentUpon>Disco-DataTableHelpers.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-ExpressionEditor.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-ExpressionEditor.min.js">
<DependentUpon>Disco-ExpressionEditor.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-jQueryExtensions.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-jQueryExtensions.min.js">
<DependentUpon>Disco-jQueryExtensions.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Disco-PropertyChangeHelpers.js" />
<Content Include="ClientSource\Scripts\Modules\Disco-PropertyChangeHelpers.min.js">
<DependentUpon>Disco-PropertyChangeHelpers.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Highcharts.js" />
<Content Include="ClientSource\Scripts\Modules\Highcharts.min.js">
<DependentUpon>Highcharts.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQuery-Fancytree.js" />
<Content Include="ClientSource\Scripts\Modules\jQuery-Fancytree.min.js">
<DependentUpon>jQuery-Fancytree.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQuery-Isotope.js" />
<Content Include="ClientSource\Scripts\Modules\jQuery-Isotope.min.js">
<DependentUpon>jQuery-Isotope.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQuery-NumberFormatter.js" />
<Content Include="ClientSource\Scripts\Modules\jQuery-NumberFormatter.min.js">
<DependentUpon>jQuery-NumberFormatter.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQuery-SignalR.js" />
<Content Include="ClientSource\Scripts\Modules\jQuery-SignalR.min.js">
<DependentUpon>jQuery-SignalR.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQueryUI-DynaTree.js" />
<Content Include="ClientSource\Scripts\Modules\jQueryUI-DynaTree.min.js">
<DependentUpon>jQueryUI-DynaTree.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\jQueryUI-TimePicker.js" />
<Content Include="ClientSource\Scripts\Modules\jQueryUI-TimePicker.min.js">
<DependentUpon>jQueryUI-TimePicker.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Knockout.js" />
<Content Include="ClientSource\Scripts\Modules\Knockout.min.js">
<DependentUpon>Knockout.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Shadowbox.js" />
<Content Include="ClientSource\Scripts\Modules\Shadowbox.min.js">
<DependentUpon>Shadowbox.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\Timeline.js" />
<Content Include="ClientSource\Scripts\Modules\Timeline.min.js">
<DependentUpon>Timeline.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Scripts\Modules\tinymce.js" />
<Content Include="ClientSource\Scripts\Modules\tinymce.min.js">
<DependentUpon>tinymce.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Shadowbox.min.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Timeline.min.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Shadowbox.min.css" />
<Content Include="ClientSource\Style\Timeline.min.css" />
<Content Include="ClientSource\Style\tinymce\content.inline.min.css">
<DependentUpon>content.inline.less</DependentUpon>
</Content>
@@ -1435,18 +1463,22 @@
</None>
<Content Include="ClientSource\Style\AppMaintenance.min.css">
<DependentUpon>AppMaintenance.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\BundleSite.min.css">
<DependentUpon>BundleSite.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Config.min.css">
<DependentUpon>Config.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\Credits.css">
<DependentUpon>Credits.less</DependentUpon>
</None>
<Content Include="ClientSource\Style\Credits.min.css">
<DependentUpon>Credits.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\Credits\CrystalIcons.png" />
<None Include="ClientSource\Style\Credits\dotless.png" />
@@ -1474,6 +1506,7 @@
</None>
<Content Include="ClientSource\Style\Declarations.min.css">
<DependentUpon>Declarations.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\Dialog.css">
<DependentUpon>Dialog.less</DependentUpon>
@@ -1483,9 +1516,11 @@
</None>
<Content Include="ClientSource\Style\Device.min.css">
<DependentUpon>Device.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Dialog.min.css">
<DependentUpon>Dialog.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\ExpressionEditor.css" />
<Content Include="ClientSource\Style\ExpressionEditor.htm" />
@@ -1555,12 +1590,14 @@
<None Include="ClientSource\Style\IsotopeStyles.css" />
<Content Include="ClientSource\Style\IsotopeStyles.min.css">
<DependentUpon>IsotopeStyles.css</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\Job.css">
<DependentUpon>Job.less</DependentUpon>
</None>
<Content Include="ClientSource\Style\Job.min.css">
<DependentUpon>Job.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\jQueryUI\dynatree\icons.gif" />
<None Include="ClientSource\Style\jQueryUI\dynatree\loading.gif" />
@@ -1693,6 +1730,7 @@
</None>
<Content Include="ClientSource\Style\User.min.css">
<DependentUpon>User.less</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\FontAwesome\font-awesome.less" />
<Content Include="favicon.ico" />
@@ -1720,7 +1758,7 @@
<Generator>RazorGenerator</Generator>
<LastGenOutput>CommonHelpers.generated.cs</LastGenOutput>
</None>
<None Include="Properties\PublishProfiles\HADES3.pubxml" />
<None Include="Properties\PublishProfiles\SRV-WEB03 Production.pubxml" />
<None Include="ClientSource\Scripts\Modules\Highcharts\highcharts.src.js" />
<None Include="ClientSource\Scripts\Core\jquery-2.1.1.js" />
<None Include="ClientSource\Scripts\Modules\tinymce\jquery.tinymce.min.js" />
@@ -1952,7 +1990,9 @@
<Generator>RazorGenerator</Generator>
<LastGenOutput>Query.generated.cs</LastGenOutput>
</None>
<Content Include="ClientBin\PreparationClient.zip" />
<Content Include="ClientBin\PreparationClient.zip">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ClientSource\Style\Config.less" />
<None Include="ClientSource\Style\Credits.less" />
<None Include="ClientSource\Style\Declarations.less" />
@@ -2314,6 +2354,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<UserProperties BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
@@ -171,6 +171,42 @@ namespace Disco.Web.Areas.API.Controllers
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Index);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult AttachmentDownload()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentDownload);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult AttachmentThumbnail()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentThumbnail);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult AttachmentUpload()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentUpload);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Attachment()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Attachment);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Attachments()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Attachments);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult AttachmentRemove()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentRemove);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public DeviceBatchController Actions { get { return MVC.API.DeviceBatch; } }
@@ -207,6 +243,12 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string Delete = "Delete";
public readonly string Index = "Index";
public readonly string Timeline = "Timeline";
public readonly string AttachmentDownload = "AttachmentDownload";
public readonly string AttachmentThumbnail = "AttachmentThumbnail";
public readonly string AttachmentUpload = "AttachmentUpload";
public readonly string Attachment = "Attachment";
public readonly string Attachments = "Attachments";
public readonly string AttachmentRemove = "AttachmentRemove";
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -232,6 +274,12 @@ namespace Disco.Web.Areas.API.Controllers
public const string Delete = "Delete";
public const string Index = "Index";
public const string Timeline = "Timeline";
public const string AttachmentDownload = "AttachmentDownload";
public const string AttachmentThumbnail = "AttachmentThumbnail";
public const string AttachmentUpload = "AttachmentUpload";
public const string Attachment = "Attachment";
public const string Attachments = "Attachments";
public const string AttachmentRemove = "AttachmentRemove";
}
@@ -423,6 +471,55 @@ namespace Disco.Web.Areas.API.Controllers
{
public readonly string id = "id";
}
static readonly ActionParamsClass_AttachmentDownload s_params_AttachmentDownload = new ActionParamsClass_AttachmentDownload();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_AttachmentDownload AttachmentDownloadParams { get { return s_params_AttachmentDownload; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_AttachmentDownload
{
public readonly string id = "id";
}
static readonly ActionParamsClass_AttachmentThumbnail s_params_AttachmentThumbnail = new ActionParamsClass_AttachmentThumbnail();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_AttachmentThumbnail AttachmentThumbnailParams { get { return s_params_AttachmentThumbnail; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_AttachmentThumbnail
{
public readonly string id = "id";
}
static readonly ActionParamsClass_AttachmentUpload s_params_AttachmentUpload = new ActionParamsClass_AttachmentUpload();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_AttachmentUpload AttachmentUploadParams { get { return s_params_AttachmentUpload; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_AttachmentUpload
{
public readonly string id = "id";
public readonly string Comments = "Comments";
}
static readonly ActionParamsClass_Attachment s_params_Attachment = new ActionParamsClass_Attachment();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Attachment AttachmentParams { get { return s_params_Attachment; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Attachment
{
public readonly string id = "id";
}
static readonly ActionParamsClass_Attachments s_params_Attachments = new ActionParamsClass_Attachments();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Attachments AttachmentsParams { get { return s_params_Attachments; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Attachments
{
public readonly string id = "id";
}
static readonly ActionParamsClass_AttachmentRemove s_params_AttachmentRemove = new ActionParamsClass_AttachmentRemove();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_AttachmentRemove AttachmentRemoveParams { get { return s_params_AttachmentRemove; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_AttachmentRemove
{
public readonly string id = "id";
}
static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } }
@@ -717,6 +814,79 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo;
}
[NonAction]
partial void AttachmentDownloadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
[NonAction]
public override System.Web.Mvc.ActionResult AttachmentDownload(int id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentDownload);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
AttachmentDownloadOverride(callInfo, id);
return callInfo;
}
[NonAction]
partial void AttachmentThumbnailOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
[NonAction]
public override System.Web.Mvc.ActionResult AttachmentThumbnail(int id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentThumbnail);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
AttachmentThumbnailOverride(callInfo, id);
return callInfo;
}
[NonAction]
partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, string Comments);
[NonAction]
public override System.Web.Mvc.ActionResult AttachmentUpload(int id, string Comments)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentUpload);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Comments", Comments);
AttachmentUploadOverride(callInfo, id, Comments);
return callInfo;
}
[NonAction]
partial void AttachmentOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
[NonAction]
public override System.Web.Mvc.ActionResult Attachment(int id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Attachment);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
AttachmentOverride(callInfo, id);
return callInfo;
}
[NonAction]
partial void AttachmentsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
[NonAction]
public override System.Web.Mvc.ActionResult Attachments(int id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Attachments);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
AttachmentsOverride(callInfo, id);
return callInfo;
}
[NonAction]
partial void AttachmentRemoveOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
[NonAction]
public override System.Web.Mvc.ActionResult AttachmentRemove(int id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentRemove);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
AttachmentRemoveOverride(callInfo, id);
return callInfo;
}
}
}
+30 -43
View File
@@ -1,107 +1,94 @@
[
[
{
"outputFile": "ClientSource/Style/Fancytree/disco.fancytree.css",
"inputFile": "ClientSource/Style/Fancytree/disco.fancytree.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Fancytree/disco.fancytree.less"
},
{
"outputFile": "ClientSource/Style/jQueryUI/jquery-ui.css",
"inputFile": "ClientSource/Style/jQueryUI/jquery-ui.less",
"sourceMap": false
"inputFile": "ClientSource/Style/jQueryUI/jquery-ui.less"
},
{
"outputFile": "ClientSource/Style/Public/HeldDevices.css",
"inputFile": "ClientSource/Style/Public/HeldDevices.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Public/HeldDevices.less"
},
{
"outputFile": "ClientSource/Style/Public/HeldDevicesNoticeboard.css",
"inputFile": "ClientSource/Style/Public/HeldDevicesNoticeboard.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Public/HeldDevicesNoticeboard.less"
},
{
"outputFile": "ClientSource/Style/Timeline/disco.timelineextensions.css",
"inputFile": "ClientSource/Style/Timeline/disco.timelineextensions.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Timeline/disco.timelineextensions.less"
},
{
"outputFile": "ClientSource/Style/tinymce/skin.css",
"inputFile": "ClientSource/Style/tinymce/skin.less",
"sourceMap": false
"inputFile": "ClientSource/Style/tinymce/skin.less"
},
{
"outputFile": "ClientSource/Style/tinymce/content.css",
"inputFile": "ClientSource/Style/tinymce/content.less",
"sourceMap": false
"inputFile": "ClientSource/Style/tinymce/content.less"
},
{
"outputFile": "ClientSource/Style/tinymce/content.inline.css",
"inputFile": "ClientSource/Style/tinymce/content.inline.less",
"sourceMap": false
"inputFile": "ClientSource/Style/tinymce/content.inline.less"
},
{
"outputFile": "ClientSource/Style/AppMaintenance.css",
"inputFile": "ClientSource/Style/AppMaintenance.less",
"sourceMap": false
"inputFile": "ClientSource/Style/AppMaintenance.less"
},
{
"outputFile": "ClientSource/Style/BundleSite.css",
"inputFile": "ClientSource/Style/BundleSite.less",
"sourceMap": false
"inputFile": "ClientSource/Style/BundleSite.less"
},
{
"outputFile": "ClientSource/Style/Config.css",
"inputFile": "ClientSource/Style/Config.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Config.less"
},
{
"outputFile": "ClientSource/Style/Credits.css",
"inputFile": "ClientSource/Style/Credits.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Credits.less"
},
{
"outputFile": "ClientSource/Style/Declarations.css",
"inputFile": "ClientSource/Style/Declarations.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Declarations.less"
},
{
"outputFile": "ClientSource/Style/Device.css",
"inputFile": "ClientSource/Style/Device.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Device.less"
},
{
"outputFile": "ClientSource/Style/Dialog.css",
"inputFile": "ClientSource/Style/Dialog.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Dialog.less"
},
{
"outputFile": "ClientSource/Style/Job.css",
"inputFile": "ClientSource/Style/Job.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Job.less"
},
{
"outputFile": "ClientSource/Style/jQueryUIExtensions.css",
"inputFile": "ClientSource/Style/jQueryUIExtensions.less",
"sourceMap": false
"inputFile": "ClientSource/Style/jQueryUIExtensions.less"
},
{
"outputFile": "ClientSource/Style/normalize.css",
"inputFile": "ClientSource/Style/normalize.less",
"sourceMap": false
"inputFile": "ClientSource/Style/normalize.less"
},
{
"outputFile": "ClientSource/Style/Shared.css",
"inputFile": "ClientSource/Style/Shared.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Shared.less"
},
{
"outputFile": "ClientSource/Style/Site.css",
"inputFile": "ClientSource/Style/Site.less",
"sourceMap": false
"inputFile": "ClientSource/Style/Site.less"
},
{
"outputFile": "ClientSource/Style/User.css",
"inputFile": "ClientSource/Style/User.less",
"sourceMap": false
"inputFile": "ClientSource/Style/User.less"
},
{
"outputFile": "ClientSource/Scripts/Modules/jQuery-SignalR/disco-hubs.es5.js",
"inputFile": "ClientSource/Scripts/Modules/jQuery-SignalR/disco-hubs.js"
},
{
"outputFile": "ClientSource/Scripts/Modules/jQuery-SignalR.es5.js",
"inputFile": "ClientSource/Scripts/Modules/jQuery-SignalR.js"
}
]
+11 -4
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.30711.63
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Disco.ClientBootstrapper", "Disco.ClientBootstrapper\Disco.ClientBootstrapper.csproj", "{15BD9561-A3C7-4608-9F7E-F1A1CFB60055}"
EndProject
@@ -133,8 +133,15 @@ Global
SolutionGuid = {1CCC4DCB-653B-464B-B05D-285032B28DC4}
EndGlobalSection
GlobalSection(AutomaticVersions) = postSolution
UpdateAssemblyVersion = False
UpdateAssemblyFileVersion = False
UpdateAssemblyVersion = True
UpdateAssemblyFileVersion = True
UpdateAssemblyInfoVersion = False
ShouldCreateLogs = True
AdvancedSettingsExpanded = True
AssemblyVersionSettings = None.None.DateStamp.TimeStamp
AssemblyFileVersionSettings = None.None.DateStamp.TimeStamp
UpdatePackageVersion = False
AssemblyInfoVersionType = SettingsVersion
InheritWinAppVersionFrom = None
EndGlobalSection
EndGlobal