diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs index 47e614ed..c7f2d45d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs @@ -13,12 +13,14 @@ namespace WebsitePanel.WebDav.Core.Config.Entities { IsEnabled = ConfigSection.OfficeOnline.IsEnabled; Url = ConfigSection.OfficeOnline.Url; + NewFilePath = ConfigSection.OfficeOnline.CobaltNewFilePath; CobaltFileTtl = ConfigSection.OfficeOnline.CobaltFileTtl; _officeExtensions = ConfigSection.OfficeOnline.Cast().ToList(); } public bool IsEnabled { get; private set; } public string Url { get; private set; } + public string NewFilePath { get; private set; } public int CobaltFileTtl { get; private set; } public IEnumerator GetEnumerator() diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs index 560b6964..823fc98a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs @@ -8,6 +8,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections private const string OwaViewKey = "OwaView"; private const string OwaEditorKey = "OwaEditor"; private const string OwaMobileViewKey = "OwaMobileView"; + private const string OwaNewFileViewKey = "OwaNewFileView"; [ConfigurationProperty(ExtensionKey, IsKey = true, IsRequired = true)] public string Extension @@ -37,5 +38,12 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections get { return this[OwaMobileViewKey].ToString(); } set { this[OwaMobileViewKey] = value; } } + + [ConfigurationProperty(OwaNewFileViewKey, IsKey = true, IsRequired = true)] + public string OwaNewFileView + { + get { return this[OwaNewFileViewKey].ToString(); } + set { this[OwaNewFileViewKey] = value; } + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs index 03f570c5..51603c99 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs @@ -9,6 +9,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections private const string UrlKey = "url"; private const string IsEnabledKey = "isEnabled"; private const string CobaltFileTtlKey = "cobaltFileTtl"; + private const string CobaltNewFilePathKey = "cobaltNewFilePath"; [ConfigurationProperty(UrlKey, IsKey = true, IsRequired = true)] public string Url @@ -24,6 +25,13 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections set { this[IsEnabledKey] = value; } } + [ConfigurationProperty(CobaltNewFilePathKey, IsKey = true, IsRequired = true)] + public string CobaltNewFilePath + { + get { return this[CobaltNewFilePathKey].ToString(); } + set { this[CobaltNewFilePathKey] = value; } + } + [ConfigurationProperty(CobaltFileTtlKey, IsKey = true, IsRequired = true)] public int CobaltFileTtl { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs index 076cb1e3..e5e72685 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs @@ -37,6 +37,10 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa public bool RestrictedWebViewOnly { get; set; } [DataMember] public string ClientUrl { get; set; } + [DataMember] + public bool CloseButtonClosesWindow { get; set; } + //[DataMember] + //public string CloseUrl { get; set; } //[DataMember] //public bool UserCanNotWriteRelative { get; set; } @@ -59,8 +63,7 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa //public string BreadcrumbFolderUrl { get; set; } //[DataMember] //public string ClientUrl { get; set; } - //[DataMember] - //public bool CloseButtonClosesWindow { get; set; } + //[DataMember] //public string CloseUrl { get; set; } //[DataMember] diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs index 6f35d7ff..058ad936 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs @@ -1,4 +1,4 @@ -using System.Web.Mvc; +using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Entities.Owa; @@ -6,7 +6,7 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Owa { public interface IWopiServer { - CheckFileInfo GetCheckFileInfo(string path); - FileResult GetFile(string path); + CheckFileInfo GetCheckFileInfo(WebDavAccessToken token); + byte[] GetFileBytes(int accessTokenId); } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs index d3f837a7..7b59436e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs @@ -240,9 +240,9 @@ namespace WebsitePanel.WebDav.Core.Managers return _currentFolder.GetResource(resourceName); } - catch (InvalidOperationException exception) + catch (Exception) { - throw new ResourceNotFoundException("Resource not found", exception); + return null; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs index 2684bf83..e9f16955 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs @@ -2,8 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Runtime.Caching; +using System.Web; using Cobalt; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Config; @@ -72,9 +74,20 @@ namespace WebsitePanel.WebDav.Core.Owa var token = _tokenManager.GetToken(accessTokenId); - var fileBytes = _webDavManager.GetFileBytes(token.FilePath); + Atom atom; - var atom = new AtomFromByteArray(fileBytes); + if (_webDavManager.FileExist(token.FilePath)) + { + var fileBytes = _webDavManager.GetFileBytes(token.FilePath); + + atom = new AtomFromByteArray(fileBytes); + } + else + { + var filePath = HttpContext.Current.Server.MapPath(WebDavAppConfigManager.Instance.OfficeOnline.NewFilePath + Path.GetExtension(token.FilePath)); + + atom = new AtomFromByteArray(File.ReadAllBytes(filePath)); + } Cobalt.Metrics o1; cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, atom, out o1); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs index dada9bab..860d3528 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs @@ -6,6 +6,8 @@ using System.Runtime.Serialization.Json; using System.Text; using System.Web; using System.Web.Mvc; +using Cobalt; +using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Entities.Owa; @@ -22,27 +24,30 @@ namespace WebsitePanel.WebDav.Core.Owa private readonly IWebDavManager _webDavManager; private readonly IAccessTokenManager _tokenManager; private readonly IWebDavAuthorizationService _webDavAuthorizationService; + private readonly IWopiFileManager _fileManager; - public WopiServer(IWebDavManager webDavManager, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService) + + public WopiServer(IWebDavManager webDavManager, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService, IWopiFileManager fileManager) { _webDavManager = webDavManager; _tokenManager = tokenManager; _webDavAuthorizationService = webDavAuthorizationService; + _fileManager = fileManager; } - public CheckFileInfo GetCheckFileInfo(string path) + public CheckFileInfo GetCheckFileInfo(WebDavAccessToken token) { - var resource = _webDavManager.GetResource(path); + var resource = _webDavManager.GetResource(token.FilePath); - var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, path); + var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, token.FilePath); var readOnly = permissions.HasFlag(WebDavPermissions.Write) == false || permissions.HasFlag(WebDavPermissions.OwaEdit) == false; var cFileInfo = new CheckFileInfo { - BaseFileName = resource.DisplayName.Split(new []{'/'},StringSplitOptions.RemoveEmptyEntries).LastOrDefault(), + BaseFileName = resource == null ? token.FilePath.Split('/').Last() : resource.DisplayName.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault(), OwnerId = WspContext.User.Login, - Size = resource.ContentLength, + Size = resource == null ? 0 : resource.ContentLength, Version = DateTime.Now.ToString("s"), SupportsCoauth = true, SupportsCobalt = true, @@ -53,17 +58,34 @@ namespace WebsitePanel.WebDav.Core.Owa SupportsUpdate = true, UserCanWrite = !readOnly, ReadOnly = readOnly, - RestrictedWebViewOnly = false + RestrictedWebViewOnly = false, + CloseButtonClosesWindow = true }; + if (resource != null) + { + cFileInfo.ClientUrl = _webDavManager.GetFileUrl(token.FilePath); + } + return cFileInfo; } - public FileResult GetFile(string path) + public byte[] GetFileBytes(int accessTokenId) { - var fileBytes = _webDavManager.GetFileBytes(path); + var token = _tokenManager.GetToken(accessTokenId); - return new FileContentResult(fileBytes, MediaTypeNames.Application.Octet); + if (_webDavManager.FileExist(token.FilePath)) + { + return _webDavManager.GetFileBytes(token.FilePath); + } + + var cobaltFile = _fileManager.Get(token.FilePath) ?? _fileManager.Create(accessTokenId); + + var stream = new MemoryStream(); + + new GenericFda(cobaltFile.CobaltEndpoint, null).GetContentStream().CopyTo(stream); + + return stream.ToArray(); } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs index a5dc75e8..bf48c585 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs @@ -46,6 +46,20 @@ namespace WebsitePanel.WebDavPortal #region Enterprise storage + routes.MapRoute( + name: FileSystemRouteNames.ItemExist, + url: "storage/item-exist/{org}/{*pathPart}", + defaults: + new { controller = "FileSystem", action = "ItemExist", pathPart = UrlParameter.Optional } + ); + + routes.MapRoute( + name: FileSystemRouteNames.NewWebDavItem, + url: "storage/new/{org}/{*pathPart}", + defaults: + new { controller = "FileSystem", action = "NewWebDavItem", pathPart = UrlParameter.Optional } + ); + routes.MapRoute( name: FileSystemRouteNames.SearchFiles, url: "storage/search/{org}/{*pathPart}", diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs index 9a6832b2..acb38f0c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs @@ -12,6 +12,9 @@ namespace WebsitePanel.WebDavPortal.UI.Routes public const string ShowContentDetails = "ShowContentDetailsRoute"; public const string ShowOfficeOnlinePath_ = "ShowOfficeOnlineRoute"; public const string ViewOfficeOnline = "ViewOfficeOnlineRoute"; + public const string NewFileOfficeOnline = "NewFileOfficeOnlineRoute"; + public const string NewWebDavItem = "NewWebDavItemRoute"; + public const string ItemExist = "ItemExistRoute"; public const string EditOfficeOnline = "EditOfficeOnlineRoute"; public const string ShowAdditionalContent = "ShowAdditionalContentRoute"; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx new file mode 100644 index 00000000..b5ca5258 Binary files /dev/null and b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx differ diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx new file mode 100644 index 00000000..cc170548 Binary files /dev/null and b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx differ diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx new file mode 100644 index 00000000..31991b64 Binary files /dev/null and b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx differ diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index 988dabfa..4f95621b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -251,12 +251,17 @@ tr.selected-file { .file-actions-menu .file-deletion { display: none; + margin-right: 10px; } .file-actions-menu .file-upload { display: inline-block; } +.create-new-item { + margin-top: -2px; +} + #message-area { margin-top: 15px; } @@ -336,6 +341,11 @@ tr.selected-file { top: 20%; } + +.small-processing { + display: none; +} + /* Theme Mods */ input,div{border-radius:0px!important;} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs index 4b0e2a87..761214ef 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs @@ -54,22 +54,24 @@ namespace WebsitePanel.WebDavPortal.Controllers.Api { var token = _tokenManager.GetToken(accessTokenId); - var fileInfo = _wopiServer.GetCheckFileInfo(token.FilePath); + var fileInfo = _wopiServer.GetCheckFileInfo(token); - var urlPart = Url.Route(FileSystemRouteNames.ShowContentPath, new { org = WspContext.User.OrganizationId, pathPart = token.FilePath }); + if (fileInfo.Size <= 1) + { + return fileInfo; + } + + var urlPart = Url.Route(FileSystemRouteNames.ShowContentPath, new {org = WspContext.User.OrganizationId, pathPart = token.FilePath}); var url = new Uri(Request.RequestUri, urlPart).ToString(); fileInfo.DownloadUrl = url; - fileInfo.ClientUrl = _webDavManager.GetFileUrl(token.FilePath); return fileInfo; } public HttpResponseMessage GetFile(int accessTokenId) { - var token = _tokenManager.GetToken(accessTokenId); - - var bytes = _webDavManager.GetFileBytes(token.FilePath); + var bytes = _wopiServer.GetFileBytes(accessTokenId); var result = new HttpResponseMessage(HttpStatusCode.OK); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs index 9d4016e1..0940d23a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs @@ -303,6 +303,36 @@ namespace WebsitePanel.WebDavPortal.Controllers return Json(model); } + public ActionResult NewWebDavItem(string org, string pathPart) + { + var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart); + + var owaOpener = WebDavAppConfigManager.Instance.OfficeOnline.FirstOrDefault(x => x.Extension == Path.GetExtension(pathPart)); + + if (permissions.HasFlag(WebDavPermissions.Write) == false || (owaOpener != null && permissions.HasFlag(WebDavPermissions.OwaEdit) == false)) + { + return new RedirectToRouteResult(FileSystemRouteNames.ShowContentPath, null); + } + + if (owaOpener != null) + { + return ShowOfficeDocument(org, pathPart, owaOpener.OwaNewFileView); + } + + return new RedirectToRouteResult(FileSystemRouteNames.ShowContentPath, null); + } + + [HttpPost] + public JsonResult ItemExist(string org, string pathPart, string newItemName) + { + var exist = _webdavManager.FileExist(string.Format("{0}/{1}", pathPart, newItemName)); + + return new JsonResult() + { + Data = !exist + }; + } + #region Owa Actions public ActionResult ShowOfficeDocument(string org, string pathPart, string owaOpenerUri) @@ -345,6 +375,7 @@ namespace WebsitePanel.WebDavPortal.Controllers return ShowOfficeDocument(org, pathPart, owaOpener.OwaEditor); } + #endregion private void FillContentModel(IEnumerable items, string organizationId) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs index 0aa9d823..f7a90c29 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs @@ -105,6 +105,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Create. + /// + public static string Create { + get { + return ResourceManager.GetString("Create", resourceCulture); + } + } + /// /// Looks up a localized string similar to Delete. /// @@ -141,6 +150,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Enter file name. + /// + public static string EnterFileName { + get { + return ResourceManager.GetString("EnterFileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. /// @@ -150,6 +168,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Excel workbook. + /// + public static string ExcelWorkbook { + get { + return ResourceManager.GetString("ExcelWorkbook", resourceCulture); + } + } + /// /// Looks up a localized string similar to File. /// @@ -159,6 +186,24 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File name. + /// + public static string FileName { + get { + return ResourceManager.GetString("FileName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File extension will be added automatically. + /// + public static string FileNameExtensionHint { + get { + return ResourceManager.GetString("FileNameExtensionHint", resourceCulture); + } + } + /// /// Looks up a localized string similar to File Upload. /// @@ -186,6 +231,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File already exist. + /// + public static string ItemExist { + get { + return ResourceManager.GetString("ItemExist", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} items was removed.. /// @@ -249,6 +303,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Powerpoint presentation. + /// + public static string PowerPointPresentation { + get { + return ResourceManager.GetString("PowerPointPresentation", resourceCulture); + } + } + /// /// Looks up a localized string similar to Processing. /// @@ -339,6 +402,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Word document. + /// + public static string WordDocument { + get { + return ResourceManager.GetString("WordDocument", resourceCulture); + } + } + /// /// Looks up a localized string similar to Yes. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx index 7d3fbf56..624df9ea 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx @@ -132,6 +132,9 @@ Confirm + + Create + Delete @@ -144,12 +147,24 @@ Are you sure you want to delete {0} item(s)? + + Enter file name + Error + + Excel workbook + File + + File name + + + File extension will be added automatically + File Upload @@ -159,6 +174,9 @@ Info + + File already exist + {0} items was removed. @@ -180,6 +198,9 @@ Please wait... + + Powerpoint presentation + Processing @@ -210,6 +231,9 @@ Upload + + Word document + Yes diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js index 25693b41..64823404 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js @@ -1,5 +1,9 @@ function WspDialogs() { - this.settings = { dialogId: "#confirm-dialog", processDialogId: "#processDialog" }; + this.settings = { + dialogId: "#confirm-dialog", + processDialogId: "#processDialog", + inlineProcessDialog: '.glyphicon-refresh' + }; } WspDialogs.prototype = @@ -36,6 +40,14 @@ WspDialogs.prototype = hideProcessDialog: function() { $(this.settings.processDialogId).modal('hide'); -} + }, + + showInlineProcessing: function(itemId) { + $(itemId).parent().find(this.settings.inlineProcessDialog).show(); + }, + + hideInlineProcessing: function (itemId) { + $(itemId).parent().find(this.settings.inlineProcessDialog).hide(); + } }; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js index f14edab4..114e103d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js @@ -2,8 +2,15 @@ this.settings = { deletionBlockSelector: ".file-actions-menu .file-deletion", deletionUrl: "storage/files-group-action/delete", + fileExistUrl: "storage/fileExist", textDateModified: "Date modified", - textSize: "Size" + textSize: "Size", + textItemExist: "File already exists", + textItemExistFunc: function() { + return textItemExist; + } , + createNewItemDialogId: "#createNewItemDialog", + createNewItemButtonId: "#create-button" }; this.itemsTable = null; this.searchTable = null; @@ -272,6 +279,38 @@ WspFileBrowser.prototype = { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]; + }, + + showCreateNewItemDialog: function (extension, target) { + $(this.settings.createNewItemButtonId).data('extension', extension); + $(this.settings.createNewItemButtonId).data('target', target); + + $(this.settings.createNewItemDialogId + " input").val(""); + + $(this.settings.createNewItemDialogId).modal(); + }, + + hideCreateNewItemDialog: function () { + $(this.settings.createNewItemDialogId).modal('hide'); + }, + + uniqueFileNameFieldRule: function(fieldId) { + + return { + url: this.settings.fileExistUrl, + type: "post", + data: { + newItemName: function() { + return $(fieldId).val() + $(wsp.fileBrowser.settings.createNewItemButtonId).data('extension'); + } + }, + beforeSend: function(response) { + wsp.dialogs.showInlineProcessing(fieldId); + }, + complete: function() { + wsp.dialogs.hideInlineProcessing(fieldId); + } + }; } }; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js index 41f36ed8..ce9fb0a4 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js @@ -78,6 +78,132 @@ $('#drag-and-drop-area #file-input').click(function (e) { }); + +$("#create-button").click(function (e) { + + if ($('#filenameForm').valid()) { + + var fileName = $('#createNewItemDialog #filename').val() + $(this).data('extension'); + + $(this).attr('href', $(this).data('href') + '/' + fileName); + + $(this).attr('target', $(this).data('target')); + + wsp.fileBrowser.hideCreateNewItemDialog(); + //; + } else { + e.preventDefault(); + } +}); + +$.fn.clearValidation = function () { var v = $(this).validate(); $('[name]', this).each(function () { v.successList.push(this); v.showErrors(); }); v.resetForm(); v.reset(); $(this).find('.form-group').removeClass('has-error'); }; + +$(document).ready(function() { + //bootstrap jquery validate styles fix + $.validator.setDefaults({ + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + errorElement: 'span', + errorClass: 'help-block', + errorPlacement: function(error, element) { + if (element.parent('.input-group').length) { + error.insertAfter(element.parent()); + } else { + error.insertAfter(element); + } + } + }); + + $.validator.addMethod("synchronousRemote", function (value, element, param) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name]) { + this.settings.messages[element.name] = {}; + } + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param === "string" && { url: param } || param; + + if (previous.old === value) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + var valid = "pending"; + $.ajax($.extend(true, { + url: param, + async: false, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function (response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + valid = response === true || response === "true"; + if (valid) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + delete validator.invalid[element.name]; + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage(element, "remote"); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.invalid[element.name] = true; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return valid; + }, "Please fix this field."); + + + $('#filenameForm').validate({ + onkeyup: false, + onclick: false, + async: false, + rules: { + filename: { + required: true, + synchronousRemote: wsp.fileBrowser.uniqueFileNameFieldRule("#filename") + } + }, + messages: { + filename: { + synchronousRemote: wsp.fileBrowser.settings.textItemExist + } + } + }); + +}); + + +$(".create-new-item li a").click(function () { + + $("#filenameForm").clearValidation(); + + wsp.fileBrowser.showCreateNewItemDialog($(this).data('extension'), $(this).data('target')); + + $("#filename").focus(); +}); + + function isMobileDevice() { return (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml index af490ffc..e62225b2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml @@ -26,7 +26,10 @@ else @section scripts{ @if (Model.UserSettings.WebDavViewType == FolderViewTypes.BigIcons) @@ -47,9 +50,37 @@ else { } } + +@section popups{ + +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml index 496ac682..fdba3215 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml @@ -56,6 +56,17 @@ data-target-title-text="@UI.DeleteFileQuestion" data-target-content="@UI.DialogsContentConfrimFileDeletion">@UI.Delete + } -} \ No newline at end of file +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config index 3f07e5e5..b33b3e60 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config @@ -85,13 +85,13 @@ - - - - - - - + + + + + + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj index 6ccbc782..8c5bfd40 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj @@ -369,6 +369,8 @@ + + @@ -376,6 +378,7 @@ +