Update: Plugin Framework Install & UI

This commit is contained in:
Gary Sharp committed 2013-02-12 17:27:54 +11:00
1 parent b24253fd64
commit 734b02fa1d
35 files changed
+1356 -452

No files matched your search

+2
View File
@@ -149,6 +149,8 @@
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUpdateLastNetworkLogonDateJob.cs" /> <Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUpdateLastNetworkLogonDateJob.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUserAccountExtensions.cs" /> <Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUserAccountExtensions.cs" />
<Compile Include="BI\Expressions\ExpressionCache.cs" /> <Compile Include="BI\Expressions\ExpressionCache.cs" />
<Compile Include="BI\Interop\Community\CommunityHelpers.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryUpdateTask.cs" />
<Compile Include="BI\Interop\Community\UpdateCheck.cs" /> <Compile Include="BI\Interop\Community\UpdateCheck.cs" />
<Compile Include="BI\Interop\Community\UpdateCheckTask.cs" /> <Compile Include="BI\Interop\Community\UpdateCheckTask.cs" />
<Compile Include="BI\Interop\MimeTypes.cs" /> <Compile Include="BI\Interop\MimeTypes.cs" />
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0208.1156")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0208.1156")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
Binary file not shown.
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
+6
View File
@@ -48,6 +48,12 @@
<Compile Include="BI\Config\OrganisationAddress.cs" /> <Compile Include="BI\Config\OrganisationAddress.cs" />
<Compile Include="BI\DocumentTemplate\DocumentState.cs" /> <Compile Include="BI\DocumentTemplate\DocumentState.cs" />
<Compile Include="BI\Expressions\IImageExpressionResult.cs" /> <Compile Include="BI\Expressions\IImageExpressionResult.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryCompatibilityItem.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryCompatibilityResponse.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryCompatibilityRequest.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryItem.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryUpdateRequest.cs" />
<Compile Include="BI\Interop\Community\PluginLibraryUpdateResponse.cs" />
<Compile Include="BI\Interop\Community\UpdateRequestBase.cs" /> <Compile Include="BI\Interop\Community\UpdateRequestBase.cs" />
<Compile Include="BI\Interop\Community\UpdateRequestV1.cs" /> <Compile Include="BI\Interop\Community\UpdateRequestV1.cs" />
<Compile Include="BI\Interop\Community\UpdateResponse.cs" /> <Compile Include="BI\Interop\Community\UpdateResponse.cs" />
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
+1 -18
View File
@@ -101,23 +101,6 @@
<Compile Include="Logging\Targets\LogLiveContext.cs" /> <Compile Include="Logging\Targets\LogLiveContext.cs" />
<Compile Include="Logging\Targets\LogPersistContext.cs" /> <Compile Include="Logging\Targets\LogPersistContext.cs" />
<Compile Include="Logging\Utilities.cs" /> <Compile Include="Logging\Utilities.cs" />
<None Include="_Plugins\Categories\CertificateProvider\CertificateProviderPlugin.cs" />
<None Include="_Plugins\Categories\CertificateProvider\CertificateProviderLog.cs" />
<None Include="_Plugins\Categories\InteroperabilityProvider\InteroperabilityProviderPlugin.cs" />
<None Include="_Plugins\Categories\WarrantyProvider\WarrantyProviderPlugin.cs" />
<None Include="_Plugins\Categories\WarrantyProvider\WarrantyProviderSubmitJobException.cs" />
<None Include="_Plugins\PluginCategoryAttribute.cs" />
<None Include="_Plugins\PluginDefinition.cs" />
<None Include="_Plugins\Plugins.cs" />
<None Include="_Plugins\Plugin.cs" />
<None Include="_Plugins\IPluginConfiguration.cs" />
<None Include="_Plugins\IPluginWebController.cs" />
<None Include="_Plugins\InvalidCategoryTypeException.cs" />
<None Include="_Plugins\PluginExtensions.cs" />
<None Include="_Plugins\PluginsLog.cs" />
<None Include="_Plugins\PluginWebControllerException.cs" />
<None Include="_Plugins\PluginWebControllerExtensions.cs" />
<None Include="_Plugins\UnknownPluginException.cs" />
<Compile Include="Plugins\InstallPluginTask.cs" /> <Compile Include="Plugins\InstallPluginTask.cs" />
<Compile Include="Plugins\PluginAttribute.cs" /> <Compile Include="Plugins\PluginAttribute.cs" />
<Compile Include="Plugins\PluginExtensions.cs" /> <Compile Include="Plugins\PluginExtensions.cs" />
@@ -168,7 +151,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>
<UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" BuildVersion_BuildAction="ReBuild" BuildVersion_StartDate="2001/1/1" /> <UserProperties BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="True" />
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
<PropertyGroup> <PropertyGroup>
+39 -2
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Disco.Data.Repository; using Disco.Data.Repository;
@@ -17,12 +18,38 @@ namespace Disco.Services.Plugins
protected override void ExecuteTask() protected override void ExecuteTask()
{ {
string packageUrlPath = (string)this.ExecutionContext.JobDetail.JobDataMap["PackageUrl"];
string packageFilePath = (string)this.ExecutionContext.JobDetail.JobDataMap["PackageFilePath"]; string packageFilePath = (string)this.ExecutionContext.JobDetail.JobDataMap["PackageFilePath"];
bool DeletePackageAfterInstall = (bool)this.ExecutionContext.JobDetail.JobDataMap["DeletePackageAfterInstall"]; bool DeletePackageAfterInstall = (bool)this.ExecutionContext.JobDetail.JobDataMap["DeletePackageAfterInstall"];
if (!Plugins.PluginsLoaded) if (!Plugins.PluginsLoaded)
throw new InvalidOperationException("Plugins have not been initialized"); throw new InvalidOperationException("Plugins have not been initialized");
if (!string.IsNullOrEmpty(packageUrlPath))
{
this.Status.UpdateStatus(0, "Downloading Plugin Package", "Connecting...");
if (File.Exists(packageFilePath))
File.Delete(packageFilePath);
if (!Directory.Exists(Path.GetDirectoryName(packageFilePath)))
Directory.CreateDirectory(Path.GetDirectoryName(packageFilePath));
// Need to Download the Package
WebClient downloader = new WebClient();
DateTime progressExpires = DateTime.Now;
downloader.DownloadProgressChanged += (sender, e) =>
{
Console.WriteLine(e.ProgressPercentage);
if (progressExpires <= DateTime.Now)
{
this.Status.UpdateStatus(e.ProgressPercentage, string.Format("{0} of {1} KB downloaded", e.BytesReceived / 1024, e.TotalBytesToReceive / 1024));
progressExpires = DateTime.Now.AddMilliseconds(250);
}
};
downloader.DownloadFileTaskAsync(new Uri(packageUrlPath), packageFilePath).Wait();
}
this.Status.UpdateStatus(10, "Opening Plugin Package", Path.GetFileName(packageFilePath)); this.Status.UpdateStatus(10, "Opening Plugin Package", Path.GetFileName(packageFilePath));
using (var packageStream = File.OpenRead(packageFilePath)) using (var packageStream = File.OpenRead(packageFilePath))
@@ -58,6 +85,12 @@ namespace Disco.Services.Plugins
{ {
string packagePath = Path.Combine(dbContext.DiscoConfiguration.PluginsLocation, packageManifest.Id); string packagePath = Path.Combine(dbContext.DiscoConfiguration.PluginsLocation, packageManifest.Id);
// Check for Compatibility
var compatibilityData = Plugins.LoadCompatibilityData(dbContext);
var pluginCompatibility = compatibilityData.Plugins.FirstOrDefault(i => i.Id.Equals(packageManifest.Id, StringComparison.InvariantCultureIgnoreCase) && packageManifest.Version == Version.Parse(i.Version));
if (pluginCompatibility != null && !pluginCompatibility.Compatible)
throw new InvalidOperationException(string.Format("The plugin [{0} v{1}] is not compatible: {2}", packageManifest.Id, packageManifest.VersionFormatted, pluginCompatibility.Reason));
// Force Delete of Existing Folder // Force Delete of Existing Folder
if (Directory.Exists(packagePath)) if (Directory.Exists(packagePath))
{ {
@@ -117,12 +150,16 @@ namespace Disco.Services.Plugins
File.Delete(packageFilePath); File.Delete(packageFilePath);
} }
public static ScheduledTaskStatus InstallPlugin(string PackageFilePath, bool DeletePackageAfterInstall) public static ScheduledTaskStatus InstallLocalPlugin(string PackageFilePath, bool DeletePackageAfterInstall)
{
return InstallPlugin(null, PackageFilePath, DeletePackageAfterInstall);
}
public static ScheduledTaskStatus InstallPlugin(string PackageUrl, string PackageFilePath, bool DeletePackageAfterInstall)
{ {
if (ScheduledTasks.GetTaskStatuses(typeof(InstallPluginTask)).Where(s => s.IsRunning).Count() > 0) if (ScheduledTasks.GetTaskStatuses(typeof(InstallPluginTask)).Where(s => s.IsRunning).Count() > 0)
throw new InvalidOperationException("A plugin is already being Installed"); throw new InvalidOperationException("A plugin is already being Installed");
JobDataMap taskData = new JobDataMap() { { "PackageFilePath", PackageFilePath }, { "DeletePackageAfterInstall", DeletePackageAfterInstall } }; JobDataMap taskData = new JobDataMap() { { "PackageUrl", PackageUrl }, { "PackageFilePath", PackageFilePath }, { "DeletePackageAfterInstall", DeletePackageAfterInstall } };
var instance = new InstallPluginTask(); var instance = new InstallPluginTask();
@@ -12,5 +12,8 @@ namespace Disco.Services.Plugins
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Author { get; set; } public string Author { get; set; }
public string Url { get; set; }
public string HostVersionMin { get; set; }
public string HostVersionMax { get; set; }
} }
} }
+31 -3
View File
@@ -11,16 +11,27 @@ using System.Web.Mvc;
using Disco.Data.Repository; using Disco.Data.Repository;
using Disco.Services.Tasks; using Disco.Services.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Disco.Services.Plugins namespace Disco.Services.Plugins
{ {
public class PluginManifest public class PluginManifest
{ {
[JsonProperty]
public string Id { get; set; } public string Id { get; set; }
[JsonProperty]
public string Name { get; set; } public string Name { get; set; }
[JsonProperty]
public string Author { get; set; } public string Author { get; set; }
[JsonProperty]
public string Url { get; set; }
[JsonProperty]
public Version Version { get; set; } public Version Version { get; set; }
[JsonProperty] [JsonProperty]
public Version HostVersionMin { get; set; }
[JsonProperty]
public Version HostVersionMax { get; set; }
[JsonProperty]
internal string AssemblyPath { get; set; } internal string AssemblyPath { get; set; }
[JsonProperty] [JsonProperty]
private string TypeName { get; set; } private string TypeName { get; set; }
@@ -49,6 +60,16 @@ namespace Disco.Services.Plugins
[JsonIgnore] [JsonIgnore]
public string StorageLocation { get; private set; } public string StorageLocation { get; private set; }
[JsonIgnore]
public string VersionFormatted
{
get
{
var v = Version;
return string.Format("{0}.{1}.{2:0000}.{3:0000}", v.Major, v.Minor, v.Build, v.Revision);
}
}
[JsonIgnore] [JsonIgnore]
private bool environmentInitalized { get; set; } private bool environmentInitalized { get; set; }
@@ -98,7 +119,7 @@ namespace Disco.Services.Plugins
manifestString = manifestStreamReader.ReadToEnd(); manifestString = manifestStreamReader.ReadToEnd();
} }
var manifest = JsonConvert.DeserializeObject<PluginManifest>(manifestString); var manifest = JsonConvert.DeserializeObject<PluginManifest>(manifestString, new VersionConverter());
manifest.PluginLocation = PluginLocation; manifest.PluginLocation = PluginLocation;
@@ -129,6 +150,10 @@ namespace Disco.Services.Plugins
var pluginId = pluginAttributes.Id; var pluginId = pluginAttributes.Id;
var pluginName = pluginAttributes.Name; var pluginName = pluginAttributes.Name;
var pluginAuthor = pluginAttributes.Author; var pluginAuthor = pluginAttributes.Author;
var pluginUrl = pluginAttributes.Url;
var pluginHostVersionMin = pluginAttributes.HostVersionMin == null ? null : Version.Parse(pluginAttributes.HostVersionMin);
var pluginHostVersionMax = pluginAttributes.HostVersionMax == null ? null : Version.Parse(pluginAttributes.HostVersionMax);
var pluginVersion = assemblyName.Version; var pluginVersion = assemblyName.Version;
var pluginAssemblyPath = Path.GetFileName(assembly.Location); var pluginAssemblyPath = Path.GetFileName(assembly.Location);
@@ -167,6 +192,9 @@ namespace Disco.Services.Plugins
Name = pluginName, Name = pluginName,
Author = pluginAuthor, Author = pluginAuthor,
Version = pluginVersion, Version = pluginVersion,
Url = pluginUrl,
HostVersionMin = pluginHostVersionMin,
HostVersionMax = pluginHostVersionMax,
AssemblyPath = pluginAssemblyPath, AssemblyPath = pluginAssemblyPath,
TypeName = pluginTypeName, TypeName = pluginTypeName,
AssemblyReferences = pluginAssemblyReferences, AssemblyReferences = pluginAssemblyReferences,
@@ -188,7 +216,7 @@ namespace Disco.Services.Plugins
public string ToManifestFile() public string ToManifestFile()
{ {
return JsonConvert.SerializeObject(this, Formatting.Indented); return JsonConvert.SerializeObject(this, Formatting.Indented, new VersionConverter());
} }
private bool InitializePluginEnvironment(DiscoDataContext dbContext) private bool InitializePluginEnvironment(DiscoDataContext dbContext)
{ {
@@ -362,7 +390,7 @@ namespace Disco.Services.Plugins
var fileDateCheck = System.IO.File.GetLastWriteTime(resourcePath); var fileDateCheck = System.IO.File.GetLastWriteTime(resourcePath);
if (fileDateCheck == resourceHash.Item2) if (fileDateCheck == resourceHash.Item2)
#endif #endif
return new Tuple<string, string>(resourcePath, resourceHash.Item1); return new Tuple<string, string>(resourcePath, resourceHash.Item1);
} }
if (!File.Exists(resourcePath)) if (!File.Exists(resourcePath))
+110 -4
View File
@@ -7,6 +7,9 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Disco.Data.Repository; using Disco.Data.Repository;
using System.IO.Compression; using System.IO.Compression;
using Disco.Models.BI.Interop.Community;
using System.Web;
using Newtonsoft.Json;
namespace Disco.Services.Plugins namespace Disco.Services.Plugins
{ {
@@ -42,6 +45,15 @@ namespace Disco.Services.Plugins
} }
} }
public static bool PluginInstalled(string PluginId)
{
if (_PluginManifests == null)
throw new InvalidOperationException("Plugins have not been initialized");
PluginManifest manifest;
return _PluginManifests.TryGetValue(PluginId, out manifest);
}
public static PluginManifest GetPlugin(string PluginId, Type ContainsCategoryType) public static PluginManifest GetPlugin(string PluginId, Type ContainsCategoryType)
{ {
if (_PluginManifests == null) if (_PluginManifests == null)
@@ -145,6 +157,81 @@ namespace Disco.Services.Plugins
throw new InvalidOperationException(string.Format("Unknown Plugin Feature Category Type: [{0}]", FeatureCategoryType.Name)); throw new InvalidOperationException(string.Format("Unknown Plugin Feature Category Type: [{0}]", FeatureCategoryType.Name));
} }
public static string CatalogueFile(DiscoDataContext dbContext)
{
return Path.Combine(dbContext.DiscoConfiguration.PluginPackagesLocation, "Catalogue.json");
}
public static string CompatibilityFile(DiscoDataContext dbContext)
{
return Path.Combine(dbContext.DiscoConfiguration.PluginPackagesLocation, "Compatibility.json");
}
public static PluginLibraryUpdateResponse LoadCatalogue(DiscoDataContext dbContext)
{
var catalogueFile = CatalogueFile(dbContext);
if (!File.Exists(catalogueFile))
return null;
return JsonConvert.DeserializeObject<PluginLibraryUpdateResponse>(File.ReadAllText(catalogueFile));
}
public static PluginLibraryCompatibilityResponse LoadCompatibilityData(DiscoDataContext dbContext)
{
var pluginAssembly = typeof(Plugins).Assembly;
Version hostVersion = pluginAssembly.GetName().Version;
PluginLibraryCompatibilityResponse Data = null;
var localCompatFile = Path.Combine(Path.GetDirectoryName(pluginAssembly.Location), "ReleasePluginCompatibility.json");
var serverCompatFile = CompatibilityFile(dbContext);
if (File.Exists(localCompatFile))
{
Data = JsonConvert.DeserializeObject<PluginLibraryCompatibilityResponse>(File.ReadAllText(localCompatFile));
Data.HostVersion = hostVersion.ToString(4);
}
if (File.Exists(serverCompatFile))
{
var serverData = JsonConvert.DeserializeObject<PluginLibraryCompatibilityResponse>(File.ReadAllText(serverCompatFile));
if (Version.Parse(serverData.HostVersion) == hostVersion)
{
if (Data == null)
{
// No Local Compatibility File
Data = serverData;
}
else
{
// Join Compatibility Files
var localItems = Data.Plugins;
var localItemVersions = localItems.ToDictionary(i => i, i => Version.Parse(i.Version));
var joinedItems = localItems.ToList();
Data.ResponseTimestamp = serverData.ResponseTimestamp;
foreach (var serverItem in serverData.Plugins)
{
var serverItemVersion = Version.Parse(serverItem.Version);
var localItem = localItems.FirstOrDefault(i => i.Id.Equals(serverItem.Id, StringComparison.InvariantCultureIgnoreCase) && serverItemVersion == localItemVersions[i]);
if (localItem != null)
joinedItems.Remove(localItem);
joinedItems.Add(serverItem);
}
Data.Plugins = joinedItems;
}
}
}
if (Data == null)
{
Data = new PluginLibraryCompatibilityResponse()
{
HostVersion = hostVersion.ToString(4),
Plugins = new List<PluginLibraryCompatibilityItem>(),
ResponseTimestamp = new DateTime(2011, 7, 1)
};
}
return Data;
}
public static void InitalizePlugins(DiscoDataContext dbContext) public static void InitalizePlugins(DiscoDataContext dbContext)
{ {
if (_PluginManifests == null) if (_PluginManifests == null)
@@ -153,6 +240,8 @@ namespace Disco.Services.Plugins
{ {
if (_PluginManifests == null) if (_PluginManifests == null)
{ {
Version hostVersion = typeof(Plugins).Assembly.GetName().Version;
var compatibilityData = new Lazy<PluginLibraryCompatibilityResponse>(() => LoadCompatibilityData(dbContext));
Dictionary<string, PluginManifest> loadedPlugins = new Dictionary<string, PluginManifest>(); Dictionary<string, PluginManifest> loadedPlugins = new Dictionary<string, PluginManifest>();
PluginPath = dbContext.DiscoConfiguration.PluginsLocation; PluginPath = dbContext.DiscoConfiguration.PluginsLocation;
@@ -185,11 +274,21 @@ namespace Disco.Services.Plugins
if (File.Exists(updatePackagePath)) if (File.Exists(updatePackagePath))
{ {
// Update Plugin // Update Plugin
pluginManifest = UpdatePlugin(dbContext, pluginManifest, updatePackagePath); pluginManifest = UpdatePlugin(dbContext, pluginManifest, updatePackagePath, compatibilityData.Value);
} }
if (pluginManifest != null) if (pluginManifest != null)
{ {
// Check Version Compatibility
var pluginCompatibility = compatibilityData.Value.Plugins.FirstOrDefault(i => i.Id.Equals(pluginManifest.Id, StringComparison.InvariantCultureIgnoreCase) && pluginManifest.Version == Version.Parse(i.Version));
if (pluginCompatibility != null && !pluginCompatibility.Compatible)
throw new InvalidOperationException(string.Format("The plugin [{0} v{1}] is not compatible: {2}", pluginManifest.Id, pluginManifest.VersionFormatted, pluginCompatibility.Reason));
if (pluginManifest.HostVersionMin != null && pluginManifest.HostVersionMin > hostVersion)
throw new InvalidOperationException(string.Format("The plugin [{0} v{1}] does not support this version of Disco (Requires v{2} or greater)", pluginManifest.Id, pluginManifest.VersionFormatted, pluginManifest.HostVersionMin.ToString()));
if (pluginManifest.HostVersionMax != null && pluginManifest.HostVersionMax < hostVersion)
throw new InvalidOperationException(string.Format("The plugin [{0} v{1}] does not support this version of Disco (Support expired as of v{2})", pluginManifest.Id, pluginManifest.VersionFormatted, pluginManifest.HostVersionMax.ToString()));
pluginManifest.InitializePlugin(dbContext); pluginManifest.InitializePlugin(dbContext);
loadedPlugins[pluginManifest.Id] = pluginManifest; loadedPlugins[pluginManifest.Id] = pluginManifest;
} }
@@ -251,13 +350,13 @@ namespace Disco.Services.Plugins
_PluginAssemblyManifests = _PluginManifests.Values.ToDictionary(p => p.PluginAssembly, p => p); _PluginAssemblyManifests = _PluginManifests.Values.ToDictionary(p => p.PluginAssembly, p => p);
} }
public static PluginManifest UpdatePlugin(DiscoDataContext dbContext, PluginManifest ExistingManifest, String UpdatePluginPackageFilePath) public static PluginManifest UpdatePlugin(DiscoDataContext dbContext, PluginManifest ExistingManifest, String UpdatePluginPackageFilePath, PluginLibraryCompatibilityResponse CompatibilityData = null)
{ {
PluginManifest updatedManifest; PluginManifest updatedManifest;
using (var packageStream = File.OpenRead(UpdatePluginPackageFilePath)) using (var packageStream = File.OpenRead(UpdatePluginPackageFilePath))
{ {
updatedManifest = UpdatePlugin(dbContext, ExistingManifest, packageStream); updatedManifest = UpdatePlugin(dbContext, ExistingManifest, packageStream, CompatibilityData);
} }
// Remove Update after processing // Remove Update after processing
@@ -266,7 +365,7 @@ namespace Disco.Services.Plugins
return updatedManifest; return updatedManifest;
} }
public static PluginManifest UpdatePlugin(DiscoDataContext dbContext, PluginManifest ExistingManifest, Stream UpdatePluginPackage) public static PluginManifest UpdatePlugin(DiscoDataContext dbContext, PluginManifest ExistingManifest, Stream UpdatePluginPackage, PluginLibraryCompatibilityResponse CompatibilityData = null)
{ {
using (MemoryStream packageStream = new MemoryStream()) using (MemoryStream packageStream = new MemoryStream())
{ {
@@ -301,6 +400,13 @@ namespace Disco.Services.Plugins
throw new InvalidDataException("A newer version of this plugin is already installed"); throw new InvalidDataException("A newer version of this plugin is already installed");
} }
// Check Compatibility
if (CompatibilityData == null)
CompatibilityData = LoadCompatibilityData(dbContext);
var pluginCompatibility = CompatibilityData.Plugins.FirstOrDefault(i => i.Id.Equals(packageManifest.Id, StringComparison.InvariantCultureIgnoreCase) && packageManifest.Version == Version.Parse(i.Version));
if (pluginCompatibility != null && !pluginCompatibility.Compatible)
throw new InvalidOperationException(string.Format("The plugin [{0} v{1}] is not compatible: {2}", packageManifest.Id, packageManifest.VersionFormatted, pluginCompatibility.Reason));
string packagePath = Path.Combine(dbContext.DiscoConfiguration.PluginsLocation, packageManifest.Id); string packagePath = Path.Combine(dbContext.DiscoConfiguration.PluginsLocation, packageManifest.Id);
// Force Delete of Existing Folder // Force Delete of Existing Folder
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0207.1727")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0207.1727")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
@@ -4,12 +4,21 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using Disco.BI.Interop.Community;
using Disco.Services.Plugins; using Disco.Services.Plugins;
namespace Disco.Web.Areas.API.Controllers namespace Disco.Web.Areas.API.Controllers
{ {
public partial class PluginController : dbAdminController public partial class PluginController : dbAdminController
{ {
public virtual ActionResult UpdateLibraryCatalogue()
{
var status = PluginLibraryUpdateTask.ScheduleNow();
status.SetFinishedUrl(Url.Action(MVC.Config.Plugins.Install()));
return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId));
}
public virtual ActionResult Uninstall(string id, bool UninstallData) public virtual ActionResult Uninstall(string id, bool UninstallData)
{ {
@@ -23,7 +32,29 @@ namespace Disco.Web.Areas.API.Controllers
return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId)); return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId));
} }
public virtual ActionResult Install(HttpPostedFileBase Plugin) public virtual ActionResult Install(string PluginId)
{
if (string.IsNullOrEmpty(PluginId))
throw new ArgumentNullException("PluginId", "A PluginId must be supplied");
var catalogue = Plugins.LoadCatalogue(dbContext);
var plugin = catalogue.Plugins.FirstOrDefault(p => p.Id.Equals(PluginId));
if (plugin == null)
throw new ArgumentNullException("PluginId", "Plugin not found in catalogue");
// Already Installed?
if (Plugins.PluginInstalled(plugin.Id))
throw new InvalidOperationException("This plugin is already installed");
var tempPluginLocation = Path.Combine(dbContext.DiscoConfiguration.PluginPackagesLocation, string.Format("{0}.discoPlugin", plugin.Id));
var status = InstallPluginTask.InstallPlugin(plugin.LatestDownloadUrl, tempPluginLocation, true);
return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId));
}
public virtual ActionResult InstallLocal(HttpPostedFileBase Plugin)
{ {
if (Plugin == null || Plugin.ContentLength <= 0 || string.IsNullOrWhiteSpace(Plugin.FileName)) if (Plugin == null || Plugin.ContentLength <= 0 || string.IsNullOrWhiteSpace(Plugin.FileName))
throw new ArgumentException("A discoPlugin file must be uploaded", "Plugin"); throw new ArgumentException("A discoPlugin file must be uploaded", "Plugin");
@@ -36,10 +67,9 @@ namespace Disco.Web.Areas.API.Controllers
if (System.IO.File.Exists(tempPluginLocation)) if (System.IO.File.Exists(tempPluginLocation))
System.IO.File.Delete(tempPluginLocation); System.IO.File.Delete(tempPluginLocation);
Plugin.SaveAs(tempPluginLocation); Plugin.SaveAs(tempPluginLocation);
var status = InstallPluginTask.InstallPlugin(tempPluginLocation, true); var status = InstallPluginTask.InstallLocalPlugin(tempPluginLocation, true);
return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId)); return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId));
} }
@@ -106,6 +106,11 @@ namespace Disco.Web.Areas.Config
"Config/Plugins", "Config/Plugins",
new { controller = "Plugins", action = "Index"} new { controller = "Plugins", action = "Index"}
); );
context.MapRoute(
"Config_Plugins_Install",
"Config/Plugins/Install",
new { controller = "Plugins", action = "Install" }
);
context.MapRoute( context.MapRoute(
"Config_Plugins_Configure", "Config_Plugins_Configure",
"Config/Plugins/{PluginId}", "Config/Plugins/{PluginId}",
@@ -29,24 +29,14 @@ namespace Disco.Web.Areas.Config.Controllers
public virtual ActionResult TaskStatus(string id) public virtual ActionResult TaskStatus(string id)
{ {
if (string.IsNullOrEmpty(id)) if (string.IsNullOrEmpty(id))
{ throw new ArgumentNullException("id", "A Task Status Id is required");
string sessionId;
do
{
System.Threading.Thread.Sleep(100);
sessionId = Disco.Services.Tasks.ScheduledTasks.GetTaskStatuses(typeof(Disco.BI.Interop.ActiveDirectory.ActiveDirectoryUpdateLastNetworkLogonDateJob)).Select(t => t.SessionId).FirstOrDefault();
} while (sessionId == null);
return View(new Models.Logging.TaskStatusModel() { SessionId = sessionId }); var taskStatus = Disco.Services.Tasks.ScheduledTasks.GetTaskStatus(id);
} if (taskStatus == null)
else return RedirectToAction(MVC.Config.Logging.Index());
{
var taskStatus = Disco.Services.Tasks.ScheduledTasks.GetTaskStatus(id);
return View(new Models.Logging.TaskStatusModel() { SessionId = taskStatus.SessionId });
}
return View(new Models.Logging.TaskStatusModel() { SessionId = taskStatus.SessionId });
} }
} }
@@ -4,6 +4,7 @@ using System.Linq;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using Disco.Services.Plugins; using Disco.Services.Plugins;
using Disco.Services.Tasks;
using Disco.Web.Areas.Config.Models.Plugins; using Disco.Web.Areas.Config.Models.Plugins;
namespace Disco.Web.Areas.Config.Controllers namespace Disco.Web.Areas.Config.Controllers
@@ -65,5 +66,27 @@ namespace Disco.Web.Areas.Config.Controllers
} }
#endregion #endregion
public virtual ActionResult Install()
{
// Check for recent catalogue
var catalogue = Plugins.LoadCatalogue(dbContext);
if (catalogue == null || catalogue.ResponseTimestamp < DateTime.Now.AddMinutes(-15))
{
// Need to Update Catalogue
return RedirectToAction(MVC.API.Plugin.UpdateLibraryCatalogue());
}
else
{
var model = new Models.Plugins.InstallModel()
{
Catalogue = catalogue
};
return View(model);
}
}
} }
} }
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Disco.Models.BI.Interop.Community;
namespace Disco.Web.Areas.Config.Models.Plugins
{
public class InstallModel
{
public PluginLibraryUpdateResponse Catalogue { get; set; }
}
}
@@ -14,8 +14,8 @@
</div> </div>
<button id="expressionEditorValidateButton"> <button id="expressionEditorValidateButton">
Validate</button> Validate</button>
@if (false) @* @if (false)
{ <script src="/ClientSource/Scripts/Core/jquery-1.7.1.js" type="text/javascript"></script>} { <script src="/ClientSource/Scripts/Core/jquery-1.7.1.js" type="text/javascript"></script>}*@
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {
var initExpression = '@(Model.Expression)'; var initExpression = '@(Model.Expression)';
@@ -71,35 +71,7 @@ WriteLiteral(" id=\"expressionEditorValidateButton\"");
WriteLiteral(">\r\n Validate</button>\r\n"); WriteLiteral(">\r\n Validate</button>\r\n");
WriteLiteral("\r\n <script");
#line 17 "..\..\Areas\Config\Views\Expressions\Editor.cshtml"
#line default
#line hidden
#line 17 "..\..\Areas\Config\Views\Expressions\Editor.cshtml"
if (false)
{
#line default
#line hidden
WriteLiteral(" <script");
WriteLiteral(" src=\"/ClientSource/Scripts/Core/jquery-1.7.1.js\"");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral("></script>");
#line 18 "..\..\Areas\Config\Views\Expressions\Editor.cshtml"
}
#line default
#line hidden
WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\""); WriteLiteral(" type=\"text/javascript\"");
+68 -106
View File
@@ -3,72 +3,75 @@
@{ @{
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Plugins"); ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Plugins");
} }
@{ <div id="plugins">
if (Model.PluginManifests.Count == 0) @{
{ if (Model.PluginManifests.Count == 0)
<div class="form" style="width: 450px; padding: 100px 0;"> {
<h2>No Plugins are Installed</h2> <div class="form" style="width: 450px; padding: 100px 0;">
</div> <h2>No Plugins are Installed</h2>
}
else
{
var pluginGroups = Model.PluginManifestsByType;
int itemsPerColumn = pluginGroups.Count / 3;
var itemNextId = 0;
<table id="pageMenu">
<tr>
@for (int i = 0; i < 3; i++)
{
<td>
@{
int itemsForThisColumn = itemsPerColumn + (pluginGroups.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < pluginGroups.Count; i2++)
{
var pluginGroup = pluginGroups[itemNextId];
itemNextId++;
<div class="pageMenuArea">
<h2>@Plugins.PluginFeatureCategoryDisplayName(pluginGroup.Item1)</h2>
@foreach (var pluginDefinition in pluginGroup.Item2)
{
@Html.ActionLink(pluginDefinition.Name, MVC.Config.Plugins.Configure(pluginDefinition.Id))
<div class="pageMenuBlurb">
@pluginDefinition.Id | v@(pluginDefinition.Version.ToString(3))
</div>
}
</div>
}
}
</td>
}
</tr>
</table>
<div id="dialogUninstallPlugins" title="Uninstall Plugin">
<div>
@Html.DropDownList("uninstallPlugin", Model.PluginManifests.ToSelectListItems(null, true, "Select a Plugin to Uninstall"))
</div> </div>
<div> }
<input id="uninstallPluginData" type="checkbox" /><label for="uninstallPluginData"> Uninstall Plugin Data</label> else
<div id="uninstallPluginDataAlert" style="display: none; padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all"> {
var pluginGroups = Model.PluginManifestsByType;
int itemsPerColumn = pluginGroups.Count / 3;
var itemNextId = 0;
<table id="pageMenu">
<tr>
@for (int i = 0; i < 3; i++)
{
<td>
@{
int itemsForThisColumn = itemsPerColumn + (pluginGroups.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < pluginGroups.Count; i2++)
{
var pluginGroup = pluginGroups[itemNextId];
itemNextId++;
<div class="pageMenuArea">
<h2>@Plugins.PluginFeatureCategoryDisplayName(pluginGroup.Item1)</h2>
@foreach (var pluginDefinition in pluginGroup.Item2)
{
<a href="@Url.Action(MVC.Config.Plugins.Configure(pluginDefinition.Id))">
<h3>@pluginDefinition.Name</h3>
</a>
<div class="pageMenuBlurb">
<span class="pluginId">@pluginDefinition.Id</span> | <span class="pluginVersion">v@(pluginDefinition.VersionFormatted)</span> | @pluginDefinition.Author | <a href="@pluginDefinition.Url" target="_blank">More Information</a>
</div>
}
</div>
}
}
</td>
}
</tr>
</table>
<div id="dialogUninstallPlugins" title="Uninstall Plugin">
<div>
@Html.DropDownList("uninstallPlugin", Model.PluginManifests.ToSelectListItems(null, true, "Select a Plugin to Uninstall"))
</div>
<div>
<input id="uninstallPluginData" type="checkbox" /><label for="uninstallPluginData"> Uninstall Plugin Data</label>
<div id="uninstallPluginDataAlert" style="display: none; padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all">
<span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-alert"></span>NOTE: Data will be permanently deleted
</div>
</div>
</div>
<div id="dialogUninstallPluginConfirm" title="Confirm Plugin Uninstall">
<div style="padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-highlight ui-corner-all">
<span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-help"></span>Are you sure you want to uninstall this plugin?
<h4 id="uninstallPluginConfirm"></h4>
</div>
<div id="uninstallPluginDataConfirm" style="display: none; padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all">
<span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-alert"></span>NOTE: Data will be permanently deleted <span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-alert"></span>NOTE: Data will be permanently deleted
</div> </div>
</div> </div>
</div> <script>
<div id="dialogUninstallPluginConfirm" title="Confirm Plugin Uninstall"> $(function () {
<div style="padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-highlight ui-corner-all"> // Uninstall
<span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-help"></span>Are you sure you want to uninstall this plugin? var uninstallUrl = '@(Url.Action(MVC.API.Plugin.Uninstall()))/';
<h4 id="uninstallPluginConfirm"></h4>
</div>
<div id="uninstallPluginDataConfirm" style="display: none; padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all">
<span style="margin-right: 0.3em; float: left;" class="ui-icon ui-icon-alert"></span>NOTE: Data will be permanently deleted
</div>
</div>
<script>
$(function () {
// Uninstall
var uninstallUrl = '@(Url.Action(MVC.API.Plugin.Uninstall()))/';
var uninstallPlugin, uninstallPluginData, $dialogConfirm, uninstallPluginConfirm, uninstallPluginDataConfirm; var uninstallPlugin, uninstallPluginData, $dialogConfirm, uninstallPluginConfirm, uninstallPluginDataConfirm;
var pluginId, pluginName, pluginUninstallData; var pluginId, pluginName, pluginUninstallData;
@@ -147,55 +150,14 @@
} }
}); });
}); });
</script> </script>
}
}
<div id="dialogInstallPlugin" title="Install Plugin">
<div style="padding-bottom: 10px;">
@using (Html.BeginForm(MVC.API.Plugin.Install(), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<label for="pluginFile">Plugin Package: </label>
<input id="pluginFile" name="Plugin" type="file" />
} }
</div> }
<div style="padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all">
<span style="margin-right: 0.3em; margin-bottom: 2em; float: left;" class="ui-icon ui-icon-alert"></span>Warning: All plugins run with the same level of network privileges as the Disco Web App.<br />
<strong>Only install plugins from a trusted source.</strong>
</div>
</div> </div>
<script>
$(function () {
// Install
var $dialogInstall = $('#dialogInstallPlugin').dialog({
resizable: false,
modal: true,
width: 350,
autoOpen: false,
buttons: {
"Upload & Install": function () {
var pluginFile = $('#pluginFile');
if (pluginFile.val()) {
pluginFile.closest('form').submit();
$(this).dialog('disable');
} else {
alert('Choose a Plugin Package to Install');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
});
$('#buttonInstall').click(function () {
$dialogInstall.dialog('open');
return false;
});
});
</script>
<div class="actionBar"> <div class="actionBar">
@if (Model.PluginManifests.Count > 0) @if (Model.PluginManifests.Count > 0)
{ {
@Html.ActionLinkButton("Uninstall Plugins", MVC.Config.Plugins.Index(), "buttonUninstall") @Html.ActionLinkButton("Uninstall Plugins", MVC.Config.Plugins.Index(), "buttonUninstall")
} }
@Html.ActionLinkButton("Install Plugins", MVC.Config.Plugins.Index(), "buttonInstall") @Html.ActionLinkButton("Install Plugins", MVC.Config.Plugins.Install())
</div> </div>
@@ -54,89 +54,99 @@ namespace Disco.Web.Areas.Config.Views.Plugins
#line default #line default
#line hidden #line hidden
WriteLiteral("\r\n"); WriteLiteral("\r\n<div");
WriteLiteral(" id=\"plugins\"");
WriteLiteral(">\r\n");
#line 6 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 7 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
if (Model.PluginManifests.Count == 0)
{
#line default #line default
#line hidden #line hidden
WriteLiteral(" <div");
#line 7 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
if (Model.PluginManifests.Count == 0)
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"form\""); WriteLiteral(" class=\"form\"");
WriteLiteral(" style=\"width: 450px; padding: 100px 0;\""); WriteLiteral(" style=\"width: 450px; padding: 100px 0;\"");
WriteLiteral(">\r\n <h2>No Plugins are Installed</h2>\r\n </div> \r\n"); WriteLiteral(">\r\n <h2>No Plugins are Installed</h2>\r\n </div> \r\n");
#line 12 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 13 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
} }
else else
{ {
var pluginGroups = Model.PluginManifestsByType; var pluginGroups = Model.PluginManifestsByType;
int itemsPerColumn = pluginGroups.Count / 3; int itemsPerColumn = pluginGroups.Count / 3;
var itemNextId = 0; var itemNextId = 0;
#line default #line default
#line hidden #line hidden
WriteLiteral(" <table"); WriteLiteral(" <table");
WriteLiteral(" id=\"pageMenu\""); WriteLiteral(" id=\"pageMenu\"");
WriteLiteral(">\r\n <tr>\r\n"); WriteLiteral(">\r\n <tr>\r\n");
#line 23 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 24 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default #line default
#line hidden #line hidden
#line 23 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 24 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{
#line default
#line hidden
WriteLiteral(" <td>\r\n");
#line 26 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default
#line hidden
#line 26 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
int itemsForThisColumn = itemsPerColumn + (pluginGroups.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < pluginGroups.Count; i2++)
{ {
var pluginGroup = pluginGroups[itemNextId];
itemNextId++;
#line default #line default
#line hidden #line hidden
WriteLiteral(" <div"); WriteLiteral(" <td>\r\n");
#line 27 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default
#line hidden
#line 27 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
int itemsForThisColumn = itemsPerColumn + (pluginGroups.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < pluginGroups.Count; i2++)
{
var pluginGroup = pluginGroups[itemNextId];
itemNextId++;
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"pageMenuArea\""); WriteLiteral(" class=\"pageMenuArea\"");
WriteLiteral(">\r\n <h2>"); WriteLiteral(">\r\n <h2>");
#line 33 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 34 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(Plugins.PluginFeatureCategoryDisplayName(pluginGroup.Item1)); Write(Plugins.PluginFeatureCategoryDisplayName(pluginGroup.Item1));
#line default #line default
@@ -144,104 +154,142 @@ WriteLiteral(">\r\n <h2>");
WriteLiteral("</h2>\r\n"); WriteLiteral("</h2>\r\n");
#line 34 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 35 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default #line default
#line hidden #line hidden
#line 34 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 35 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
foreach (var pluginDefinition in pluginGroup.Item2) foreach (var pluginDefinition in pluginGroup.Item2)
{ {
#line default #line default
#line hidden #line hidden
WriteLiteral(" <a");
#line 36 "..\..\Areas\Config\Views\Plugins\Index.cshtml" WriteAttribute("href", Tuple.Create(" href=\"", 1435), Tuple.Create("\"", 1504)
Write(Html.ActionLink(pluginDefinition.Name, MVC.Config.Plugins.Configure(pluginDefinition.Id)));
#line 37 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
, Tuple.Create(Tuple.Create("", 1442), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Config.Plugins.Configure(pluginDefinition.Id))
#line default
#line hidden
, 1442), false)
);
WriteLiteral(">\r\n <h3>");
#line 38 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(pluginDefinition.Name);
#line default #line default
#line hidden #line hidden
WriteLiteral("</h3>\r\n </a>\r\n");
#line 36 "..\..\Areas\Config\Views\Plugins\Index.cshtml" WriteLiteral(" <div");
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"pageMenuBlurb\""); WriteLiteral(" class=\"pageMenuBlurb\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n <span");
WriteLiteral(" "); WriteLiteral(" class=\"pluginId\"");
WriteLiteral(">");
#line 38 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 41 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(pluginDefinition.Id); Write(pluginDefinition.Id);
#line default #line default
#line hidden #line hidden
WriteLiteral(" | v"); WriteLiteral("</span> | <span");
WriteLiteral(" class=\"pluginVersion\"");
WriteLiteral(">v");
#line 38 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 41 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(pluginDefinition.Version.ToString(3)); Write(pluginDefinition.VersionFormatted);
#line default #line default
#line hidden #line hidden
WriteLiteral("\r\n </div>\r\n"); WriteLiteral("</span> | ");
#line 40 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 41 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
} Write(pluginDefinition.Author);
#line default #line default
#line hidden #line hidden
WriteLiteral(" </div>\r\n"); WriteLiteral(" | <a");
WriteAttribute("href", Tuple.Create(" href=\"", 1885), Tuple.Create("\"", 1913)
#line 41 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
, Tuple.Create(Tuple.Create("", 1892), Tuple.Create<System.Object, System.Int32>(pluginDefinition.Url
#line default
#line hidden
, 1892), false)
);
WriteLiteral(" target=\"_blank\"");
WriteLiteral(">More Information</a>\r\n </div>\r\n");
#line 42 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 43 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
#line 45 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
}
#line default
#line hidden
WriteLiteral("\r\n </td>\r\n");
#line 48 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
} }
#line default #line default
#line hidden #line hidden
WriteLiteral("\r\n </td>\r\n"); WriteLiteral(" </tr>\r\n </table>\r\n");
WriteLiteral(" <div");
#line 45 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
}
#line default
#line hidden
WriteLiteral(" </tr>\r\n </table>\r\n");
WriteLiteral(" <div");
WriteLiteral(" id=\"dialogUninstallPlugins\""); WriteLiteral(" id=\"dialogUninstallPlugins\"");
WriteLiteral(" title=\"Uninstall Plugin\""); WriteLiteral(" title=\"Uninstall Plugin\"");
WriteLiteral(">\r\n <div>\r\n"); WriteLiteral(">\r\n <div>\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 50 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 53 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(Html.DropDownList("uninstallPlugin", Model.PluginManifests.ToSelectListItems(null, true, "Select a Plugin to Uninstall"))); Write(Html.DropDownList("uninstallPlugin", Model.PluginManifests.ToSelectListItems(null, true, "Select a Plugin to Uninstall")));
#line default #line default
#line hidden #line hidden
WriteLiteral("\r\n </div>\r\n <div>\r\n <input"); WriteLiteral("\r\n </div>\r\n <div>\r\n <input");
WriteLiteral(" id=\"uninstallPluginData\""); WriteLiteral(" id=\"uninstallPluginData\"");
@@ -251,7 +299,7 @@ WriteLiteral(" /><label");
WriteLiteral(" for=\"uninstallPluginData\""); WriteLiteral(" for=\"uninstallPluginData\"");
WriteLiteral("> Uninstall Plugin Data</label>\r\n <div"); WriteLiteral("> Uninstall Plugin Data</label>\r\n <div");
WriteLiteral(" id=\"uninstallPluginDataAlert\""); WriteLiteral(" id=\"uninstallPluginDataAlert\"");
@@ -259,6 +307,45 @@ WriteLiteral(" style=\"display: none; padding: 0.7em 0.7em; margin-top: 8px;\"")
WriteLiteral(" class=\"ui-state-error ui-corner-all\""); WriteLiteral(" class=\"ui-state-error ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral("></span>NOTE: Data will be permanently deleted\r\n </div>\r\n " +
" </div>\r\n </div>\r\n");
WriteLiteral(" <div");
WriteLiteral(" id=\"dialogUninstallPluginConfirm\"");
WriteLiteral(" title=\"Confirm Plugin Uninstall\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" style=\"padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-highlight ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-help\"");
WriteLiteral("></span>Are you sure you want to uninstall this plugin?\r\n <h4");
WriteLiteral(" id=\"uninstallPluginConfirm\"");
WriteLiteral("></h4>\r\n </div>\r\n <div");
WriteLiteral(" id=\"uninstallPluginDataConfirm\"");
WriteLiteral(" style=\"display: none; padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-error ui-corner-all\"");
WriteLiteral(">\r\n <span"); WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; float: left;\""); WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
@@ -266,52 +353,14 @@ WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\""); WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral("></span>NOTE: Data will be permanently deleted\r\n </div>\r\n </div" + WriteLiteral("></span>NOTE: Data will be permanently deleted\r\n </div>\r\n </div" +
">\r\n </div>\r\n"); ">\r\n");
WriteLiteral(" <div"); WriteLiteral(" <script>\r\n $(function () {\r\n // Uninstall\r\n " +
" var uninstallUrl = \'");
WriteLiteral(" id=\"dialogUninstallPluginConfirm\"");
WriteLiteral(" title=\"Confirm Plugin Uninstall\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" style=\"padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-highlight ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-help\"");
WriteLiteral("></span>Are you sure you want to uninstall this plugin?\r\n <h4");
WriteLiteral(" id=\"uninstallPluginConfirm\"");
WriteLiteral("></h4>\r\n </div>\r\n <div");
WriteLiteral(" id=\"uninstallPluginDataConfirm\"");
WriteLiteral(" style=\"display: none; padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-error ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral("></span>NOTE: Data will be permanently deleted\r\n </div>\r\n </div>\r\n");
WriteLiteral(" <script>\r\n $(function () {\r\n // Uninstall\r\n var " +
"uninstallUrl = \'");
#line 71 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 74 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(Url.Action(MVC.API.Plugin.Uninstall())); Write(Url.Action(MVC.API.Plugin.Uninstall()));
#line default #line default
@@ -357,123 +406,29 @@ WriteLiteral("/\';\r\n var uninstallPlugin, uninstallPluginData, $dia
" if ($(this).is(\':checked\')) {\r\n $(\'#uninstallPluginD" + " if ($(this).is(\':checked\')) {\r\n $(\'#uninstallPluginD" +
"ataAlert\').slideDown();\r\n } else {\r\n $(\'#unins" + "ataAlert\').slideDown();\r\n } else {\r\n $(\'#unins" +
"tallPluginDataAlert\').slideUp();\r\n }\r\n });\r\n })" + "tallPluginDataAlert\').slideUp();\r\n }\r\n });\r\n })" +
";\r\n </script>\r\n"); ";\r\n </script>\r\n");
#line 151 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 154 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
}
#line default
#line hidden
WriteLiteral("\r\n<div");
WriteLiteral(" id=\"dialogInstallPlugin\"");
WriteLiteral(" title=\"Install Plugin\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" style=\"padding-bottom: 10px;\"");
WriteLiteral(">\r\n");
#line 155 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default
#line hidden
#line 155 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
using (Html.BeginForm(MVC.API.Plugin.Install(), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#line default
#line hidden
WriteLiteral(" <label");
WriteLiteral(" for=\"pluginFile\"");
WriteLiteral(">Plugin Package: </label>\r\n");
WriteLiteral(" <input");
WriteLiteral(" id=\"pluginFile\"");
WriteLiteral(" name=\"Plugin\"");
WriteLiteral(" type=\"file\"");
WriteLiteral(" />\r\n");
#line 159 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
} }
#line default #line default
#line hidden #line hidden
WriteLiteral(" </div>\r\n <div"); WriteLiteral("\r\n</div>\r\n<div");
WriteLiteral(" style=\"padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-error ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; margin-bottom: 2em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral(@"></span>Warning: All plugins run with the same level of network privileges as the Disco Web App.<br />
<strong>Only install plugins from a trusted source.</strong>
</div>
</div>
<script>
$(function () {
// Install
var $dialogInstall = $('#dialogInstallPlugin').dialog({
resizable: false,
modal: true,
width: 350,
autoOpen: false,
buttons: {
""Upload & Install"": function () {
var pluginFile = $('#pluginFile');
if (pluginFile.val()) {
pluginFile.closest('form').submit();
$(this).dialog('disable');
} else {
alert('Choose a Plugin Package to Install');
}
},
Cancel: function () {
$(this).dialog(""close"");
}
}
});
$('#buttonInstall').click(function () {
$dialogInstall.dialog('open');
return false;
});
});
</script>
<div");
WriteLiteral(" class=\"actionBar\""); WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 196 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 158 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
#line default #line default
#line hidden #line hidden
#line 196 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 158 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
if (Model.PluginManifests.Count > 0) if (Model.PluginManifests.Count > 0)
{ {
@@ -481,14 +436,14 @@ WriteLiteral(">\r\n");
#line default #line default
#line hidden #line hidden
#line 198 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 160 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(Html.ActionLinkButton("Uninstall Plugins", MVC.Config.Plugins.Index(), "buttonUninstall")); Write(Html.ActionLinkButton("Uninstall Plugins", MVC.Config.Plugins.Index(), "buttonUninstall"));
#line default #line default
#line hidden #line hidden
#line 198 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 160 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
} }
@@ -498,8 +453,8 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 200 "..\..\Areas\Config\Views\Plugins\Index.cshtml" #line 162 "..\..\Areas\Config\Views\Plugins\Index.cshtml"
Write(Html.ActionLinkButton("Install Plugins", MVC.Config.Plugins.Index(), "buttonInstall")); Write(Html.ActionLinkButton("Install Plugins", MVC.Config.Plugins.Install()));
#line default #line default
@@ -0,0 +1,144 @@
@model Disco.Web.Areas.Config.Models.Plugins.InstallModel
@using Disco.Services.Plugins;
@{
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Plugins", MVC.Config.Plugins.Index(), "Install Plugin");
}
<div id="pluginCatalog">
<h4 id="pluginCatalogHeading">The plugin catalogue [<a href="http://discoict.com.au/">http://discoict.com.au</a>] was last updated @CommonHelpers.FriendlyDate(Model.Catalogue.ResponseTimestamp)
</h4>
@if (Model.Catalogue.Plugins.Count == 0)
{
<div class="form" style="width: 450px; padding: 100px 0;">
<h2>No Plugins are Available</h2>
</div>
}
else
{
var plugins = Model.Catalogue.Plugins;
int itemsPerColumn = plugins.Count / 3;
var itemNextId = 0;
<table id="pageMenu">
<tr>
@for (int i = 0; i < 3; i++)
{
<td>
@{
int itemsForThisColumn = itemsPerColumn + (plugins.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < plugins.Count; i2++)
{
var plugin = plugins[itemNextId];
itemNextId++;
<div class="pageMenuArea pluginItem@(Plugins.PluginInstalled(plugin.Id) ? " pluginInstalled" : string.Empty)">
<a class="pluginInstallLink" href="@(Url.Action(MVC.API.Plugin.Install(plugin.Id)))">
<h2 class="pluginName">@plugin.Name</h2>
</a>
<div class="pluginItemBlurb">@(new HtmlString(plugin.Blurb))</div>
<div class="pageMenuBlurb">
<span class="pluginId">@plugin.Id</span> | <span class="pluginVersion">v@(plugin.LatestVersion)</span> | @plugin.Author | <a href="@plugin.Url" target="_blank">More Information</a>
</div>
</div>
}
}
</td>
}
</tr>
</table>
}
</div>
<div id="dialogInstallPlugin" title="Install this Plugin?">
<h2 id="dialogInstallPluginName"></h2>
<h4 id="dialogInstallPluginDetails"></h4>
<div style="padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-highlight ui-corner-all">
<span style="margin-right: 0.3em; margin-bottom: 2em; float: left;" class="ui-icon ui-icon-alert"></span>Warning: All plugins run with the same level of network privileges as the Disco Web App.<br />
<strong>Only Install plugins from a trusted source.</strong>
</div>
</div>
<div id="dialogUploadPlugin" title="Install Plugin Package">
<div style="padding-bottom: 10px;">
@using (Html.BeginForm(MVC.API.Plugin.InstallLocal(), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<label for="pluginFile">Plugin Package: </label>
<input id="pluginFile" name="Plugin" type="file" />
}
</div>
<div style="padding: 0.7em 0.7em; margin-top: 8px;" class="ui-state-error ui-corner-all">
<span style="margin-right: 0.3em; margin-bottom: 2em; float: left;" class="ui-icon ui-icon-alert"></span>Warning: All plugins run with the same level of network privileges as the Disco Web App.<br />
<strong>Only install plugins from a trusted source.</strong>
</div>
</div>
<script>
$(function () {
var $selectedPlugin;
var $selectedPluginUrl;
// Install
var $dialogInstall = $('#dialogInstallPlugin').dialog({
resizable: false,
modal: true,
width: 350,
autoOpen: false,
buttons: {
"Install": function () {
if ($selectedPlugin == null || !$selectedPluginUrl) {
$(this).dialog("close");
return;
}
$(this).dialog("disable");
window.location.href = $selectedPluginUrl;
},
Cancel: function () {
$selectedPlugin = null;
$(this).dialog("close");
}
}
});
$('#pageMenu').find('a.pluginInstallLink').click(function () {
$this = $(this);
$selectedPlugin = $this.closest('.pluginItem');
$selectedPluginUrl = $this.attr('href');
if ($selectedPlugin.is('.pluginInstalled')) {
alert('This plugin is already installed.');
} else {
$('#dialogInstallPluginName').text($selectedPlugin.find('.pluginName').text());
$('#dialogInstallPluginDetails').text($selectedPlugin.find('.pluginId').text() + ' | ' + $selectedPlugin.find('.pluginVersion').text());
$dialogInstall.dialog('open');
}
return false;
});
// Upload
var $dialogUpload = $('#dialogUploadPlugin').dialog({
resizable: false,
modal: true,
width: 350,
autoOpen: false,
buttons: {
"Upload & Install": function () {
var pluginFile = $('#pluginFile');
if (pluginFile.val()) {
pluginFile.closest('form').submit();
$(this).dialog('disable');
} else {
alert('Choose a Plugin Package to Upload');
}
},
Cancel: function () {
$(this).dialog("close");
}
}
});
$('#buttonUpload').click(function () {
$dialogUpload.dialog('open');
return false;
});
});
</script>
<div class="actionBar">
@Html.ActionLinkButton("Update Catalogue", MVC.API.Plugin.UpdateLibraryCatalogue())
@Html.ActionLinkButton("Install Plugin Package", MVC.API.Plugin.InstallLocal(), "buttonUpload")
</div>
@@ -0,0 +1,443 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Disco.Web.Areas.Config.Views.Plugins
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Mvc.Html;
using System.Web.Routing;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
using Disco.BI.Extensions;
using Disco.Models.Repository;
#line 2 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
using Disco.Services.Plugins;
#line default
#line hidden
using Disco.Web;
using Disco.Web.Extensions;
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.0.0")]
[System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/Plugins/Install.cshtml")]
public class Install : System.Web.Mvc.WebViewPage<Disco.Web.Areas.Config.Models.Plugins.InstallModel>
{
public Install()
{
}
public override void Execute()
{
#line 3 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Plugins", MVC.Config.Plugins.Index(), "Install Plugin");
#line default
#line hidden
WriteLiteral("\r\n<div");
WriteLiteral(" id=\"pluginCatalog\"");
WriteLiteral(">\r\n <h4");
WriteLiteral(" id=\"pluginCatalogHeading\"");
WriteLiteral(">The plugin catalogue [<a");
WriteLiteral(" href=\"http://discoict.com.au/\"");
WriteLiteral(">http://discoict.com.au</a>] was last updated ");
#line 7 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(CommonHelpers.FriendlyDate(Model.Catalogue.ResponseTimestamp));
#line default
#line hidden
WriteLiteral("\r\n </h4>\r\n");
#line 9 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
#line default
#line hidden
#line 9 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
if (Model.Catalogue.Plugins.Count == 0)
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"form\"");
WriteLiteral(" style=\"width: 450px; padding: 100px 0;\"");
WriteLiteral(">\r\n <h2>No Plugins are Available</h2>\r\n </div> \r\n");
#line 14 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
}
else
{
var plugins = Model.Catalogue.Plugins;
int itemsPerColumn = plugins.Count / 3;
var itemNextId = 0;
#line default
#line hidden
WriteLiteral(" <table");
WriteLiteral(" id=\"pageMenu\"");
WriteLiteral(">\r\n <tr>\r\n");
#line 22 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
#line default
#line hidden
#line 22 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
for (int i = 0; i < 3; i++)
{
#line default
#line hidden
WriteLiteral(" <td>\r\n");
#line 25 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
#line default
#line hidden
#line 25 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
int itemsForThisColumn = itemsPerColumn + (plugins.Count % 3 > i ? 1 : 0);
for (int i2 = 0; i2 < itemsForThisColumn && itemNextId < plugins.Count; i2++)
{
var plugin = plugins[itemNextId];
itemNextId++;
#line default
#line hidden
WriteLiteral(" <div");
WriteAttribute("class", Tuple.Create(" class=\"", 1328), Tuple.Create("\"", 1432)
, Tuple.Create(Tuple.Create("", 1336), Tuple.Create("pageMenuArea", 1336), true)
, Tuple.Create(Tuple.Create(" ", 1348), Tuple.Create("pluginItem", 1349), true)
#line 31 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
, Tuple.Create(Tuple.Create("", 1359), Tuple.Create<System.Object, System.Int32>(Plugins.PluginInstalled(plugin.Id) ? " pluginInstalled" : string.Empty
#line default
#line hidden
, 1359), false)
);
WriteLiteral(">\r\n <a");
WriteLiteral(" class=\"pluginInstallLink\"");
WriteAttribute("href", Tuple.Create(" href=\"", 1496), Tuple.Create("\"", 1551)
#line 32 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
, Tuple.Create(Tuple.Create("", 1503), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Plugin.Install(plugin.Id))
#line default
#line hidden
, 1503), false)
);
WriteLiteral(">\r\n <h2");
WriteLiteral(" class=\"pluginName\"");
WriteLiteral(">");
#line 33 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(plugin.Name);
#line default
#line hidden
WriteLiteral("</h2>\r\n </a>\r\n <div" +
"");
WriteLiteral(" class=\"pluginItemBlurb\"");
WriteLiteral(">");
#line 35 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(new HtmlString(plugin.Blurb));
#line default
#line hidden
WriteLiteral("</div>\r\n <div");
WriteLiteral(" class=\"pageMenuBlurb\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"pluginId\"");
WriteLiteral(">");
#line 37 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(plugin.Id);
#line default
#line hidden
WriteLiteral("</span> | <span");
WriteLiteral(" class=\"pluginVersion\"");
WriteLiteral(">v");
#line 37 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(plugin.LatestVersion);
#line default
#line hidden
WriteLiteral("</span> | ");
#line 37 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(plugin.Author);
#line default
#line hidden
WriteLiteral(" | <a");
WriteAttribute("href", Tuple.Create(" href=\"", 1992), Tuple.Create("\"", 2010)
#line 37 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
, Tuple.Create(Tuple.Create("", 1999), Tuple.Create<System.Object, System.Int32>(plugin.Url
#line default
#line hidden
, 1999), false)
);
WriteLiteral(" target=\"_blank\"");
WriteLiteral(">More Information</a>\r\n </div>\r\n " +
" </div>\r\n");
#line 40 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
}
#line default
#line hidden
WriteLiteral("\r\n </td>\r\n");
#line 43 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
}
#line default
#line hidden
WriteLiteral(" </tr>\r\n </table>\r\n");
#line 46 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
}
#line default
#line hidden
WriteLiteral("</div>\r\n<div");
WriteLiteral(" id=\"dialogInstallPlugin\"");
WriteLiteral(" title=\"Install this Plugin?\"");
WriteLiteral(">\r\n <h2");
WriteLiteral(" id=\"dialogInstallPluginName\"");
WriteLiteral("></h2>\r\n <h4");
WriteLiteral(" id=\"dialogInstallPluginDetails\"");
WriteLiteral("></h4>\r\n\r\n <div");
WriteLiteral(" style=\"padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-highlight ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; margin-bottom: 2em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral("></span>Warning: All plugins run with the same level of network privileges as the" +
" Disco Web App.<br />\r\n <strong>Only Install plugins from a trusted sourc" +
"e.</strong>\r\n </div>\r\n</div>\r\n<div");
WriteLiteral(" id=\"dialogUploadPlugin\"");
WriteLiteral(" title=\"Install Plugin Package\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" style=\"padding-bottom: 10px;\"");
WriteLiteral(">\r\n");
#line 59 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
#line default
#line hidden
#line 59 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
using (Html.BeginForm(MVC.API.Plugin.InstallLocal(), FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#line default
#line hidden
WriteLiteral(" <label");
WriteLiteral(" for=\"pluginFile\"");
WriteLiteral(">Plugin Package: </label>\r\n");
WriteLiteral(" <input");
WriteLiteral(" id=\"pluginFile\"");
WriteLiteral(" name=\"Plugin\"");
WriteLiteral(" type=\"file\"");
WriteLiteral(" />\r\n");
#line 63 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n <div");
WriteLiteral(" style=\"padding: 0.7em 0.7em; margin-top: 8px;\"");
WriteLiteral(" class=\"ui-state-error ui-corner-all\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" style=\"margin-right: 0.3em; margin-bottom: 2em; float: left;\"");
WriteLiteral(" class=\"ui-icon ui-icon-alert\"");
WriteLiteral("></span>Warning: All plugins run with the same level of network privileges as the" +
" Disco Web App.<br />\r\n <strong>Only install plugins from a trusted sourc" +
"e.</strong>\r\n </div>\r\n</div>\r\n<script>\r\n $(function () {\r\n var $sel" +
"ectedPlugin;\r\n var $selectedPluginUrl;\r\n\r\n // Install\r\n var" +
" $dialogInstall = $(\'#dialogInstallPlugin\').dialog({\r\n resizable: fal" +
"se,\r\n modal: true,\r\n width: 350,\r\n autoOpen: fa" +
"lse,\r\n buttons: {\r\n \"Install\": function () {\r\n " +
" if ($selectedPlugin == null || !$selectedPluginUrl) {\r\n " +
" $(this).dialog(\"close\");\r\n return;\r\n " +
" }\r\n $(this).dialog(\"disable\");\r\n\r\n " +
" window.location.href = $selectedPluginUrl;\r\n },\r\n " +
" Cancel: function () {\r\n $selectedPlugin = null;\r\n " +
" $(this).dialog(\"close\");\r\n }\r\n }\r\n }" +
");\r\n $(\'#pageMenu\').find(\'a.pluginInstallLink\').click(function () {\r\n " +
" $this = $(this);\r\n\r\n $selectedPlugin = $this.closest(\'.plugin" +
"Item\');\r\n $selectedPluginUrl = $this.attr(\'href\');\r\n\r\n if " +
"($selectedPlugin.is(\'.pluginInstalled\')) {\r\n alert(\'This plugin i" +
"s already installed.\');\r\n } else {\r\n $(\'#dialogInstall" +
"PluginName\').text($selectedPlugin.find(\'.pluginName\').text());\r\n " +
"$(\'#dialogInstallPluginDetails\').text($selectedPlugin.find(\'.pluginId\').text() +" +
" \' | \' + $selectedPlugin.find(\'.pluginVersion\').text());\r\n\r\n $dia" +
"logInstall.dialog(\'open\');\r\n }\r\n return false;\r\n })" +
";\r\n\r\n // Upload\r\n var $dialogUpload = $(\'#dialogUploadPlugin\').dia" +
"log({\r\n resizable: false,\r\n modal: true,\r\n widt" +
"h: 350,\r\n autoOpen: false,\r\n buttons: {\r\n \"" +
"Upload & Install\": function () {\r\n var pluginFile = $(\'#plugi" +
"nFile\');\r\n if (pluginFile.val()) {\r\n p" +
"luginFile.closest(\'form\').submit();\r\n $(this).dialog(\'dis" +
"able\');\r\n } else {\r\n alert(\'Choose a P" +
"lugin Package to Upload\');\r\n }\r\n },\r\n " +
" Cancel: function () {\r\n $(this).dialog(\"close\");\r\n " +
" }\r\n }\r\n });\r\n $(\'#buttonUpload\').click(func" +
"tion () {\r\n $dialogUpload.dialog(\'open\');\r\n return false;\r" +
"\n });\r\n });\r\n</script>\r\n<div");
WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 142 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(Html.ActionLinkButton("Update Catalogue", MVC.API.Plugin.UpdateLibraryCatalogue()));
#line default
#line hidden
WriteLiteral("\r\n");
WriteLiteral(" ");
#line 143 "..\..\Areas\Config\Views\Plugins\Install.cshtml"
Write(Html.ActionLinkButton("Install Plugin Package", MVC.API.Plugin.InstallLocal(), "buttonUpload"));
#line default
#line hidden
WriteLiteral("\r\n</div>\r\n");
}
}
}
#pragma warning restore 1591
+75 -7
View File
@@ -1,15 +1,22 @@
.tableData { .tableData {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
border-collapse: collapse; border-collapse: collapse;
} }
.tableData td { .tableData > tbody > tr > td {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
background-color: #fff; background-color: #fff;
} }
.tableData th { .tableData > tbody > tr:nth-child(odd) > td {
background-color: #fcfcfd;
}
.tableData > thead > tr > th,
.tableData > tbody > tr > th {
background-color: #e8eef4; background-color: #e8eef4;
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
} }
.tableData > tbody > tr:hover > td {
background-color: #e8eef4;
}
.tableDataDark { .tableDataDark {
border: solid 1px #8db2d8; border: solid 1px #8db2d8;
border-collapse: collapse; border-collapse: collapse;
@@ -115,14 +122,21 @@ table.expressionsTable {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
border-collapse: collapse; border-collapse: collapse;
} }
table.expressionsTable td { table.expressionsTable > tbody > tr > td {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
background-color: #fff; background-color: #fff;
} }
table.expressionsTable th { table.expressionsTable > tbody > tr:nth-child(odd) > td {
background-color: #fcfcfd;
}
table.expressionsTable > thead > tr > th,
table.expressionsTable > tbody > tr > th {
background-color: #e8eef4; background-color: #e8eef4;
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
} }
table.expressionsTable > tbody > tr:hover > td {
background-color: #e8eef4;
}
table.expressionsTable td.parseError { table.expressionsTable td.parseError {
background-color: #FFD8D8; background-color: #FFD8D8;
} }
@@ -133,14 +147,21 @@ table.expressionsTable td.parseError {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
border-collapse: collapse; border-collapse: collapse;
} }
#deviceComponents td { #deviceComponents > tbody > tr > td {
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
background-color: #fff; background-color: #fff;
} }
#deviceComponents th { #deviceComponents > tbody > tr:nth-child(odd) > td {
background-color: #fcfcfd;
}
#deviceComponents > thead > tr > th,
#deviceComponents > tbody > tr > th {
background-color: #e8eef4; background-color: #e8eef4;
border: solid 1px #e8eef4; border: solid 1px #e8eef4;
} }
#deviceComponents > tbody > tr:hover > td {
background-color: #e8eef4;
}
#deviceComponents tr th.actions { #deviceComponents tr th.actions {
width: 20px; width: 20px;
} }
@@ -700,3 +721,50 @@ div.logEventsViewport table.logEventsViewport > tbody > tr > td.eventType {
width: 570px; width: 570px;
height: 200px; height: 200px;
} }
#plugins .pageMenuArea a > h3 {
display: inline;
color: #335a87;
}
#plugins .pageMenuArea a > h3:hover {
color: #4f81bd;
}
#pluginCatalog #pluginCatalogHeading {
margin-bottom: 20px;
text-align: right;
}
#pluginCatalog .pluginItem.pluginInstalled > a:first-child h2:after {
content: ' [Installed]';
font-size: .8em;
font-weight: bold;
}
#pluginCatalog .pluginItem .pluginItemBlurb {
margin: 4px 0 4px 2px;
padding: 0 4px;
border-left: 4px solid #e8eef4;
}
#pluginCatalog .pluginItem .pluginItemBlurb * {
padding: 0;
margin: 0;
}
#pluginCatalog .pluginItem > a:first-child {
padding-left: 30px;
background-image: url(data:image/png;base64,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 truncated
background-position: left center;
background-repeat: no-repeat;
min-height: 22px;
}
#pluginCatalog .pluginItem > a:first-child:hover {
background-image: url(data:image/png;base64,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 truncated
}
#pluginCatalog .pluginItem > a:first-child h2 {
display: inline;
color: #335a87;
}
#pluginCatalog .pluginItem > a:first-child h2:hover {
color: #4f81bd;
}
#pluginCatalog .pluginItem:not(.pluginInstalled) > a:first-child h2:hover:after {
font-size: .8em;
font-weight: bold;
content: ' < Install';
}
+93 -10
View File
@@ -14,16 +14,16 @@
#updateAvailableContainer #updateAvailableContainer
{ {
float: right; float: right;
border: 1px dashed #ddd; border: 1px dashed #ddd;
background-color: #fff; background-color: #fff;
line-height: 1.5em; line-height: 1.5em;
font-size: 0.6em; font-size: 0.6em;
padding: 4px 4px 4px 70px; padding: 4px 4px 4px 70px;
text-align: right; text-align: right;
height: 64px; height: 64px;
background-image: url(data:image/png;base64,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 truncated background-image: url(data:image/png;base64,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 truncated
background-position: 10px center; background-position: 10px center;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
#expressionEditor #expressionEditor
@@ -948,3 +948,86 @@ div.logEventsViewport
height: 200px; height: 200px;
} }
} }
// Plugins
#plugins
{
.pageMenuArea a > h3
{
display: inline;
color: @HyperLinkColour;
&:hover
{
color: @HyperLinkHoverColour;
}
}
}
#pluginCatalog
{
#pluginCatalogHeading
{
margin-bottom: 20px;
text-align: right;
}
.pluginItem
{
&.pluginInstalled > a:first-child h2:after
{
content: ' [Installed]';
font-size: .8em;
font-weight: bold;
}
.pluginItemBlurb
{
margin: 4px 0 4px 2px;
padding: 0 4px;
border-left: 4px solid @TableDataBorderColour;
*
{
padding: 0;
margin: 0;
}
}
&>a:first-child
{
padding-left: 30px;
background-image: url(data:image/png;base64,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 truncated
background-position: left center;
background-repeat: no-repeat;
min-height: 22px;
&:hover
{
background-image: url(data:image/png;base64,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 truncated
}
h2
{
display: inline;
color: @HyperLinkColour;
&:hover
{
color: @HyperLinkHoverColour;
}
}
}
&:not(.pluginInstalled)
{
&>a:first-child h2:hover:after
{
font-size: .8em;
font-weight: bold;
content: ' < Install';
}
}
}
}
+1 -1
View File
@@ -1 +1 @@
.tableData{border:solid 1px #e8eef4;border-collapse:collapse}.tableData td{border:solid 1px #e8eef4;background-color:#fff}.tableData th{background-color:#e8eef4;border:solid 1px #e8eef4}.tableDataDark{border:solid 1px #8db2d8;border-collapse:collapse}.tableDataDark td{border:solid 1px #8db2d8;background-color:#fff}.tableDataDark th{background-color:#8db2d8;border:solid 1px #8db2d8}.tableDataContainer{background-color:#fff}.tableDataVertical{border:solid 1px #e8eef4;border-collapse:collapse}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#e8eef4;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}#pageMenu td .pageMenuArea>a.config{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACsElEQVQ4y41T3UtTcRie3QaNRhKC/4SgN4KBeSGK4EAvuzChNZQSvJgXYldCV5tMiUzEDVuZ84M0P4OmpjO3lV+bs21nH2fnbGd69mFuMz/39DunFsUadODh/Hj5vc/zPu/7/iQAJP9CQ0NDrU6nO9Lr9YnS0tKqfPdyAoODg7daWlpuqFQqYyyeQDKVQmdnp6G9vf26RqO5nZfAYDC0vZ2ezuj0es5oHEuGuQhCYQ7RWAznFxeYmpo6fmkwcCaTKfO8v1/5F4FMJrv26vUIQ7MhxOJxEYc8DzrIgItEcHB4iONkEql0Gqdn5xgdHfXnVFBXV6cNkATK54M/QMNm+4yPq2vY3NqCl8QSR0ci0icnqK6ufppDoO3t3fSRROe+C/PzCyKJ3e64CjLslZC0tLyMyMHPSjQ9PZbfBEqlslar1fIut/uS8vpgtdoQCoVB/NJSqVReWFh4b2FxkY8SW0JVQl88FHXZ19fHl5eXV0kqK++qInwU+y43duwOrJnXQVE+1NfLn2RVHigUAx7KC/P6BulLEH6aJs2No6LiTpukrKzsEcOy2HN+xfbOLlbXzOCjMajV6vdZgiGd7oswlZnZOdj3nAjQhCQQQElJiUJCPmlTU9MsGR1H/GJre0ds1uTkJEZG3nwzGo3HY+Pj4jSsNhu8/gD0w8OskCPk/rl5z1LpE7DE/wfTkjjGXWLJQRRpovhuZgYO5z4pP4iamhp1zhS6u7u572dniCcScHs8sFisWN+w4NMvWIi6QB4ku9LV1RXKIVB1dJjJX1iiDNm+TJjjRL+CqrAfRDlDFusqHDlAa2vrSg6B4KexsXGiqKjofnFx8WNSxalfbBYNyutNkvhDElfI5fIJ4W7ex5TFi4EBF0umwzAMmpubV/77NWZRUFAgI52eE0DON/Pd+wH6O+vw3ozilAAAAABJRU5ErkJggg==)}#pageMenu td .pageMenuArea>a.config:hover{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACiElEQVQ4y41Ta0iTYRQe/ShCTCpJiiRIKvtTiUE3+2VRiMR+JEk3ktKMslmGJZVEf1aZhpFFS/uRQ7Jcq2jVKvKCu2S66eZl05zu5qd9m+5i28TtO73njYXyNeiDw/dyOOc5z3me9xUAgOBfUXYgNUv3+JxH/0Q0lZ22MjNWHS/R9agwsfZU+hL5hZ0vAi4HhLwsKC5lSBuLtsepbx9MignQ/bRENCC7xekkRYyx4brf6zCB194Pv1gbhGeCMNAk9pEaZlgp4Tru5xXOA0hKWLSg59kVu8dqBJyK4R+3wJSlG3xOM/iZHxD0TEDI54LZ4DQYpFdHeAyK96+rxgb3YAdMDevBoZXDaHM9jH1/R3MBt5PGjH8SzmSmiHkAmru5Omz8aWyGwbf3KAijV0YIqwg2WT7XgW9siDJR38n59hdAcjI9S1NxiGX728M4ya5uAo+tF8i+1sT4hcLk5YuPDikesLgWskJdXCZNWFt1hM3ZtjpTcDxjTen0xAiwfW04EUZbpOA2a6Eka315dMrDE2kS0gTWtgaqC7JDcXN3JIsExOMinIjUGd1HCoCA7WLhpygAuQ9d6Ir5TRWM93yhABj7NiUVCMiXUHl4s4JYx6ALTNcHKlZf400w1Jd5Sd7X+/wGdcOueQWTQ52gry12YA/2zr15NWgTsiFeUxtxpQnDVzrNJK+gLPF8dm9KJc+FlvI9zGzAR++Aa0AFNtXLeYHTERxDeXm3kwfw+uIuFReJIABHBOJwZ9yXTv0jHEf+EczX5W9t5QHgPteEG2VrV8Tlpa6KP09YhKJiEVf8JH+a5AtKszfIsDbmY4pGZ02+mVImwlYf29L6369xDqNlROn3GOS8NFbdbzB85s9H8NGVAAAAAElFTkSuQmCC)}#updateAvailableContainer{float:right;border:1px dashed #ddd;background-color:#fff;line-height:1.5em;font-size:.6em;padding:4px 4px 4px 70px;text-align:right;height:64px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADEAAABACAYAAACz4p94AAAVPUlEQVRo3s2aWaxk13Wev7X3PkONd+6+PQ+cmoNItkha4iCYtBVLpGQ7MkQ78EMICBZt+EFAAENMgAAKkAQInYcEQR6Sl8AKHE1OBBkg2YJFKS0O8iCSgimymyLZTXY3e+471q1bVWfYKw/7nLrVDCkDQQNhNQ7OrdNVe69/Tf9aa5dwLV+P/ycOuE1z8fxZKaa2U4pQYkEBY0m3tZk79pKePXbc8/ZPrtm27pqscvfn4aWnYO+exq5WvqCptUOXMHAJmYkZFYpzMfO7usysnSnOvnnqIpB9tEC89BQArW5zenpK7ugPB+nQRLRtQm4tK3lJZCKmui1ttFt9Ytf76IGoXs00WUib9oHp6dlOZoyU4siNxY9KrHV0Gw1Va5dw9nVg9SMJIo3jxTSJPjnXbc8UYqWwjhzDMCmxxtFsNXQTvUDkvguc/kiCEGsX4ii6ud3tTJXGUIhjKJbesERcRLedMvB+Gmu713LfawoC9Q1nbDrTdHFpHKWxbIil5RTjItrNhEtIijWNjyyIIi8iI0g3TSisozQOVUPTCDZKaDYjBBVEoo8siOFoJKinncTk1lLaiEwtqXNESUI3teABMeYjC2IwGIovSpqxIzeO0jr6RKQupptEbIs8AmBEP7og+hv4vCB2DmsdhYtwGtHEMR8J2xyIEhj8IxvYvR5lNsIaQYxBjMFhaakw42C23k2uLYhr6ptcPJ8x3FQjghXBVEASK7Ss0A67KSvr2TW1xF9897uRM/aPW63mnla7U7Zb7bC5UN0FEETkqmfhOUglrBHDn3z32cM220yCpDJWuAGsASuQRK79L77y2Jef+Mf/40EFUdlaQyb2kbAZBkFRijwnyzLyoiDPMrJwRXme/5UzmEjEfBkxtwqCMeHaEnTr76ufT2wuAqIcmmlxYZDhvWppVEpVCpQcyD1kHk0i17hp1/bfCZKCqdarARgRMBPPjCAalBeAMt5bVVHV0llr1BjJjAhxHBEnCda6qzRvEMSAiA2LimDEhA3HloDIOWBEXnopjacsPUP19MXQK6HnEUWI4pi02awiPAgKEnxbggWlAmOqTxljq2ASvCp5ntcgCmeMwVpLmjb43z/8AUl+kZgMjEHiGfCKiWJwCUWRUSKIsYhmCAXYFCmGiHpeO9OnffAuhmVJQYliGPmCnhiuGEvHwWiwyQ/+15+z9uPv4FUxrS6MelDm+NYUuBhrLNYlaL+HZhkap2AU1ZCieyPLdTffwaFDN6GqODGVyQRmZ2f4/V/7OKkbgFho7YM8g7QFaYdvP3+MYxeWKLMR4kugBBOD5qhXfvOR69HWHFfyAu+FUmHolT5wxSSkubB9cZ5z76zyzsJ1eO+RRgufD1Atybylt3yFe67byR/93iOwdB42N6E9HfKoehDLL05c5u9PXkZV8ao4U7mGmOAew9GIxOeABzsMILBkuXDiSo+p3TsYnrpC7j02jiFK8HEoM664Kdpxh41hTmkVXyr9smCoJasopcbc8IV/ip69xFkxlB5GvmRQKFnpaLine truncated .tableData{border:solid 1px #e8eef4;border-collapse:collapse}.tableData>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}.tableData>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}.tableData>tbody>tr:hover>td{background-color:#e8eef4}.tableDataDark{border:solid 1px #8db2d8;border-collapse:collapse}.tableDataDark td{border:solid 1px #8db2d8;background-color:#fff}.tableDataDark th{background-color:#8db2d8;border:solid 1px #8db2d8}.tableDataContainer{background-color:#fff}.tableDataVertical{border:solid 1px #e8eef4;border-collapse:collapse}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#e8eef4;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}#pageMenu td .pageMenuArea>a.config{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACsElEQVQ4y41T3UtTcRie3QaNRhKC/4SgN4KBeSGK4EAvuzChNZQSvJgXYldCV5tMiUzEDVuZ84M0P4OmpjO3lV+bs21nH2fnbGd69mFuMz/39DunFsUadODh/Hj5vc/zPu/7/iQAJP9CQ0NDrU6nO9Lr9YnS0tKqfPdyAoODg7daWlpuqFQqYyyeQDKVQmdnp6G9vf26RqO5nZfAYDC0vZ2ezuj0es5oHEuGuQhCYQ7RWAznFxeYmpo6fmkwcCaTKfO8v1/5F4FMJrv26vUIQ7MhxOJxEYc8DzrIgItEcHB4iONkEql0Gqdn5xgdHfXnVFBXV6cNkATK54M/QMNm+4yPq2vY3NqCl8QSR0ci0icnqK6ufppDoO3t3fSRROe+C/PzCyKJ3e64CjLslZC0tLyMyMHPSjQ9PZbfBEqlslar1fIut/uS8vpgtdoQCoVB/NJSqVReWFh4b2FxkY8SW0JVQl88FHXZ19fHl5eXV0kqK++qInwU+y43duwOrJnXQVE+1NfLn2RVHigUAx7KC/P6BulLEH6aJs2No6LiTpukrKzsEcOy2HN+xfbOLlbXzOCjMajV6vdZgiGd7oswlZnZOdj3nAjQhCQQQElJiUJCPmlTU9MsGR1H/GJre0ds1uTkJEZG3nwzGo3HY+Pj4jSsNhu8/gD0w8OskCPk/rl5z1LpE7DE/wfTkjjGXWLJQRRpovhuZgYO5z4pP4iamhp1zhS6u7u572dniCcScHs8sFisWN+w4NMvWIi6QB4ku9LV1RXKIVB1dJjJX1iiDNm+TJjjRL+CqrAfRDlDFusqHDlAa2vrSg6B4KexsXGiqKjofnFx8WNSxalfbBYNyutNkvhDElfI5fIJ4W7ex5TFi4EBF0umwzAMmpubV/77NWZRUFAgI52eE0DON/Pd+wH6O+vw3ozilAAAAABJRU5ErkJggg==)}#pageMenu td .pageMenuArea>a.config:hover{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACiElEQVQ4y41Ta0iTYRQe/ShCTCpJiiRIKvtTiUE3+2VRiMR+JEk3ktKMslmGJZVEf1aZhpFFS/uRQ7Jcq2jVKvKCu2S66eZl05zu5qd9m+5i28TtO73njYXyNeiDw/dyOOc5z3me9xUAgOBfUXYgNUv3+JxH/0Q0lZ22MjNWHS/R9agwsfZU+hL5hZ0vAi4HhLwsKC5lSBuLtsepbx9MignQ/bRENCC7xekkRYyx4brf6zCB194Pv1gbhGeCMNAk9pEaZlgp4Tru5xXOA0hKWLSg59kVu8dqBJyK4R+3wJSlG3xOM/iZHxD0TEDI54LZ4DQYpFdHeAyK96+rxgb3YAdMDevBoZXDaHM9jH1/R3MBt5PGjH8SzmSmiHkAmru5Omz8aWyGwbf3KAijV0YIqwg2WT7XgW9siDJR38n59hdAcjI9S1NxiGX728M4ya5uAo+tF8i+1sT4hcLk5YuPDikesLgWskJdXCZNWFt1hM3ZtjpTcDxjTen0xAiwfW04EUZbpOA2a6Eka315dMrDE2kS0gTWtgaqC7JDcXN3JIsExOMinIjUGd1HCoCA7WLhpygAuQ9d6Ir5TRWM93yhABj7NiUVCMiXUHl4s4JYx6ALTNcHKlZf400w1Jd5Sd7X+/wGdcOueQWTQ52gry12YA/2zr15NWgTsiFeUxtxpQnDVzrNJK+gLPF8dm9KJc+FlvI9zGzAR++Aa0AFNtXLeYHTERxDeXm3kwfw+uIuFReJIABHBOJwZ9yXTv0jHEf+EczX5W9t5QHgPteEG2VrV8Tlpa6KP09YhKJiEVf8JH+a5AtKszfIsDbmY4pGZ02+mVImwlYf29L6369xDqNlROn3GOS8NFbdbzB85s9H8NGVAAAAAElFTkSuQmCC)}#updateAvailableContainer{float:right;border:1px dashed #ddd;background-color:#fff;line-height:1.5em;font-size:.6em;padding:4px 4px 4px 70px;text-align:right;height:64px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADEAAABACAYAAACz4p94AAAVPUlEQVRo3s2aWaxk13Wev7X3PkONd+6+PQ+cmoNItkha4iCYtBVLpGQ7MkQ78EMICBZt+EFAAENMgAAKkAQInYcEQR6Sl8AKHE1OBBkg2YJFKS0O8iCSgimymyLZTXY3e+471q1bVWfYKw/7nLrVDCkDQQNhNQ7OrdNVe69/Tf9aa5dwLV+P/ycOuE1z8fxZKaa2U4pQYkEBY0m3tZk79pKePXbc8/ZPrtm27pqscvfn4aWnYO+exq5WvqCptUOXMHAJmYkZFYpzMfO7usysnSnOvnnqIpB9tEC89BQArW5zenpK7ugPB+nQRLRtQm4tK3lJZCKmui1ttFt9Ytf76IGoXs00WUib9oHp6dlOZoyU4siNxY9KrHV0Gw1Va5dw9nVg9SMJIo3jxTSJPjnXbc8UYqWwjhzDMCmxxtFsNXQTvUDkvguc/kiCEGsX4ii6ud3tTJXGUIhjKJbesERcRLedMvB+Gmu713LfawoC9Q1nbDrTdHFpHKWxbIil5RTjItrNhEtIijWNjyyIIi8iI0g3TSisozQOVUPTCDZKaDYjBBVEoo8siOFoJKinncTk1lLaiEwtqXNESUI3teABMeYjC2IwGIovSpqxIzeO0jr6RKQupptEbIs8AmBEP7og+hv4vCB2DmsdhYtwGtHEMR8J2xyIEhj8IxvYvR5lNsIaQYxBjMFhaakw42C23k2uLYhr6ptcPJ8x3FQjghXBVEASK7Ss0A67KSvr2TW1xF9897uRM/aPW63mnla7U7Zb7bC5UN0FEETkqmfhOUglrBHDn3z32cM220yCpDJWuAGsASuQRK79L77y2Jef+Mf/40EFUdlaQyb2kbAZBkFRijwnyzLyoiDPMrJwRXme/5UzmEjEfBkxtwqCMeHaEnTr76ufT2wuAqIcmmlxYZDhvWppVEpVCpQcyD1kHk0i17hp1/bfCZKCqdarARgRMBPPjCAalBeAMt5bVVHV0llr1BjJjAhxHBEnCda6qzRvEMSAiA2LimDEhA3HloDIOWBEXnopjacsPUP19MXQK6HnEUWI4pi02awiPAgKEnxbggWlAmOqTxljq2ASvCp5ntcgCmeMwVpLmjb43z/8AUl+kZgMjEHiGfCKiWJwCUWRUSKIsYhmCAXYFCmGiHpeO9OnffAuhmVJQYliGPmCnhiuGEvHwWiwyQ/+15+z9uPv4FUxrS6MelDm+NYUuBhrLNYlaL+HZhkap2AU1ZCieyPLdTffwaFDN6GqODGVyQRmZ2f4/V/7OKkbgFho7YM8g7QFaYdvP3+MYxeWKLMR4kugBBOD5qhXfvOR69HWHFfyAu+FUmHolT5wxSSkubB9cZ5z76zyzsJ1eO+RRgufD1AtLine truncated
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+12 -2
View File
@@ -164,6 +164,12 @@
</Compile> </Compile>
<Compile Include="Areas\API\Controllers\PluginController.cs" /> <Compile Include="Areas\API\Controllers\PluginController.cs" />
<Compile Include="Areas\Config\Models\Config\IndexModel.cs" /> <Compile Include="Areas\Config\Models\Config\IndexModel.cs" />
<Compile Include="Areas\Config\Models\Plugins\InstallModel.cs" />
<Compile Include="Areas\Config\Views\Plugins\Install.generated.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Install.cshtml</DependentUpon>
</Compile>
<Compile Include="Controllers\InitialConfigController.cs" /> <Compile Include="Controllers\InitialConfigController.cs" />
<Compile Include="Controllers\PluginWebHandlerController.cs" /> <Compile Include="Controllers\PluginWebHandlerController.cs" />
<Compile Include="Extensions\HtmlExtensions.cs" /> <Compile Include="Extensions\HtmlExtensions.cs" />
@@ -240,7 +246,7 @@
<Compile Include="Areas\Config\Models\Logging\TaskStatusModel.cs" /> <Compile Include="Areas\Config\Models\Logging\TaskStatusModel.cs" />
<Compile Include="Areas\Config\Models\Organisation\IndexModel.cs" /> <Compile Include="Areas\Config\Models\Organisation\IndexModel.cs" />
<Compile Include="Areas\Config\Models\Plugins\IndexViewModel.cs" /> <Compile Include="Areas\Config\Models\Plugins\IndexViewModel.cs" />
<Compile Include="Areas\Config\Models\Plugins\ProviderConfigurationViewModel.cs" /> <Compile Include="Areas\Config\Models\Plugins\PluginConfigurationViewModel.cs" />
<Compile Include="Areas\Config\Models\Shared\LogEventsModel.cs" /> <Compile Include="Areas\Config\Models\Shared\LogEventsModel.cs" />
<Compile Include="Areas\Config\Models\SystemConfig\IndexModel.cs" /> <Compile Include="Areas\Config\Models\SystemConfig\IndexModel.cs" />
<Compile Include="Areas\Config\Views\Config\Index.generated.cs"> <Compile Include="Areas\Config\Views\Config\Index.generated.cs">
@@ -743,6 +749,10 @@
<ItemGroup> <ItemGroup>
<Content Include="ClientBin\Disco.ClientBootstrapper.exe" /> <Content Include="ClientBin\Disco.ClientBootstrapper.exe" />
<Content Include="ClientBin\Disco.Silverlight.AttachmentUpload.xap" /> <Content Include="ClientBin\Disco.Silverlight.AttachmentUpload.xap" />
<None Include="Areas\Config\Views\Plugins\Install.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Install.generated.cs</LastGenOutput>
</None>
<None Include="ClientSource\Scripts\Core.min.js.map"> <None Include="ClientSource\Scripts\Core.min.js.map">
<DependentUpon>Core.js.bundle</DependentUpon> <DependentUpon>Core.js.bundle</DependentUpon>
</None> </None>
@@ -1812,7 +1822,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties> </WebProjectProperties>
</FlavorProperties> </FlavorProperties>
<UserProperties BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="True" BuildVersion_BuildAction="ReBuild" BuildVersion_StartDate="2001/1/1" /> <UserProperties BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" />
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" /> <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+2 -2
View File
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// //
// You can specify all the values or you can default the Revision and Build Numbers // You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.2.0208.1156")] [assembly: AssemblyVersion("1.2.0212.1702")]
[assembly: AssemblyFileVersion("1.2.0208.1156")] [assembly: AssemblyFileVersion("1.2.0212.1702")]
+44 -3
View File
@@ -6767,6 +6767,12 @@ namespace Disco.Web.Areas.API.Controllers
} }
[NonAction] [NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public System.Web.Mvc.ActionResult InstallLocal()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.InstallLocal);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public System.Web.Mvc.ActionResult Install() public System.Web.Mvc.ActionResult Install()
{ {
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Install); return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Install);
@@ -6787,14 +6793,18 @@ namespace Disco.Web.Areas.API.Controllers
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNamesClass public class ActionNamesClass
{ {
public readonly string UpdateLibraryCatalogue = "UpdateLibraryCatalogue";
public readonly string Uninstall = "Uninstall"; public readonly string Uninstall = "Uninstall";
public readonly string InstallLocal = "InstallLocal";
public readonly string Install = "Install"; public readonly string Install = "Install";
} }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNameConstants public class ActionNameConstants
{ {
public const string UpdateLibraryCatalogue = "UpdateLibraryCatalogue";
public const string Uninstall = "Uninstall"; public const string Uninstall = "Uninstall";
public const string InstallLocal = "InstallLocal";
public const string Install = "Install"; public const string Install = "Install";
} }
@@ -6808,13 +6818,21 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string id = "id"; public readonly string id = "id";
public readonly string UninstallData = "UninstallData"; public readonly string UninstallData = "UninstallData";
} }
static readonly ActionParamsClass_InstallLocal s_params_InstallLocal = new ActionParamsClass_InstallLocal();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_InstallLocal InstallLocalParams { get { return s_params_InstallLocal; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_InstallLocal
{
public readonly string Plugin = "Plugin";
}
static readonly ActionParamsClass_Install s_params_Install = new ActionParamsClass_Install(); static readonly ActionParamsClass_Install s_params_Install = new ActionParamsClass_Install();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Install InstallParams { get { return s_params_Install; } } public ActionParamsClass_Install InstallParams { get { return s_params_Install; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Install public class ActionParamsClass_Install
{ {
public readonly string Plugin = "Plugin"; public readonly string PluginId = "PluginId";
} }
static readonly ViewsClass s_views = new ViewsClass(); static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -6835,6 +6853,12 @@ namespace Disco.Web.Areas.API.Controllers
{ {
public T4MVC_PluginController() : base(Dummy.Instance) { } public T4MVC_PluginController() : base(Dummy.Instance) { }
public override System.Web.Mvc.ActionResult UpdateLibraryCatalogue()
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateLibraryCatalogue);
return callInfo;
}
public override System.Web.Mvc.ActionResult Uninstall(string id, bool UninstallData) public override System.Web.Mvc.ActionResult Uninstall(string id, bool UninstallData)
{ {
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Uninstall); var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Uninstall);
@@ -6843,10 +6867,17 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo; return callInfo;
} }
public override System.Web.Mvc.ActionResult Install(System.Web.HttpPostedFileBase Plugin) public override System.Web.Mvc.ActionResult InstallLocal(System.Web.HttpPostedFileBase Plugin)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.InstallLocal);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Plugin", Plugin);
return callInfo;
}
public override System.Web.Mvc.ActionResult Install(string PluginId)
{ {
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Install); var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Install);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Plugin", Plugin); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "PluginId", PluginId);
return callInfo; return callInfo;
} }
@@ -8369,6 +8400,7 @@ namespace Disco.Web.Areas.Config.Controllers
{ {
public readonly string Index = "Index"; public readonly string Index = "Index";
public readonly string Configure = "Configure"; public readonly string Configure = "Configure";
public readonly string Install = "Install";
} }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -8376,6 +8408,7 @@ namespace Disco.Web.Areas.Config.Controllers
{ {
public const string Index = "Index"; public const string Index = "Index";
public const string Configure = "Configure"; public const string Configure = "Configure";
public const string Install = "Install";
} }
@@ -8400,9 +8433,11 @@ namespace Disco.Web.Areas.Config.Controllers
{ {
public readonly string Configure = "Configure"; public readonly string Configure = "Configure";
public readonly string Index = "Index"; public readonly string Index = "Index";
public readonly string Install = "Install";
} }
public readonly string Configure = "~/Areas/Config/Views/Plugins/Configure.cshtml"; public readonly string Configure = "~/Areas/Config/Views/Plugins/Configure.cshtml";
public readonly string Index = "~/Areas/Config/Views/Plugins/Index.cshtml"; public readonly string Index = "~/Areas/Config/Views/Plugins/Index.cshtml";
public readonly string Install = "~/Areas/Config/Views/Plugins/Install.cshtml";
} }
} }
@@ -8432,6 +8467,12 @@ namespace Disco.Web.Areas.Config.Controllers
return callInfo; return callInfo;
} }
public override System.Web.Mvc.ActionResult Install()
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Install);
return callInfo;
}
} }
} }