Merge pull request #2756 from kows/hackathon-export-doc-type-to-angular

Rewrite exportdocumenttype.aspx to Angular [v8hackaton]
This commit is contained in:
Sebastiaan Janssen
2018-07-25 12:13:52 +02:00
committed by GitHub
15 changed files with 189 additions and 207 deletions

View File

@@ -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
* <pre>
* contentTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
* .then(function(contentTypeList) {
* console.log(contentTypeList);
* });
* </pre>
* @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
* <pre>
* contentTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
* .then(function(contentTypeList) {
* console.log(contentTypeList);
* });
* </pre>
* @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);

View File

@@ -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();
};
});

View File

@@ -0,0 +1,10 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.DocumentTypes.ExportController">
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
<a class="btn btn-link" ng-click="nav.hideDialog()">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="export()">
<localize key="actions_export">Export</localize>
</button>
</div>
</div>

View File

@@ -402,7 +402,6 @@
<Content Include="Umbraco\Developer\Packages\directoryBrowser.aspx" />
<Content Include="Umbraco\Developer\Packages\editPackage.aspx" />
<Content Include="Umbraco\Dialogs\create.aspx" />
<Content Include="Umbraco\Dialogs\exportDocumenttype.aspx" />
<Content Include="Umbraco\Dialogs\importDocumenttype.aspx" />
<Content Include="Umbraco\Dialogs\notifications.aspx" />
<Content Include="Umbraco\Dialogs\protectPage.aspx" />

View File

@@ -1445,6 +1445,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="deleteUserSuccess">User %0% was deleted</key>
<key alias="resendInviteHeader">Invite user</key>
<key alias="resendInviteSuccess">Invitation has been re-sent to %0%</key>
<key alias="documentTypeExportedSuccess">Document type was exported to file</key>
<key alias="documentTypeExportedError">An error occurred while exporting the document type</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>

View File

@@ -1455,6 +1455,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="contentReqCulturePublishError">Cannot publish the document since the required '%0%' is not published</key>
<key alias="contentCultureValidationError">Validation failed for language '%0%'</key>
<key alias="contentCultureUnexpectedValidationError">Unexpected validation failed for language '%0%'</key>
<key alias="documentTypeExportedSuccess">Document type was exported to file</key>
<key alias="documentTypeExportedError">An error occurred while exporting the document type</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>

View File

@@ -1 +0,0 @@
<%@ Page language="c#" Codebehind="exportDocumenttype.aspx.cs" AutoEventWireup="false" Inherits="umbraco.presentation.dialogs.exportDocumenttype" %>

View File

@@ -302,14 +302,6 @@ Umbraco.Application.Actions = function() {
}
},
actionExport: function() {
/// <summary></summary>
if (UmbClientMgr.mainTree().getActionNode().nodeType != '') {
this.openDialog("Export", "dialogs/exportDocumentType.aspx?nodeId=" + UmbClientMgr.mainTree().getActionNode().nodeId + "&rnd=" + this._utils.generateRandom(), 320, 205);
}
},
actionAudit: function() {
/// <summary></summary>

View File

@@ -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;
}
}
}

View File

@@ -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<ActionCopy>(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias)));
menu.Items.Add<ActionExport>(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<ActionExport>(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true);
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
if (enableInheritedDocumentTypes)
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);

View File

@@ -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(

View File

@@ -1299,10 +1299,6 @@
<Compile Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx.designer.cs">
<DependentUpon>editPackage.aspx</DependentUpon>
</Compile>
<Compile Include="umbraco.presentation\umbraco\dialogs\exportDocumenttype.aspx.cs">
<DependentUpon>exportDocumenttype.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="umbraco.presentation\umbraco\dialogs\importDocumenttype.aspx.cs">
<DependentUpon>importDocumenttype.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -1500,7 +1496,6 @@
<Content Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx">
<SubType>ASPXCodeBehind</SubType>
</Content>
<Content Include="umbraco.presentation\umbraco\dialogs\exportDocumenttype.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\importDocumenttype.aspx" />
<Content Include="umbraco.presentation\umbraco\dialogs\notifications.aspx">
<SubType>ASPXCodeBehind</SubType>
@@ -1589,5 +1584,5 @@
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(IntermediateOutputPath)" References="@(FixedReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="$(SGenUseProxyTypes)" UseKeep="$(SGenUseKeep)" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)" SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" EnvironmentVariables="$(SGenEnvironment)" MSBuildArchitecture="$(SGenMSBuildArchitecture)" SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)" Platform="$(SGenPlatformTarget)" Types="$(SGenSerializationTypes)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
</Target>
</Target>
</Project>

View File

@@ -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";
}
}

View File

@@ -1 +0,0 @@
<%@ Page language="c#" Codebehind="exportDocumenttype.aspx.cs" AutoEventWireup="false" Inherits="umbraco.presentation.dialogs.exportDocumenttype" %>

View File

@@ -1,59 +0,0 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Services;
using Umbraco.Web;
namespace umbraco.presentation.dialogs
{
/// <summary>
/// Summary description for exportDocumenttype.
/// </summary>
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<int>("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);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}