Merge
This commit is contained in:
commit
ff598eaad2
39 changed files with 995 additions and 86 deletions
|
@ -1,5 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WebsitePanel.EnterpriseServer.Base.HostedSolution;
|
||||
using WebsitePanel.WebDav.Core.Config.WebConfigSections;
|
||||
using WebsitePanel.WebDavPortal.WebConfigSections;
|
||||
|
||||
namespace WebsitePanel.WebDav.Core.Config.Entities
|
||||
|
@ -33,6 +35,26 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
|
|||
}
|
||||
}
|
||||
|
||||
public string UserGroupsKey
|
||||
{
|
||||
get
|
||||
{
|
||||
SessionKeysElement sessionKey =
|
||||
_sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.UserGroupsKey);
|
||||
return sessionKey != null ? sessionKey.Value : null;
|
||||
}
|
||||
}
|
||||
|
||||
public string WebDavRootFoldersPermissions
|
||||
{
|
||||
get
|
||||
{
|
||||
SessionKeysElement sessionKey =
|
||||
_sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.WebDavRootFolderPermissionsKey);
|
||||
return sessionKey != null ? sessionKey.Value : null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ResourseRenderCount
|
||||
{
|
||||
get
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System.Configuration;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.WebConfigSections
|
||||
namespace WebsitePanel.WebDav.Core.Config.WebConfigSections
|
||||
{
|
||||
public class SessionKeysElement : ConfigurationElement
|
||||
{
|
||||
|
@ -10,6 +10,8 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
|
|||
public const string AccountInfoKey = "AccountInfoSessionKey";
|
||||
public const string AuthTicketKey = "AuthTicketKey";
|
||||
public const string WebDavManagerKey = "WebDavManagerSessionKey";
|
||||
public const string UserGroupsKey = "UserGroupsKey";
|
||||
public const string WebDavRootFolderPermissionsKey = "WebDavRootFolderPermissionsKey";
|
||||
public const string ResourseRenderCountKey = "ResourseRenderCountSessionKey";
|
||||
public const string ItemIdSessionKey = "ItemId";
|
||||
|
||||
|
|
|
@ -4,5 +4,19 @@ namespace WebsitePanel.WebDav.Core.Exceptions
|
|||
{
|
||||
public class WebDavException : Exception
|
||||
{
|
||||
public WebDavException()
|
||||
: base() { }
|
||||
|
||||
public WebDavException(string message)
|
||||
: base(message) { }
|
||||
|
||||
public WebDavException(string format, params object[] args)
|
||||
: base(string.Format(format, args)) { }
|
||||
|
||||
public WebDavException(string message, Exception innerException)
|
||||
: base(message, innerException) { }
|
||||
|
||||
public WebDavException(string format, Exception innerException, params object[] args)
|
||||
: base(string.Format(format, args), innerException) { }
|
||||
}
|
||||
}
|
|
@ -148,7 +148,7 @@ namespace WebsitePanel.WebDav.Core
|
|||
public IResource GetResource(string name)
|
||||
{
|
||||
IHierarchyItem item =
|
||||
_children.Single(i => i.ItemType == ItemType.Resource && i.DisplayName.Trim('/') == name.Trim('/'));
|
||||
_children.Single(i => i.DisplayName.Trim('/') == name.Trim('/'));
|
||||
var resource = new WebDavResource();
|
||||
resource.SetCredentials(_credentials);
|
||||
resource.SetHierarchyItem(item);
|
||||
|
|
|
@ -428,6 +428,15 @@ namespace WebsitePanel.WebDav.Core
|
|||
_lastModified = lastModified;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
/// <param name="comment"></param>
|
||||
public void SetItemType(ItemType type)
|
||||
{
|
||||
_itemType = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
|
@ -541,6 +550,7 @@ namespace WebsitePanel.WebDav.Core
|
|||
SetHref(item.Href);
|
||||
SetLastModified(item.LastModified);
|
||||
SetProperties(item.Properties);
|
||||
SetItemType(item.ItemType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,6 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Managers
|
|||
void UploadFile(string path, HttpPostedFileBase file);
|
||||
IResource GetResource(string path);
|
||||
string GetFileUrl(string path);
|
||||
void DeleteResource(string path);
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ using WebsitePanel.WebDav.Core.Config;
|
|||
using WebsitePanel.WebDav.Core.Exceptions;
|
||||
using WebsitePanel.WebDav.Core.Extensions;
|
||||
using WebsitePanel.WebDav.Core.Interfaces.Managers;
|
||||
using WebsitePanel.WebDav.Core.Resources;
|
||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||
using WebsitePanel.WebDav.Core.Wsp.Framework;
|
||||
|
||||
|
@ -70,7 +71,7 @@ namespace WebsitePanel.WebDav.Core.Managers
|
|||
_cryptography.Decrypt(WspContext.User.EncryptedPassword),
|
||||
WebDavAppConfigManager.Instance.UserDomain);
|
||||
|
||||
_currentFolder = _webDavSession.OpenFolder(string.Format("{0}{1}/{2}", WebDavAppConfigManager.Instance.WebdavRoot, WspContext.User.OrganizationId, pathPart));
|
||||
_currentFolder = _webDavSession.OpenFolder(string.Format("{0}{1}/{2}", WebDavAppConfigManager.Instance.WebdavRoot, WspContext.User.OrganizationId, pathPart.TrimStart('/')));
|
||||
}
|
||||
|
||||
children = _currentFolder.GetChildren().Where(x => !WebDavAppConfigManager.Instance.ElementsRendering.ElementsToIgnore.Contains(x.DisplayName.Trim('/'))).ToArray();
|
||||
|
@ -95,15 +96,9 @@ namespace WebsitePanel.WebDav.Core.Managers
|
|||
|
||||
OpenFolder(folder);
|
||||
|
||||
try
|
||||
{
|
||||
IResource resource = _currentFolder.GetResource(resourceName);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e){}
|
||||
|
||||
return false;
|
||||
return resource.ItemType != ItemType.Folder;
|
||||
}
|
||||
|
||||
|
||||
|
@ -148,6 +143,27 @@ namespace WebsitePanel.WebDav.Core.Managers
|
|||
resource.Upload(bytes);
|
||||
}
|
||||
|
||||
public void DeleteResource(string path)
|
||||
{
|
||||
path = RemoveLeadingFromPath(path, "office365");
|
||||
path = RemoveLeadingFromPath(path, WspContext.User.OrganizationId);
|
||||
|
||||
string folderPath = GetFileFolder(path);
|
||||
|
||||
OpenFolder(folderPath);
|
||||
|
||||
var resourceName = GetResourceName(path);
|
||||
|
||||
IResource resource = _currentFolder.GetResource(resourceName);
|
||||
|
||||
if (resource.ItemType == ItemType.Folder && GetFoldersItemsCount(path) > 0)
|
||||
{
|
||||
throw new WebDavException(string.Format(WebDavResources.FolderIsNotEmptyFormat, resource.DisplayName));
|
||||
}
|
||||
|
||||
resource.Delete();
|
||||
}
|
||||
|
||||
public IResource GetResource(string path)
|
||||
{
|
||||
try
|
||||
|
@ -210,8 +226,20 @@ namespace WebsitePanel.WebDav.Core.Managers
|
|||
return rootFolders;
|
||||
}
|
||||
|
||||
private int GetFoldersItemsCount(string path)
|
||||
{
|
||||
var items = OpenFolder(path);
|
||||
|
||||
return items.Count();
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private string RemoveLeadingFromPath(string pathPart, string toRemove)
|
||||
{
|
||||
return pathPart.StartsWith('/' + toRemove) ? pathPart.Substring(toRemove.Length + 1) : pathPart;
|
||||
}
|
||||
|
||||
private byte[] ReadFully(Stream input)
|
||||
{
|
||||
var buffer = new byte[16 * 1024];
|
||||
|
|
72
WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/WebDavResources.Designer.cs
generated
Normal file
72
WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/WebDavResources.Designer.cs
generated
Normal file
|
@ -0,0 +1,72 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.33440
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WebsitePanel.WebDav.Core.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class WebDavResources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal WebDavResources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WebsitePanel.WebDav.Core.Resources.WebDavResources", typeof(WebDavResources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Folder {0} is not empty..
|
||||
/// </summary>
|
||||
internal static string FolderIsNotEmptyFormat {
|
||||
get {
|
||||
return ResourceManager.GetString("FolderIsNotEmptyFormat", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="FolderIsNotEmptyFormat" xml:space="preserve">
|
||||
<value>Folder {0} is not empty.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,5 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using WebsitePanel.EnterpriseServer.Base.HostedSolution;
|
||||
using WebsitePanel.Providers.HostedSolution;
|
||||
using WebsitePanel.WebDav.Core.Config;
|
||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||
using WebsitePanel.WebDav.Core.Security.Authentication.Principals;
|
||||
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
|
||||
|
@ -27,18 +32,9 @@ namespace WebsitePanel.WebDav.Core.Security.Authorization
|
|||
|
||||
var rootFolder = GetRootFolder(path);
|
||||
|
||||
var userGroups = WSP.Services.Organizations.GetSecurityGroupsByMember(principal.ItemId, principal.AccountId);
|
||||
var userGroups = GetUserSecurityGroups(principal);
|
||||
|
||||
var rootFolders = WSP.Services.EnterpriseStorage.GetEnterpriseFolders(principal.ItemId);
|
||||
|
||||
var esRootFolder = rootFolders.FirstOrDefault(x => x.Name == rootFolder);
|
||||
|
||||
if (esRootFolder == null)
|
||||
{
|
||||
return WebDavPermissions.None;
|
||||
}
|
||||
|
||||
var permissions = WSP.Services.EnterpriseStorage.GetEnterpriseFolderPermissions(principal.ItemId, esRootFolder.Name);
|
||||
var permissions = GetFolderEsPermissions(principal, rootFolder);
|
||||
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
|
@ -65,5 +61,44 @@ namespace WebsitePanel.WebDav.Core.Security.Authorization
|
|||
{
|
||||
return path.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||
}
|
||||
|
||||
private IEnumerable<ESPermission> GetFolderEsPermissions(WspPrincipal principal, string rootFolderName)
|
||||
{
|
||||
var dictionary = HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.WebDavRootFoldersPermissions] as
|
||||
Dictionary<string, IEnumerable<ESPermission>>;
|
||||
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<string, IEnumerable<ESPermission>>();
|
||||
|
||||
var rootFolders = WSP.Services.EnterpriseStorage.GetEnterpriseFolders(principal.ItemId);
|
||||
|
||||
foreach (var rootFolder in rootFolders)
|
||||
{
|
||||
var permissions = WSP.Services.EnterpriseStorage.GetEnterpriseFolderPermissions(principal.ItemId, rootFolder.Name);
|
||||
|
||||
dictionary.Add(rootFolder.Name, permissions);
|
||||
}
|
||||
|
||||
HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.WebDavRootFoldersPermissions] = dictionary;
|
||||
}
|
||||
|
||||
return dictionary.ContainsKey(rootFolderName) ? dictionary[rootFolderName] : new ESPermission[0];
|
||||
}
|
||||
|
||||
private IEnumerable<ExchangeAccount> GetUserSecurityGroups(WspPrincipal principal)
|
||||
{
|
||||
var groups = HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.UserGroupsKey] as
|
||||
IEnumerable<ExchangeAccount>;
|
||||
|
||||
if (groups == null)
|
||||
{
|
||||
groups = WSP.Services.Organizations.GetSecurityGroupsByMember(principal.ItemId, principal.AccountId);
|
||||
|
||||
HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.UserGroupsKey] = groups;
|
||||
}
|
||||
|
||||
return groups ?? new ExchangeAccount[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -147,6 +147,11 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>HttpErrors.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Resources\WebDavResources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>WebDavResources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Security\Authorization\Enums\WebDavPermissions.cs" />
|
||||
<Compile Include="Security\Authorization\WebDavAuthorizationService.cs" />
|
||||
<Compile Include="Security\Cryptography\CryptoUtils.cs" />
|
||||
|
@ -175,6 +180,10 @@
|
|||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>HttpErrors.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\WebDavResources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>WebDavResources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
|
|
|
@ -27,7 +27,11 @@ namespace WebsitePanel.WebDavPortal
|
|||
"~/Scripts/appScripts/recalculateResourseHeight.js",
|
||||
"~/Scripts/appScripts/uploadingData2.js",
|
||||
"~/Scripts/appScripts/authentication.js",
|
||||
"~/Scripts/appScripts/dialogs.js"));
|
||||
"~/Scripts/appScripts/messages.js",
|
||||
"~/Scripts/appScripts/fileBrowsing.js",
|
||||
"~/Scripts/appScripts/dialogs.js",
|
||||
"~/Scripts/appScripts/wsp.js"
|
||||
));
|
||||
|
||||
bundles.Add(new ScriptBundle("~/bundles/authScripts").Include(
|
||||
"~/Scripts/appScripts/authentication.js"));
|
||||
|
|
|
@ -42,6 +42,12 @@ namespace WebsitePanel.WebDavPortal
|
|||
|
||||
#endregion
|
||||
|
||||
routes.MapRoute(
|
||||
name: FileSystemRouteNames.DeleteFiles,
|
||||
url: "files-group-action/delete",
|
||||
defaults: new { controller = "FileSystem", action = "DeleteFiles" }
|
||||
);
|
||||
|
||||
routes.MapRoute(
|
||||
name: FileSystemRouteNames.UploadFile,
|
||||
url: "upload-file/{org}/{*pathPart}",
|
||||
|
|
|
@ -26,6 +26,32 @@ textarea {
|
|||
.element-container {
|
||||
margin-bottom: 15px;
|
||||
text-align:center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.element-container .element {
|
||||
position: relative;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.selected-file .element {
|
||||
position: relative;
|
||||
box-sizing:border-box;
|
||||
-moz-box-sizing:border-box;
|
||||
-webkit-box-sizing:border-box;
|
||||
border: 1px solid rgb(80, 152, 249);
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.selected-file .element div.selected-element-overlay {
|
||||
position:absolute;
|
||||
top:0px;
|
||||
left: 0px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:rgb(200, 224, 255);
|
||||
opacity:0.3;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#errorMessage {
|
||||
|
@ -55,3 +81,17 @@ textarea {
|
|||
.modal-vertical-centered {
|
||||
margin-top: 25%;
|
||||
}
|
||||
|
||||
|
||||
.file-actions-menu {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.file-actions-menu .file-deletion {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#message-area {
|
||||
margin-top: 15px;
|
||||
}
|
|
@ -6,6 +6,8 @@ using WebsitePanel.WebDav.Core.Config;
|
|||
using WebsitePanel.WebDav.Core.Security.Authentication;
|
||||
using WebsitePanel.WebDav.Core.Security.Cryptography;
|
||||
using WebsitePanel.WebDavPortal.Models;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
using WebsitePanel.WebDavPortal.Models.Common.Enums;
|
||||
using WebsitePanel.WebDavPortal.UI.Routes;
|
||||
using WebsitePanel.WebDav.Core.Interfaces.Security;
|
||||
using WebsitePanel.WebDav.Core;
|
||||
|
|
|
@ -19,6 +19,10 @@ using WebsitePanel.WebDavPortal.CustomAttributes;
|
|||
using WebsitePanel.WebDavPortal.Extensions;
|
||||
using WebsitePanel.WebDavPortal.Models;
|
||||
using System.Net;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
using WebsitePanel.WebDavPortal.Models.Common.Enums;
|
||||
using WebsitePanel.WebDavPortal.Models.FileSystem;
|
||||
using WebsitePanel.WebDavPortal.UI;
|
||||
using WebsitePanel.WebDavPortal.UI.Routes;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Controllers
|
||||
|
@ -72,7 +76,7 @@ namespace WebsitePanel.WebDavPortal.Controllers
|
|||
|
||||
return View(model);
|
||||
}
|
||||
catch (UnauthorizedException)
|
||||
catch (UnauthorizedException e)
|
||||
{
|
||||
throw new HttpException(404, "Not Found");
|
||||
}
|
||||
|
@ -121,5 +125,39 @@ namespace WebsitePanel.WebDavPortal.Controllers
|
|||
|
||||
return RedirectToRoute(FileSystemRouteNames.ShowContentPath);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public JsonResult DeleteFiles(IEnumerable<string> filePathes = null)
|
||||
{
|
||||
var model = new DeleteFilesModel();
|
||||
|
||||
if (filePathes == null)
|
||||
{
|
||||
model.AddMessage(MessageType.Error, Resources.NoFilesAreSelected);
|
||||
|
||||
return Json(model);
|
||||
}
|
||||
|
||||
foreach (var file in filePathes)
|
||||
{
|
||||
try
|
||||
{
|
||||
_webdavManager.DeleteResource(Server.UrlDecode(file));
|
||||
|
||||
model.DeletedFiles.Add(file);
|
||||
}
|
||||
catch (WebDavException exception)
|
||||
{
|
||||
model.AddMessage(MessageType.Error, exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
if (model.DeletedFiles.Any())
|
||||
{
|
||||
model.AddMessage(MessageType.Success, string.Format(Resources.ItemsWasRemovedFormat, model.DeletedFiles.Count));
|
||||
}
|
||||
|
||||
return Json(model);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.CustomAttributes
|
||||
{
|
||||
public class FormValueRequiredAttribute : ActionMethodSelectorAttribute
|
||||
{
|
||||
private readonly string _submitButtonName;
|
||||
|
||||
public FormValueRequiredAttribute(string submitButtonName)
|
||||
{
|
||||
_submitButtonName = submitButtonName;
|
||||
}
|
||||
|
||||
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
|
||||
{
|
||||
var value = controllerContext.HttpContext.Request.Form[_submitButtonName];
|
||||
return !string.IsNullOrEmpty(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using WebsitePanel.Providers.HostedSolution;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models
|
||||
{
|
||||
public class AccountModel
|
||||
public class AccountModel : BaseModel
|
||||
{
|
||||
[Required]
|
||||
[Display(Name = @"Login")]
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
using WebsitePanel.WebDavPortal.Models.Common.Enums;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models.Common
|
||||
{
|
||||
public class BaseModel
|
||||
{
|
||||
public BaseModel()
|
||||
{
|
||||
Messages = new List<Message>();
|
||||
}
|
||||
|
||||
public List<Message> Messages { get; private set; }
|
||||
|
||||
public void AddMessage(MessageType type, string value)
|
||||
{
|
||||
Messages.Add(new Message
|
||||
{
|
||||
Type =type,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace WebsitePanel.WebDavPortal.Models.Common.Enums
|
||||
{
|
||||
public enum MessageType
|
||||
{
|
||||
Success,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using WebsitePanel.WebDavPortal.Models.Common.Enums;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models.Common
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
public MessageType Type {get;set;}
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
using System;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models
|
||||
{
|
||||
public class ErrorModel
|
||||
public class ErrorModel : BaseModel
|
||||
{
|
||||
public int HttpStatusCode { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models.FileSystem
|
||||
{
|
||||
public class DeleteFilesModel : BaseModel
|
||||
{
|
||||
public DeleteFilesModel()
|
||||
{
|
||||
DeletedFiles = new List<string>();
|
||||
}
|
||||
|
||||
public List<string> DeletedFiles { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using WebsitePanel.WebDav.Core.Client;
|
||||
using WebsitePanel.WebDav.Core.Security.Authorization.Enums;
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models
|
||||
{
|
||||
public class ModelForWebDav
|
||||
public class ModelForWebDav : BaseModel
|
||||
{
|
||||
public IEnumerable<IHierarchyItem> Items { get; set; }
|
||||
public string UrlSuffix { get; set; }
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
namespace WebsitePanel.WebDavPortal.Models
|
||||
using WebsitePanel.WebDavPortal.Models.Common;
|
||||
|
||||
namespace WebsitePanel.WebDavPortal.Models
|
||||
{
|
||||
public class OfficeOnlineModel
|
||||
public class OfficeOnlineModel : BaseModel
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string FileName { get; set; }
|
||||
|
|
|
@ -1,20 +1,79 @@
|
|||
var processDialog;
|
||||
processDialog = processDialog || (function () {
|
||||
var processDialogDiv = $('#processDialog');
|
||||
function WspDialogs() {
|
||||
this.settings = { dialogId: "#confirm-dialog", processDialogId: "#processDialog" };
|
||||
}
|
||||
|
||||
WspDialogs.prototype =
|
||||
{
|
||||
showConfirmDialog: function(title, content, positiveButton, positiveClickFunction, dialogId) {
|
||||
dialogId = dialogId || this.settings.dialogId;
|
||||
|
||||
//title replace
|
||||
if (title) {
|
||||
$(dialogId).find('.modal-title').empty();
|
||||
$(dialogId).find('.modal-title').text(title);
|
||||
}
|
||||
|
||||
//body replace
|
||||
$(dialogId).find('.modal-body').empty();
|
||||
$(dialogId).find('.modal-body').html(content);
|
||||
|
||||
//title replace
|
||||
if (positiveButton) {
|
||||
$(dialogId).find('.modal-footer .positive-button').empty();
|
||||
$(dialogId).find('.modal-footer .positive-button').text(positiveButton);
|
||||
}
|
||||
|
||||
//binding click event
|
||||
$(dialogId).find('.modal-footer .positive-button').unbind('click');
|
||||
$(dialogId).find('.modal-footer .positive-button').click(positiveClickFunction);
|
||||
|
||||
$(dialogId).modal();
|
||||
},
|
||||
|
||||
showProcessDialog: function() {
|
||||
$(this.settings.processDialogId).modal();
|
||||
},
|
||||
|
||||
hideProcessDialog: function() {
|
||||
$(this.settings.processDialogId).modal('hide');
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
wsp.dialogs = wsp.dialogs || (function () {
|
||||
var settings = { dialogId: "#confirm-dialog" };
|
||||
|
||||
return {
|
||||
showPleaseWait: function () {
|
||||
settings: settings,
|
||||
|
||||
showConfirmDialog : function (title, content, positiveButton, positiveClickFunction, dialogId) {
|
||||
dialogId = dialogId || this.settings.dialogId;
|
||||
|
||||
//title replace
|
||||
if (title) {
|
||||
$(dialogId).find('.modal-title').empty();
|
||||
$(dialogId).find('.modal-title').text(title);
|
||||
}
|
||||
|
||||
//body replace
|
||||
$(dialogId).find('.modal-body').empty();
|
||||
$(dialogId).find('.modal-body').html(content);
|
||||
|
||||
//title replace
|
||||
if (positiveButton) {
|
||||
$(dialogId).find('.modal-footer .positive-button').empty();
|
||||
$(dialogId).find('.modal-footer .positive-button').text(positiveButton);
|
||||
}
|
||||
|
||||
//binding click event
|
||||
$(dialogId).find('.modal-footer .positive-button').unbind('click');
|
||||
$(dialogId).find('.modal-footer .positive-button').click(positiveClickFunction);
|
||||
|
||||
$(dialogId).modal();
|
||||
},
|
||||
|
||||
showProcessDialog: function () {
|
||||
$('#processDialog').modal();
|
||||
},
|
||||
hidePleaseWait: function () {
|
||||
$('#processDialog').modal('hide');
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.processing-dialog').click(function () {
|
||||
processDialog.showPleaseWait();
|
||||
});
|
||||
});
|
||||
})();*/
|
|
@ -0,0 +1,89 @@
|
|||
function WspFileBrowser() {
|
||||
this.settings = { deletionBlockSelector: ".file-actions-menu .file-deletion", deletionUrl: "files-group-action/delete1" };
|
||||
}
|
||||
|
||||
WspFileBrowser.prototype = {
|
||||
setSettings: function(options) {
|
||||
this.settings = $.extend(this.settings, options);
|
||||
},
|
||||
|
||||
clearAllSelectedItems: function() {
|
||||
$('.element-container').removeClass("selected-file");
|
||||
},
|
||||
|
||||
selectItem: function(item) {
|
||||
$(item).addClass("selected-file");
|
||||
},
|
||||
|
||||
openItem: function(item) {
|
||||
var links = $(item).find('.file-link');
|
||||
|
||||
if (links.length != 0) {
|
||||
links[0].click();
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedItemsCount: function() {
|
||||
return $('.element-container.selected-file').length;
|
||||
},
|
||||
|
||||
getSelectedItemsPaths: function() {
|
||||
return $('.element-container.selected-file a').map(function() {
|
||||
return $(this).attr('href');
|
||||
}).get();
|
||||
},
|
||||
|
||||
deleteSelectedItems: function(e) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: wsp.fileBrowser.settings.deletionUrl,
|
||||
data: { filePathes: wsp.fileBrowser.getSelectedItemsPaths() },
|
||||
dataType: "json",
|
||||
success: function(model) {
|
||||
wsp.messages.showMessages(model.Messages);
|
||||
|
||||
wsp.fileBrowser.clearDeletedItems(model.DeletedFiles);
|
||||
|
||||
wsp.fileBrowser.refreshDeletionBlock();
|
||||
|
||||
wsp.dialogs.hideProcessDialog();
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
wsp.messages.addErrorMessage(errorThrown);
|
||||
wsp.fileBrowser.refreshDeletionBlock();
|
||||
wsp.dialogs.hideProcessDialog();
|
||||
}
|
||||
});
|
||||
|
||||
wsp.dialogs.showProcessDialog();
|
||||
},
|
||||
|
||||
clearDeletedItems: function(items) {
|
||||
$.each(items, function(i, item) {
|
||||
$('.element-container').has('a[href="' + item + '"]').remove();
|
||||
});
|
||||
},
|
||||
refreshDeletionBlock: function() {
|
||||
if (this.getSelectedItemsCount() > 0) {
|
||||
|
||||
$(this.settings.deletionBlockSelector).css('display', 'inline-block');
|
||||
|
||||
} else {
|
||||
$(this.settings.deletionBlockSelector).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
function WspMessager(messageDivId) {
|
||||
this.settings = {
|
||||
messageDivId: messageDivId,
|
||||
successClass: "alert-success",
|
||||
infoClass: "alert-info",
|
||||
warningClass: "alert-warning",
|
||||
dangerClass: "alert-danger",
|
||||
messageDivtemplate: '<div class="alert {0} alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>{1}</div>'
|
||||
};
|
||||
}
|
||||
|
||||
WspMessager.prototype = {
|
||||
addMessage: function(cssClass, message) {
|
||||
var messageDiv = jQuery.validator.format(this.settings.messageDivtemplate, cssClass, message);
|
||||
|
||||
$(messageDiv).appendTo(this.settings.messageDivId);
|
||||
},
|
||||
|
||||
addSuccessMessage: function(message) {
|
||||
this.addMessage(this.settings.successClass, message);
|
||||
},
|
||||
|
||||
addInfoMessage: function(message) {
|
||||
this.addMessage(this.settings.infoClass, message);
|
||||
},
|
||||
|
||||
addWarningMessage : function (message) {
|
||||
this.addMessage(this.settings.warningClass, message);
|
||||
},
|
||||
|
||||
addErrorMessage: function (message) {
|
||||
this.addMessage(this.settings.dangerClass, message);
|
||||
},
|
||||
|
||||
showMessages: function (messages) {
|
||||
var objthis = this;
|
||||
|
||||
$.each(messages, function(i, message) {
|
||||
|
||||
if ((message.Type == 0)) {
|
||||
objthis.addSuccessMessage(message.Value);
|
||||
}
|
||||
else if (message.Type == 1) {
|
||||
objthis.addInfoMessage(message.Value);
|
||||
}
|
||||
else if (message.Type == 2) {
|
||||
objthis.addWarningMessage(message.Value);
|
||||
}
|
||||
else if (message.Type == 3) {
|
||||
objthis.addErrorMessage(message.Value);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
maxHeight = Math.max.apply(null, heights);
|
||||
|
||||
if (maxHeight < 135) {
|
||||
maxHeight = 135;
|
||||
}
|
||||
|
||||
$(".element-container").height(maxHeight);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
var wsp = {
|
||||
messages: new WspMessager('#message-area'),
|
||||
fileBrowser: new WspFileBrowser(),
|
||||
dialogs: new WspDialogs()
|
||||
};
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.processing-dialog').click(function () {
|
||||
wsp.dialogs.showProcessDialog();
|
||||
});
|
||||
});
|
||||
|
||||
//Toggle file select + Ctrl multiselect
|
||||
$(document).on('click', '.element-container', function (e) {
|
||||
if (e.ctrlKey) {
|
||||
|
||||
$(this).toggleClass("selected-file");
|
||||
|
||||
} else {
|
||||
|
||||
wsp.fileBrowser.clearAllSelectedItems();
|
||||
|
||||
wsp.fileBrowser.selectItem(this);
|
||||
}
|
||||
|
||||
wsp.fileBrowser.refreshDeletionBlock();
|
||||
});
|
||||
|
||||
//Double click file open
|
||||
$(document).on('dblclick', '.element-container', function (e) {
|
||||
wsp.fileBrowser.openItem(this);
|
||||
});
|
||||
|
||||
|
||||
//Delete button click
|
||||
$(document).on('click', '.file-deletion #delete-button', function (e) {
|
||||
var dialogId = $(this).data('target');
|
||||
var buttonText = $(this).data('target-positive-button-text');
|
||||
var content = $(this).data('target-content');
|
||||
var title = $(this).data('target-title-text');
|
||||
|
||||
content = jQuery.validator.format(content, wsp.fileBrowser.getSelectedItemsCount());
|
||||
|
||||
wsp.dialogs.showConfirmDialog(title, content, buttonText, wsp.fileBrowser.deleteSelectedItems, dialogId);
|
||||
});
|
||||
|
||||
|
||||
$(document).click(function (event) {
|
||||
if (!$(event.target).closest('.element-container, .prevent-deselect').length) {
|
||||
wsp.fileBrowser.clearAllSelectedItems();
|
||||
wsp.fileBrowser.refreshDeletionBlock();
|
||||
}
|
||||
})
|
|
@ -69,6 +69,15 @@ namespace WebsitePanel.WebDavPortal.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cancel.
|
||||
/// </summary>
|
||||
public static string Cancel {
|
||||
get {
|
||||
return ResourceManager.GetString("Cancel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Close.
|
||||
/// </summary>
|
||||
|
@ -78,6 +87,42 @@ namespace WebsitePanel.WebDavPortal.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Confirm.
|
||||
/// </summary>
|
||||
public static string Confirm {
|
||||
get {
|
||||
return ResourceManager.GetString("Confirm", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete.
|
||||
/// </summary>
|
||||
public static string Delete {
|
||||
get {
|
||||
return ResourceManager.GetString("Delete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete File?.
|
||||
/// </summary>
|
||||
public static string DeleteFileQuestion {
|
||||
get {
|
||||
return ResourceManager.GetString("DeleteFileQuestion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Are you sure you want to delete {0} item(s)?.
|
||||
/// </summary>
|
||||
public static string DialogsContentConfrimFileDeletion {
|
||||
get {
|
||||
return ResourceManager.GetString("DialogsContentConfrimFileDeletion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to File Upload.
|
||||
/// </summary>
|
||||
|
@ -96,6 +141,24 @@ namespace WebsitePanel.WebDavPortal.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} items was removed..
|
||||
/// </summary>
|
||||
public static string ItemsWasRemovedFormat {
|
||||
get {
|
||||
return ResourceManager.GetString("ItemsWasRemovedFormat", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No files are selected..
|
||||
/// </summary>
|
||||
public static string NoFilesAreSelected {
|
||||
get {
|
||||
return ResourceManager.GetString("NoFilesAreSelected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Processing.
|
||||
/// </summary>
|
||||
|
@ -122,5 +185,14 @@ namespace WebsitePanel.WebDavPortal.UI {
|
|||
return ResourceManager.GetString("Upload", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Yes.
|
||||
/// </summary>
|
||||
public static string Yes {
|
||||
get {
|
||||
return ResourceManager.GetString("Yes", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,15 +120,36 @@
|
|||
<data name="Actions" xml:space="preserve">
|
||||
<value>Actions</value>
|
||||
</data>
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="Close" xml:space="preserve">
|
||||
<value>Close</value>
|
||||
</data>
|
||||
<data name="Confirm" xml:space="preserve">
|
||||
<value>Confirm</value>
|
||||
</data>
|
||||
<data name="Delete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="DeleteFileQuestion" xml:space="preserve">
|
||||
<value>Delete File?</value>
|
||||
</data>
|
||||
<data name="DialogsContentConfrimFileDeletion" xml:space="preserve">
|
||||
<value>Are you sure you want to delete {0} item(s)?</value>
|
||||
</data>
|
||||
<data name="FileUpload" xml:space="preserve">
|
||||
<value>File Upload</value>
|
||||
</data>
|
||||
<data name="GigabyteShort" xml:space="preserve">
|
||||
<value>Gb</value>
|
||||
</data>
|
||||
<data name="ItemsWasRemovedFormat" xml:space="preserve">
|
||||
<value>{0} items was removed.</value>
|
||||
</data>
|
||||
<data name="NoFilesAreSelected" xml:space="preserve">
|
||||
<value>No files are selected.</value>
|
||||
</data>
|
||||
<data name="Processing" xml:space="preserve">
|
||||
<value>Processing</value>
|
||||
</data>
|
||||
|
@ -138,4 +159,7 @@
|
|||
<data name="Upload" xml:space="preserve">
|
||||
<value>Upload</value>
|
||||
</data>
|
||||
<data name="Yes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
</root>
|
|
@ -12,5 +12,7 @@ namespace WebsitePanel.WebDavPortal.UI.Routes
|
|||
public const string ShowAdditionalContent = "ShowAdditionalContentRoute";
|
||||
|
||||
public const string UploadFile = "UplaodFIleRoute";
|
||||
|
||||
public const string DeleteFiles = "DeleteFilesRoute";
|
||||
}
|
||||
}
|
|
@ -12,12 +12,7 @@
|
|||
var webDavManager = DependencyResolver.Current.GetService<IWebDavManager>();
|
||||
ViewBag.Title = WebDavAppConfigManager.Instance.ApplicationName;
|
||||
}
|
||||
@Scripts.Render("~/bundles/jquery")
|
||||
@Scripts.Render("~/bundles/appScripts")
|
||||
|
||||
<script>
|
||||
recalculateResourseHeight();
|
||||
</script>
|
||||
|
||||
<br />
|
||||
@if (Model != null && !string.IsNullOrEmpty(Model.Error))
|
||||
|
@ -26,36 +21,35 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<div class="container">
|
||||
<div class="container prevent-deselect">
|
||||
@if (Model != null)
|
||||
{
|
||||
string header = WspContext.User.OrganizationId;
|
||||
<a href="/@header/" class="btn btn-primary btn-sm active" role="button">@header</a>
|
||||
string[] elements = Model.UrlSuffix.Split(new[] {"/"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] elements = Model.UrlSuffix.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < elements.Length; i++)
|
||||
{
|
||||
<span class="glyphicon glyphicon-chevron-right" style="top: 2px;"></span>
|
||||
<a href="@string.Concat("/" + header + "/", string.Join("/", elements.Take(i + 1)))" class="btn btn-primary btn-sm active" role="button">@elements[i]</a>
|
||||
}
|
||||
|
||||
if (Model.Permissions.HasFlag(WebDavPermissions.Write))
|
||||
{
|
||||
@*<a id="upload-button" class="btn btn-success btn-sm active" data-toggle="modal" data-target="#file-upload" role="button">@Resources.FileUpload</a>*@
|
||||
|
||||
<div class="dropdown navbar-right">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
|
||||
@Resources.Actions
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
|
||||
<li role="presentation"><a id="upload-button" data-toggle="modal" data-target="#file-upload" role="menuitem" tabindex="-1" href="#">@Resources.FileUpload</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="container file-actions-menu prevent-deselect">
|
||||
@if (Model.Permissions.HasFlag(WebDavPermissions.Write))
|
||||
{
|
||||
<div class="file-deletion navbar-left">
|
||||
<a id="delete-button" class="btn btn-danger btn-sm active" role="button"
|
||||
data-target="#confirm-dialog"
|
||||
data-target-positive-button-text="@Resources.Delete"
|
||||
data-target-title-text="@Resources.DeleteFileQuestion"
|
||||
data-target-content="@Resources.DialogsContentConfrimFileDeletion">@Resources.Delete</a>
|
||||
</div>
|
||||
<a id="upload-button" class="btn btn-success btn-sm active navbar-right" data-toggle="modal" data-target="#file-upload" role="button">@Resources.FileUpload</a>
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
<div class="container">
|
||||
|
||||
<div class="row" id="resourcesDiv">
|
||||
@if (Model != null)
|
||||
{
|
||||
|
@ -68,6 +62,13 @@ else
|
|||
</div>
|
||||
}
|
||||
|
||||
@section scripts{
|
||||
<script>
|
||||
wsp.fileBrowser.setSettings({ deletionUrl: "@Url.RouteUrl(FileSystemRouteNames.DeleteFiles)" });
|
||||
recalculateResourseHeight();
|
||||
|
||||
</script>
|
||||
}
|
||||
|
||||
@section popups
|
||||
{
|
||||
|
@ -93,4 +94,5 @@ else
|
|||
</div>
|
||||
|
||||
@Html.Partial("_ProcessDialog", null)
|
||||
@Html.Partial("_ConfirmDialog")
|
||||
}
|
|
@ -17,12 +17,12 @@
|
|||
{
|
||||
case FileOpenerType.OfficeOnline:
|
||||
isTargetBlank = true;
|
||||
var pathPart = Model.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "");
|
||||
var pathPart = Model.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "").TrimStart('/');
|
||||
href = string.Concat(Url.RouteUrl(FileSystemRouteNames.ShowOfficeOnlinePath, new { org = WspContext.User.OrganizationId, pathPart = "" }), pathPart);
|
||||
break;
|
||||
default:
|
||||
isTargetBlank = false;
|
||||
href = Model.Href.AbsolutePath;
|
||||
href = Model.Href.LocalPath;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -39,17 +39,24 @@
|
|||
}
|
||||
|
||||
<div class="col-sm-2 element-container">
|
||||
<a href="@href" @Html.Raw(isTargetBlank ? "target=\"_blank\"" : string.Empty) title="@name">
|
||||
<div class="element">
|
||||
<img class="icon-size" src="@Url.Content(actualPath)" />
|
||||
|
||||
<a href="@href" @Html.Raw(isTargetBlank ? "target=\"_blank\"" : string.Empty) class="file-link" title="@name">
|
||||
<p style="word-wrap: break-word;">@name</p>
|
||||
</a>
|
||||
|
||||
@if (showStatistic)
|
||||
{
|
||||
<div class="progress web-dav-folder-progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="@percent" aria-valuemin="0" aria-valuemax="100" style="width: @percent%;">
|
||||
@percent%
|
||||
<p class="progress-text">@percent%</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>@Math.Round(Convert.ToDecimal(resource.ContentLength) / 1024, 2) / @Math.Round(Convert.ToDecimal(resource.AllocatedSpace) / 1024, 2) @Resources.GigabyteShort</p>
|
||||
}
|
||||
|
||||
<div class="selected-element-overlay">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
@using WebsitePanel.WebDavPortal.UI
|
||||
<div class="modal fade" id="confirm-dialog" tabindex="-1" role="dialog" aria-labelledby="confirm-dalog-label" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="confirm-dalog-label">@Resources.Confirm</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">@Resources.Cancel</button>
|
||||
<a href="#" class="btn btn-danger danger positive-button" data-dismiss="modal">@Resources.Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,9 +1,11 @@
|
|||
@using Ninject
|
||||
@using System.Web.Script.Serialization
|
||||
@using Ninject
|
||||
@using WebsitePanel.WebDav.Core
|
||||
@using WebsitePanel.WebDav.Core.Config
|
||||
@using WebsitePanel.WebDavPortal.DependencyInjection
|
||||
@using WebsitePanel.WebDavPortal.Models
|
||||
@using WebsitePanel.WebDavPortal.UI.Routes;
|
||||
@model WebsitePanel.WebDavPortal.Models.Common.BaseModel
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -15,8 +17,8 @@
|
|||
@Scripts.Render("~/bundles/modernizr")
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top prevent-deselect">
|
||||
<div class="container top-container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
|
@ -32,18 +34,25 @@
|
|||
<a id="logout" class="nav navbar-text navbar-right" href="@Url.RouteUrl(AccountRouteNames.Logout)" title="Log out"><i class="glyphicon glyphicon-log-out"></i></a>
|
||||
<h4 id="username" class="nav navbar-text navbar-right">@WspContext.User.Login</h4>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container body-content">
|
||||
<div id="message-area" class="container prevent-deselect"> </div>
|
||||
@RenderBody()
|
||||
</div>
|
||||
|
||||
<div class="prevent-deselect">
|
||||
@RenderSection("popups", required: false)
|
||||
</div>
|
||||
|
||||
@Scripts.Render("~/bundles/jquery")
|
||||
@Scripts.Render("~/bundles/jqueryval")
|
||||
@Scripts.Render("~/bundles/bootstrap")
|
||||
@Scripts.Render("~/bundles/appScripts")
|
||||
|
||||
|
||||
|
||||
@if (WspContext.User != null)
|
||||
{
|
||||
|
@ -54,6 +63,15 @@
|
|||
</script>
|
||||
}
|
||||
|
||||
@if (Model != null)
|
||||
{
|
||||
<script>
|
||||
wsp.messages.showMessages(@Html.Raw(Json.Encode(Model.Messages)));
|
||||
</script>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RenderSection("scripts", required: false)
|
||||
|
||||
|
||||
|
|
|
@ -46,8 +46,10 @@
|
|||
<sessionKeys>
|
||||
<add key="AccountInfoSessionKey" value="AccountInfo" />
|
||||
<add key="WebDavManagerSessionKey" value="WebDavManager" />
|
||||
<add key="WebDavRootFolderPermissionsKey" value="WebDavRootFolderPermissions" />
|
||||
<add key="ResourseRenderCountSessionKey" value="ResourseRenderCount" />
|
||||
<add key="ItemIdSessionKey" value="ItemId" />
|
||||
<add key="UserGroupsKey" value="UserGroups" />
|
||||
</sessionKeys>
|
||||
<fileIcons defaultPath="~/Content/Images/other-icon.png">
|
||||
<add extension=".txt" path="~/Content/Images/txt-icon.png" />
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
<Compile Include="Controllers\ErrorController.cs" />
|
||||
<Compile Include="Controllers\FileSystemController.cs" />
|
||||
<Compile Include="Controllers\OwaController.cs" />
|
||||
<Compile Include="CustomAttributes\FormValueRequiredAttribute.cs" />
|
||||
<Compile Include="CustomAttributes\LdapAuthorizationAttribute.cs" />
|
||||
<Compile Include="DependencyInjection\NinjectDependecyResolver.cs" />
|
||||
<Compile Include="DependencyInjection\PortalDependencies.cs" />
|
||||
|
@ -159,8 +160,12 @@
|
|||
</Compile>
|
||||
<Compile Include="HttpHandlers\FileTransferRequestHandler.cs" />
|
||||
<Compile Include="Models\AccountModel.cs" />
|
||||
<Compile Include="Models\Common\BaseModel.cs" />
|
||||
<Compile Include="Models\Common\Enums\MessageType.cs" />
|
||||
<Compile Include="Models\Common\Message.cs" />
|
||||
<Compile Include="Models\DirectoryIdentity.cs" />
|
||||
<Compile Include="Models\ErrorModel.cs" />
|
||||
<Compile Include="Models\FileSystem\DeleteFilesModel.cs" />
|
||||
<Compile Include="Models\ModelForWebDav.cs" />
|
||||
<Compile Include="Models\OfficeOnlineModel.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -225,8 +230,11 @@
|
|||
<None Include="Scripts\jquery-2.1.1.intellisense.js" />
|
||||
<Content Include="Scripts\appScripts\authentication.js" />
|
||||
<Content Include="Scripts\appScripts\dialogs.js" />
|
||||
<Content Include="Scripts\appScripts\fileBrowsing.js" />
|
||||
<Content Include="Scripts\appScripts\messages.js" />
|
||||
<Content Include="Scripts\appScripts\recalculateResourseHeight.js" />
|
||||
<Content Include="Scripts\appScripts\uploadingData2.js" />
|
||||
<Content Include="Scripts\appScripts\wsp.js" />
|
||||
<Content Include="Scripts\bootstrap.js" />
|
||||
<Content Include="Scripts\bootstrap.min.js" />
|
||||
<Content Include="Scripts\jquery-2.1.1.js" />
|
||||
|
@ -265,6 +273,7 @@
|
|||
<Content Include="Views\FileSystem\_ResourseCollectionPartial.cshtml" />
|
||||
<Content Include="Views\FileSystem\_ResoursePartial.cshtml" />
|
||||
<Content Include="Views\Shared\_ProcessDialog.cshtml" />
|
||||
<Content Include="Views\Shared\_ConfirmDialog.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Owa\" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue