diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js index d69777464c..cec9cf191e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js @@ -3,17 +3,17 @@ * @name umbraco.resources.contentTypeResource * @description Loads in data for content types **/ -function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { +function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, localizationService, notificationsService) { return { getCount: function () { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetCount")), - 'Failed to retrieve count'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetCount")), + 'Failed to retrieve count'); }, getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes) { @@ -31,32 +31,32 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { }; return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetAvailableCompositeContentTypes"), - query), - 'Failed to retrieve data for content type id ' + contentTypeId); + $http.post( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetAvailableCompositeContentTypes"), + query), + 'Failed to retrieve data for content type id ' + contentTypeId); }, - /** - * @ngdoc method - * @name umbraco.resources.contentTypeResource#getWhereCompositionIsUsedInContentTypes - * @methodOf umbraco.resources.contentTypeResource - * - * @description - * Returns a list of content types which use a specific composition with a given id - * - * ##usage - *
-         * contentTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
-         *    .then(function(contentTypeList) {
-         *        console.log(contentTypeList);
-         *    });
-         * 
- * @param {Int} contentTypeId id of the composition content type to retrieve the list of the content types where it has been used - * @returns {Promise} resourcePromise object. - * - */ + /** + * @ngdoc method + * @name umbraco.resources.contentTypeResource#getWhereCompositionIsUsedInContentTypes + * @methodOf umbraco.resources.contentTypeResource + * + * @description + * Returns a list of content types which use a specific composition with a given id + * + * ##usage + *
+        * contentTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
+        *    .then(function(contentTypeList) {
+        *        console.log(contentTypeList);
+        *    });
+        * 
+ * @param {Int} contentTypeId id of the composition content type to retrieve the list of the content types where it has been used + * @returns {Promise} resourcePromise object. + * + */ getWhereCompositionIsUsedInContentTypes: function (contentTypeId) { var query = { contentTypeId: contentTypeId @@ -92,12 +92,12 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { getAllowedTypes: function (contentTypeId) { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetAllowedChildren", - [{ contentId: contentTypeId }])), - 'Failed to retrieve data for content id ' + contentTypeId); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetAllowedChildren", + [{ contentId: contentTypeId }])), + 'Failed to retrieve data for content id ' + contentTypeId); }, @@ -115,64 +115,64 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { getAllPropertyTypeAliases: function () { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetAllPropertyTypeAliases")), - 'Failed to retrieve property type aliases'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetAllPropertyTypeAliases")), + 'Failed to retrieve property type aliases'); }, getAllStandardFields: function () { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetAllStandardFields")), - 'Failed to retrieve standard fields'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetAllStandardFields")), + 'Failed to retrieve standard fields'); }, - getPropertyTypeScaffold : function (id) { - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetPropertyTypeScaffold", - [{ id: id }])), - 'Failed to retrieve property type scaffold'); + getPropertyTypeScaffold: function (id) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetPropertyTypeScaffold", + [{ id: id }])), + 'Failed to retrieve property type scaffold'); }, getById: function (id) { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetById", - [{ id: id }])), - 'Failed to retrieve content type'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetById", + [{ id: id }])), + 'Failed to retrieve content type'); }, deleteById: function (id) { return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "DeleteById", - [{ id: id }])), - 'Failed to delete content type'); + $http.post( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "DeleteById", + [{ id: id }])), + 'Failed to delete content type'); }, deleteContainerById: function (id) { return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "DeleteContainer", - [{ id: id }])), - 'Failed to delete content type contaier'); + $http.post( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "DeleteContainer", + [{ id: id }])), + 'Failed to delete content type contaier'); }, /** @@ -189,21 +189,21 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { getAll: function () { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetAll")), - 'Failed to retrieve all content types'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetAll")), + 'Failed to retrieve all content types'); }, getScaffold: function (parentId) { return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "contentTypeApiBaseUrl", - "GetEmpty", { parentId: parentId })), - 'Failed to retrieve content type scaffold'); + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetEmpty", { parentId: parentId })), + 'Failed to retrieve content type scaffold'); }, /** @@ -223,7 +223,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { var saveModel = umbDataFormatter.formatContentTypePostData(contentType); return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostSave"), saveModel), + $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostSave"), saveModel), 'Failed to save data for content type id ' + contentType.id); }, @@ -270,7 +270,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { 'Failed to move content'); }, - copy: function(args) { + copy: function (args) { if (!args) { throw "args cannot be null"; } @@ -301,12 +301,12 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { createCollection: function (parentId, collectionName, collectionItemName, collectionIcon, collectionItemIcon) { return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateCollection", { parentId: parentId, collectionName: collectionName, collectionItemName: collectionItemName, collectionIcon: collectionIcon, collectionItemIcon: collectionItemIcon})), + $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateCollection", { parentId: parentId, collectionName: collectionName, collectionItemName: collectionItemName, collectionIcon: collectionIcon, collectionItemIcon: collectionItemIcon })), 'Failed to create collection under ' + parentId); }, - renameContainer: function(id, name) { + renameContainer: function (id, name) { return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", @@ -315,8 +315,25 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { "Failed to rename the folder with id " + id ); - } + }, + export: function (id) { + if (!id) { + throw "id cannot be null"; + } + + var url = umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "Export", { id: id }); + + return umbRequestHelper.downloadFile(url).then(function () { + localizationService.localize("speechBubbles_documentTypeExportedSuccess").then(function(value) { + notificationsService.success(value); + }); + }, function (data) { + localizationService.localize("speechBubbles_documentTypeExportedError").then(function(value) { + notificationsService.error(value); + }); + }); + } }; } angular.module('umbraco.resources').factory('contentTypeResource', contentTypeResource); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.controller.js new file mode 100644 index 0000000000..630dfb3f7f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.controller.js @@ -0,0 +1,13 @@ +angular.module("umbraco") + .controller("Umbraco.Editors.DocumentTypes.ExportController", + function ($scope, contentTypeResource, navigationService) { + + $scope.export = function () { + contentTypeResource.export($scope.currentNode.id); + navigationService.hideMenu(); + }; + + $scope.cancel = function () { + navigationService.hideDialog(); + }; + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.html new file mode 100644 index 0000000000..54c7ff0efe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/export.html @@ -0,0 +1,10 @@ +
+ +
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index eb634e3f88..db6d974fc2 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -402,7 +402,6 @@ - diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index ee18248997..3de05dbbbf 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1445,6 +1445,8 @@ To manage your website, simply open the Umbraco back office and start adding con User %0% was deleted Invite user Invitation has been re-sent to %0% + Document type was exported to file + An error occurred while exporting the document type Uses CSS syntax ex: h1, .redHeader, .blueTex diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index e61c406fae..0ecfb9c979 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1455,6 +1455,8 @@ To manage your website, simply open the Umbraco back office and start adding con Cannot publish the document since the required '%0%' is not published Validation failed for language '%0%' Unexpected validation failed for language '%0%' + Document type was exported to file + An error occurred while exporting the document type Uses CSS syntax ex: h1, .redHeader, .blueTex diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/exportDocumenttype.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/exportDocumenttype.aspx deleted file mode 100644 index ebcf851369..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/exportDocumenttype.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page language="c#" Codebehind="exportDocumenttype.aspx.cs" AutoEventWireup="false" Inherits="umbraco.presentation.dialogs.exportDocumenttype" %> diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js index 9001980354..2ee35ee696 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js +++ b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js @@ -302,14 +302,6 @@ Umbraco.Application.Actions = function() { } }, - actionExport: function() { - /// - - if (UmbClientMgr.mainTree().getActionNode().nodeType != '') { - this.openDialog("Export", "dialogs/exportDocumentType.aspx?nodeId=" + UmbClientMgr.mainTree().getActionNode().nodeId + "&rnd=" + this._utils.generateRandom(), 320, 205); - } - }, - actionAudit: function() { /// diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 7365c4f4f3..4bd74bcbd3 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -1,20 +1,21 @@ -using System.Collections.Generic; +using AutoMapper; +using System; +using System.Collections.Generic; using System.Linq; using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; using System.Web.Http; -using AutoMapper; +using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; -using Constants = Umbraco.Core.Constants; -using Umbraco.Core.Services; -using System.Net.Http; -using Umbraco.Core; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; -using Umbraco.Core.Logging; -using Umbraco.Web.Composing; -using ContentVariation = Umbraco.Core.Models.ContentVariation; +using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Editors { @@ -406,5 +407,39 @@ namespace Umbraco.Web.Editors getContentType: i => Services.ContentTypeService.Get(i), doCopy: (type, i) => Services.ContentTypeService.Copy(type, i)); } + + [HttpGet] + public HttpResponseMessage Export(int id) + { + var contentType = Services.ContentTypeService.Get(id); + if (contentType == null) throw new NullReferenceException("No content type found with id " + id); + + var serializer = new EntityXmlSerializer(); + var xml = serializer.Serialize( + Services.DataTypeService, + Services.ContentTypeService, + contentType); + + var response = new HttpResponseMessage + { + Content = new StringContent(xml.ToDataString()) + { + Headers = + { + ContentDisposition = new ContentDispositionHeaderValue("attachment") + { + FileName = $"{contentType.Alias}.udt" + }, + ContentType = new MediaTypeHeaderValue( "application/octet-stream") + + } + } + }; + + // Set custom header so umbRequestHelper.downloadFile can save the correct filename + response.Headers.Add("x-filename", $"{contentType.Alias}.udt"); + + return response; + } } } diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index 4bdef0246a..1295f32dd6 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -1,17 +1,17 @@ -using System; +using AutoMapper; +using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Formatting; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; +using Umbraco.Core.Services; +using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web._Legacy.Actions; namespace Umbraco.Web.Trees { @@ -132,13 +132,7 @@ namespace Umbraco.Web.Trees } } menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias))); - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true).ConvertLegacyMenuItem(new EntitySlim - { - Id = int.Parse(id), - Level = 1, - ParentId = Constants.System.Root, - Name = "" - }, "documenttypes", "settings"); + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true); menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); if (enableInheritedDocumentTypes) menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index bfb3c12922..f483b69b5d 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -2,22 +2,15 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http.Formatting; -using System.Text; -using System.Web; using System.Web.Http.Routing; +using umbraco.cms.presentation.Trees; using Umbraco.Core; -using Umbraco.Core.IO; +using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Services; -using Umbraco.Web.Models.Trees; -using umbraco; - -using umbraco.cms.presentation.Trees; -using umbraco.controls.Tree; -using Umbraco.Core.Configuration; -using Umbraco.Core.Models; -using Umbraco.Web.Composing; using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Composing; +using Umbraco.Web.Models.Trees; namespace Umbraco.Web.Trees { @@ -280,11 +273,6 @@ namespace Umbraco.Web.Trees new LegacyUrlAction( "dialogs/importDocumentType.aspx", Current.Services.TextService.Localize("actions/importDocumentType"))); - case "UmbClientMgr.appActions().actionExport()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/exportDocumentType.aspx?nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - "")); case "UmbClientMgr.appActions().actionAudit()": return Attempt.Succeed( new LegacyUrlAction( diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0c76aedc80..437a027763 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1299,10 +1299,6 @@ editPackage.aspx - - exportDocumenttype.aspx - ASPXCodeBehind - importDocumenttype.aspx ASPXCodeBehind @@ -1500,7 +1496,6 @@ ASPXCodeBehind - ASPXCodeBehind @@ -1589,5 +1584,5 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs b/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs index ef4f79739e..df78026ea0 100644 --- a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs +++ b/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs @@ -1,5 +1,4 @@ using System; -using Umbraco.Web.UI.Pages; namespace Umbraco.Web._Legacy.Actions { @@ -30,10 +29,7 @@ namespace Umbraco.Web._Legacy.Actions public string JsFunctionName { - get - { - return string.Format("{0}.actionExport()", ClientTools.Scripts.GetAppActions); - } + get { return ""; } } public string JsSource @@ -48,7 +44,7 @@ namespace Umbraco.Web._Legacy.Actions { get { - return "exportDocumentType"; + return "export"; } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx deleted file mode 100644 index ebcf851369..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page language="c#" Codebehind="exportDocumenttype.aspx.cs" AutoEventWireup="false" Inherits="umbraco.presentation.dialogs.exportDocumenttype" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx.cs deleted file mode 100644 index b50b46544d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/exportDocumenttype.aspx.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Services; -using Umbraco.Web; - -namespace umbraco.presentation.dialogs -{ - /// - /// Summary description for exportDocumenttype. - /// - public class exportDocumenttype : Umbraco.Web.UI.Pages.UmbracoEnsuredPage - { - public exportDocumenttype() - { - CurrentApp = Constants.Applications.Settings.ToString(); - - } - private void Page_Load(object sender, System.EventArgs e) - { - int documentTypeId = Request.GetItemAs("nodeID"); - if (documentTypeId > 0) - { - var contentType = Services.ContentTypeService.Get(documentTypeId); - if (contentType == null) throw new NullReferenceException("No content type found with id " + documentTypeId); - - Response.AddHeader("Content-Disposition", "attachment;filename=" + contentType.Alias + ".udt"); - Response.ContentType = "application/octet-stream"; - - var serializer = new EntityXmlSerializer(); - var xml = serializer.Serialize( - Services.DataTypeService, - Services.ContentTypeService, - contentType); - - xml.Save(Response.OutputStream); - } - } - - #region Web Form Designer generated code - override protected void OnInit(EventArgs e) - { - // - // CODEGEN: This call is required by the ASP.NET Web Form Designer. - // - InitializeComponent(); - base.OnInit(e); - } - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.Load += new System.EventHandler(this.Page_Load); - } - #endregion - } -}