diff --git a/Disco.Client/Properties/AssemblyInfo.cs b/Disco.Client/Properties/AssemblyInfo.cs
index 82542bec..90152eec 100644
--- a/Disco.Client/Properties/AssemblyInfo.cs
+++ b/Disco.Client/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1950")]
-[assembly: AssemblyFileVersion("1.2.0225.1950")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.ClientBootstrapper/Properties/AssemblyInfo.cs b/Disco.ClientBootstrapper/Properties/AssemblyInfo.cs
index 82c1d757..b2eccb5c 100644
--- a/Disco.ClientBootstrapper/Properties/AssemblyInfo.cs
+++ b/Disco.ClientBootstrapper/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1950")]
-[assembly: AssemblyFileVersion("1.2.0225.1950")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.Data/Properties/AssemblyInfo.cs b/Disco.Data/Properties/AssemblyInfo.cs
index 3492143e..9e7f7ae3 100644
--- a/Disco.Data/Properties/AssemblyInfo.cs
+++ b/Disco.Data/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1951")]
-[assembly: AssemblyFileVersion("1.2.0225.1951")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.Models/Properties/AssemblyInfo.cs b/Disco.Models/Properties/AssemblyInfo.cs
index 0f82186d..f544827d 100644
--- a/Disco.Models/Properties/AssemblyInfo.cs
+++ b/Disco.Models/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1951")]
-[assembly: AssemblyFileVersion("1.2.0225.1951")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.Services/Plugins/Features/UIExtension/UIExtensionFeature.cs b/Disco.Services/Plugins/Features/UIExtension/UIExtensionFeature.cs
index 753902f3..5ed1361d 100644
--- a/Disco.Services/Plugins/Features/UIExtension/UIExtensionFeature.cs
+++ b/Disco.Services/Plugins/Features/UIExtension/UIExtensionFeature.cs
@@ -24,6 +24,10 @@ namespace Disco.Services.Plugins.Features.UIExtension
{
return new LiteralResult(this.Manifest, null);
}
+ protected LiteralResult ScriptInline(string JavaScriptContent)
+ {
+ return new LiteralResult(this.Manifest, string.Concat(""));
+ }
protected PluginResourceScriptResult ScriptResource(string Resource, bool PlaceInPageHead)
{
return new PluginResourceScriptResult(this.Manifest, Resource, PlaceInPageHead);
diff --git a/Disco.Services/Plugins/PluginFeatureAttribute.cs b/Disco.Services/Plugins/PluginFeatureAttribute.cs
index 15947e5c..77b90994 100644
--- a/Disco.Services/Plugins/PluginFeatureAttribute.cs
+++ b/Disco.Services/Plugins/PluginFeatureAttribute.cs
@@ -11,5 +11,6 @@ namespace Disco.Services.Plugins
{
public string Id { get; set; }
public string Name { get; set; }
+ public bool PrimaryFeature { get; set; }
}
}
diff --git a/Disco.Services/Plugins/PluginFeatureManifest.cs b/Disco.Services/Plugins/PluginFeatureManifest.cs
index d17bb102..c9f47b25 100644
--- a/Disco.Services/Plugins/PluginFeatureManifest.cs
+++ b/Disco.Services/Plugins/PluginFeatureManifest.cs
@@ -14,7 +14,8 @@ namespace Disco.Services.Plugins
public string Id { get; set; }
public string Name { get; set; }
public string TypeName { get; set; }
-
+ public bool PrimaryFeature { get; set; }
+
[JsonProperty]
private string CategoryTypeName { get; set; }
@@ -77,6 +78,7 @@ namespace Disco.Services.Plugins
var featureId = featureAttribute.Id;
var featureName = featureAttribute.Name;
+ var featurePrimary = featureAttribute.PrimaryFeature;
// Determine Feature Category
var featureCategoryType = featureType.BaseType;
@@ -84,6 +86,10 @@ namespace Disco.Services.Plugins
if (featureCategoryType == null)
throw new ArgumentException(string.Format("Plugin Feature found [{0}], but has no Base Type to determine its Category", featureType.Name), "featureType");
+ // Handle Generic-Type Features (Only use base-feature, not generic parameters)
+ if (featureCategoryType.IsGenericType)
+ featureCategoryType = featureCategoryType.GetGenericTypeDefinition();
+
if (featureCategoryType == typeof(PluginFeature) || !typeof(PluginFeature).IsAssignableFrom(featureCategoryType))
throw new ArgumentException(string.Format("Plugin Feature found [{0}], but its Base Type is not a valid Feature Category Type (Base Feature or not assignable)", featureType.Name), "featureType");
@@ -97,6 +103,7 @@ namespace Disco.Services.Plugins
PluginManifest = pluginManifest,
Id = featureId,
Name = featureName,
+ PrimaryFeature = featurePrimary,
Type = featureType,
TypeName = featureType.FullName,
CategoryType = featureCategoryType,
diff --git a/Disco.Services/Plugins/PluginManifest.cs b/Disco.Services/Plugins/PluginManifest.cs
index 42397859..29a7f573 100644
--- a/Disco.Services/Plugins/PluginManifest.cs
+++ b/Disco.Services/Plugins/PluginManifest.cs
@@ -414,5 +414,31 @@ namespace Disco.Services.Plugins
return new Tuple(resourcePath, resourceHash.Item1);
}
+
+ public void LogException(Exception PluginException)
+ {
+ PluginsLog.LogPluginException(this.ToString(), PluginException);
+ }
+ public void LogWarning(string Message)
+ {
+ LogWarning(Message, null);
+ }
+ public void LogWarning(string MessageFormat, params object[] Args)
+ {
+ PluginsLog.LogPluginWarning(this, string.Format(MessageFormat, Args), Args);
+ }
+ public void LogMessage(string Message)
+ {
+ LogMessage(Message, null);
+ }
+ public void LogMessage(string MessageFormat, params object[] Args)
+ {
+ PluginsLog.LogPluginMessage(this, string.Format(MessageFormat, Args), Args);
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0} [{1} v{2}]", this.Name, this.Id, this.VersionFormatted);
+ }
}
}
diff --git a/Disco.Services/Plugins/PluginsLog.cs b/Disco.Services/Plugins/PluginsLog.cs
index 43e4deeb..bda9f2f4 100644
--- a/Disco.Services/Plugins/PluginsLog.cs
+++ b/Disco.Services/Plugins/PluginsLog.cs
@@ -28,6 +28,8 @@ namespace Disco.Services.Plugins
InitializeExceptionWithInner,
PluginException = 20,
PluginExceptionWithInner,
+ PluginWarning = 30,
+ PluginMessage = 40,
PluginReferenceAssemblyLoaded = 50,
PluginConfigurationLoaded = 100,
PluginConfigurationSaved = 104,
@@ -142,6 +144,39 @@ namespace Disco.Services.Plugins
Log(EventTypeIds.PluginException, Component, ex.GetType().Name, ex.Message, ex.StackTrace);
}
}
+ public static void LogPluginWarning(PluginManifest Manifest, string Message, params object[] ExportData)
+ {
+ LogPluginWarningOrMessage(EventTypeIds.PluginWarning, Manifest, Message, ExportData);
+ }
+ public static void LogPluginMessage(PluginManifest Manifest, string Message, params object[] ExportData)
+ {
+ LogPluginWarningOrMessage(EventTypeIds.PluginMessage, Manifest, Message, ExportData);
+ }
+ private static void LogPluginWarningOrMessage(EventTypeIds WarningOrMessage, PluginManifest Manifest, string Message, object[] ExportData)
+ {
+ if (WarningOrMessage != EventTypeIds.PluginMessage && WarningOrMessage != EventTypeIds.PluginWarning)
+ throw new ArgumentException("Only PluginMessage/PluginWarning is allowed", "WarningOrMessage");
+
+ object[] LogData;
+
+ if (ExportData == null || ExportData.Length == 0)
+ {
+ LogData = new object[3];
+ }
+ else
+ {
+ LogData = new object[4 + ExportData.Length];
+ for (int i = 0; i < ExportData.Length; i++)
+ LogData[4 + i] = ExportData[i];
+ }
+
+ LogData[0] = Manifest.Name;
+ LogData[1] = Manifest.Id;
+ LogData[2] = Manifest.VersionFormatted;
+ LogData[3] = Message;
+
+ Log(WarningOrMessage, LogData);
+ }
protected override List LoadEventTypes()
{
@@ -257,6 +292,28 @@ namespace Disco.Services.Plugins
UsePersist = true,
UseDisplay = true
},
+ new LogEventType
+ {
+ Id = (int)EventTypeIds.PluginWarning,
+ ModuleId = _ModuleId,
+ Name = "Plugin Warning",
+ Format = "{0} [{1} v{2}]: {3}",
+ Severity = (int)LogEventType.Severities.Warning,
+ UseLive = true,
+ UsePersist = true,
+ UseDisplay = true
+ },
+ new LogEventType
+ {
+ Id = (int)EventTypeIds.PluginMessage,
+ ModuleId = _ModuleId,
+ Name = "Plugin Message",
+ Format = "{0} [{1} v{2}]: {3}",
+ Severity = (int)LogEventType.Severities.Information,
+ UseLive = true,
+ UsePersist = true,
+ UseDisplay = true
+ },
new LogEventType
{
Id = (int)EventTypeIds.PluginReferenceAssemblyLoaded,
diff --git a/Disco.Services/Properties/AssemblyInfo.cs b/Disco.Services/Properties/AssemblyInfo.cs
index 2f41c342..d839056b 100644
--- a/Disco.Services/Properties/AssemblyInfo.cs
+++ b/Disco.Services/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1951")]
-[assembly: AssemblyFileVersion("1.2.0225.1951")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.Web.Extensions/Properties/AssemblyInfo.cs b/Disco.Web.Extensions/Properties/AssemblyInfo.cs
index 5f2c14a3..ebaff29d 100644
--- a/Disco.Web.Extensions/Properties/AssemblyInfo.cs
+++ b/Disco.Web.Extensions/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0225.1951")]
-[assembly: AssemblyFileVersion("1.2.0225.1951")]
+[assembly: AssemblyVersion("1.2.0304.2046")]
+[assembly: AssemblyFileVersion("1.2.0304.2046")]
diff --git a/Disco.Web/Areas/Config/Models/Plugins/IndexViewModel.cs b/Disco.Web/Areas/Config/Models/Plugins/IndexViewModel.cs
index e663ff33..7f726652 100644
--- a/Disco.Web/Areas/Config/Models/Plugins/IndexViewModel.cs
+++ b/Disco.Web/Areas/Config/Models/Plugins/IndexViewModel.cs
@@ -34,41 +34,36 @@ namespace Disco.Web.Areas.Config.Models.Plugins
}
}
- public List>> PluginManifestsByType
+ public List>> PluginManifestsByCategory
{
get
{
if (PluginManifests.Count == 0)
- return new List>>();
+ return null;
- var categorisedManifests = PluginManifests.SelectMany(pm => pm.Features)
- .GroupBy(fm => fm.CategoryType)
- .Select(g => new Tuple>(g.Key, g.Select(fm => fm.PluginManifest).Distinct().OrderBy(fm => fm.Name).ToList())).ToList();
-
- // Ensure all plugins are represented
- var allCategorisedManifests = categorisedManifests.SelectMany(g => g.Item2).ToList();
- var unrepresentedPlugins = PluginManifests.Where(m => !allCategorisedManifests.Contains(m)).ToList();
- if (unrepresentedPlugins.Count > 0)
+ List> pluginsByCategory = new List>();
+
+ foreach (var pluginManifest in PluginManifests)
{
- Tuple> otherCategory = null;
- foreach (var category in categorisedManifests)
- {
- if (category.Item1 == typeof(OtherFeature))
- {
- otherCategory = category;
- }
- }
- if (otherCategory == null)
- {
- otherCategory = new Tuple>(typeof(OtherFeature), new List());
- categorisedManifests.Add(otherCategory);
- }
- foreach (var pluginManifest in unrepresentedPlugins)
- otherCategory.Item2.Add(pluginManifest);
+ var orderedFeatures = pluginManifest.Features.OrderBy(pf => pf.Id);
+ var primaryFeature = orderedFeatures.Where(pf => pf.PrimaryFeature).FirstOrDefault();
+ Type categoryType;
+
+ if (primaryFeature == null)
+ primaryFeature = orderedFeatures.FirstOrDefault();
+
+ if (primaryFeature == null)
+ categoryType = typeof(OtherFeature);
+ else
+ categoryType = primaryFeature.CategoryType;
+
+ pluginsByCategory.Add(new Tuple(categoryType, pluginManifest));
}
- return categorisedManifests;
+ return pluginsByCategory.GroupBy(p => p.Item1)
+ .OrderBy(g => g.Key.Name)
+ .Select(g => new Tuple>(g.Key, g.Select(pg => pg.Item2).OrderBy(p => p.Name).ToList())).ToList();
}
}
}
diff --git a/Disco.Web/Areas/Config/Views/Plugins/Index.cshtml b/Disco.Web/Areas/Config/Views/Plugins/Index.cshtml
index b69205ed..64087680 100644
--- a/Disco.Web/Areas/Config/Views/Plugins/Index.cshtml
+++ b/Disco.Web/Areas/Config/Views/Plugins/Index.cshtml
@@ -13,7 +13,7 @@
}
else
{
- var pluginGroups = Model.PluginManifestsByType;
+ var pluginGroups = Model.PluginManifestsByCategory;
int itemsPerColumn = pluginGroups.Count / 3;
@@ -38,7 +38,7 @@
@pluginDefinition.Name
}
diff --git a/Disco.Web/Areas/Config/Views/Plugins/Index.generated.cs b/Disco.Web/Areas/Config/Views/Plugins/Index.generated.cs
index 8540dbd4..581048f7 100644
--- a/Disco.Web/Areas/Config/Views/Plugins/Index.generated.cs
+++ b/Disco.Web/Areas/Config/Views/Plugins/Index.generated.cs
@@ -37,9 +37,9 @@ namespace Disco.Web.Areas.Config.Views.Plugins
using Disco.Web;
using Disco.Web.Extensions;
- [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.0.0")]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.4.0")]
[System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/Plugins/Index.cshtml")]
- public class Index : System.Web.Mvc.WebViewPage
+ public partial class Index : System.Web.Mvc.WebViewPage
{
public Index()
{
@@ -88,7 +88,7 @@ WriteLiteral(">\r\n No Plugins are Installed
\r\n \r\n");
#line hidden
WriteLiteral(" (Url.Action(MVC.Config.Plugins.Configure(pluginDefinition.Id))
+, Tuple.Create(Tuple.Create("", 1446), Tuple.Create(Url.Action(MVC.Config.Plugins.Configure(pluginDefinition.Id))
#line default
#line hidden
-, 1442), false)
+, 1446), false)
);
WriteLiteral(">\r\n