Merge remote-tracking branch 'origin/temp-content-blueprints' into temp-content-blueprints

This commit is contained in:
Lars-Erik Aabech
2017-06-04 22:58:13 +02:00
13 changed files with 130 additions and 33 deletions

View File

@@ -43,7 +43,7 @@ namespace Umbraco.Core.Models
/// </summary>
[UmbracoObjectType(Constants.ObjectTypes.DocumentBlueprint, typeof(IContent))]
[FriendlyName("DocumentBlueprint")]
[UmbracoUdiType(Constants.UdiEntityType.Document)]
[UmbracoUdiType(Constants.UdiEntityType.DocumentBluePrint)]
DocumentBlueprint,
/// <summary>

View File

@@ -289,7 +289,7 @@ namespace Umbraco.Core.Persistence.Repositories
//now delete the items that shouldn't be there
var sqlAllIds = translate(0, GetBaseQuery(BaseQueryType.Ids));
var allContentIds = Database.Fetch<int>(sqlAllIds);
var docObjectType = Guid.Parse(Constants.ObjectTypes.Document);
var docObjectType = NodeObjectTypeId;
var xmlIdsQuery = new Sql()
.Select("DISTINCT cmsContentXml.nodeId")
.From<ContentXmlDto>(SqlSyntax)
@@ -820,7 +820,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
XmlElement last = null;
//NOTE: Query creates a reader - does not load all into memory
foreach (var row in Database.Query<dynamic>(sql, new { type = new Guid(Constants.ObjectTypes.Document) }))
foreach (var row in Database.Query<dynamic>(sql, new { type = NodeObjectTypeId }))
{
string parentId = ((int)row.parentID).ToInvariantString();
string xml = row.xml;

View File

@@ -110,6 +110,19 @@ namespace Umbraco.Core.Persistence.Repositories
return Database.Fetch<string>(sql);
}
public IEnumerable<int> GetAllContentTypeIds(string[] aliases)
{
if (aliases.Length == 0) return Enumerable.Empty<int>();
var sql = new Sql().Select("cmsContentType.nodeId")
.From<ContentTypeDto>(SqlSyntax)
.InnerJoin<NodeDto>(SqlSyntax)
.On<ContentTypeDto, NodeDto>(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId)
.Where<ContentTypeDto>(dto => aliases.Contains(dto.Alias), SqlSyntax);
return Database.Fetch<int>(sql);
}
protected override Sql GetBaseQuery(bool isCount)
{
var sql = new Sql();

View File

@@ -47,5 +47,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns>The original alias with a number appended to it, so that it is unique.</returns>
/// /// <remarks>Unique accross all content, media and member types.</remarks>
string GetUniqueAlias(string alias);
IEnumerable<int> GetAllContentTypeIds(string[] aliases);
}
}

View File

@@ -367,6 +367,15 @@ namespace Umbraco.Core.Services
}
}
public IEnumerable<int> GetAllContentTypeIds(string[] aliases)
{
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.GetAllContentTypeIds(aliases);
}
}
/// <summary>
/// Copies a content type as a child under the specified parent if specified (otherwise to the root)
/// </summary>

View File

@@ -61,6 +61,13 @@ namespace Umbraco.Core.Services
/// </param>
/// <returns></returns>
IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes);
/// <summary>
/// Returns all content type Ids for the aliases given
/// </summary>
/// <param name="aliases"></param>
/// <returns></returns>
IEnumerable<int> GetAllContentTypeIds(string[] aliases);
/// <summary>
/// Copies a content type as a child under the specified parent if specified (otherwise to the root)

View File

@@ -14,7 +14,7 @@
scope.page.menu.currentNode = null;
scope.page.menu.currentSection = appState.getSectionState("currentSection");
scope.page.listViewPath = null;
scope.page.isNew = scope.createOptions ? true : false;
scope.page.isNew = scope.isNew ? true : false;
scope.page.buttonGroupState = "init";
function init(content) {
@@ -116,7 +116,7 @@
scope.page.loading = true;
//we are creating so get an empty content item
contentResource.getScaffold(scope.contentId, scope.createOptions.docType)
scope.getScaffoldMethod()()
.then(function (data) {
scope.content = data;
@@ -230,11 +230,12 @@
templateUrl: 'views/components/content/edit.html',
scope: {
contentId: "=",
isNew: "=?",
treeAlias: "@",
createOptions: "=?",
page: "=?",
saveMethod: "&",
getMethod: "&"
getMethod: "&",
getScaffoldMethod: "&?"
},
link: link
};

View File

@@ -399,6 +399,17 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
'Failed to retrieve data for empty content item type ' + alias);
},
getBlueprintScaffold: function (blueprintId) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetEmpty",
[{ blueprintId: blueprintId }])),
'Failed to retrieve blueprint for id ' + blueprintId);
},
/**
* @ngdoc method
* @name umbraco.resources.contentResource#getNiceUrl

View File

@@ -770,9 +770,9 @@ function umbDataFormatter() {
var propTemplate = _.find(genericTab.properties, function (item) {
return item.alias === "_umb_template";
});
saveModel.expireDate = propExpireDate.value;
saveModel.releaseDate = propReleaseDate.value;
saveModel.templateAlias = propTemplate.value;
saveModel.expireDate = propExpireDate ? propExpireDate.value : null;
saveModel.releaseDate = propReleaseDate ? propReleaseDate.value : null;
saveModel.templateAlias = propTemplate ? propTemplate.value : null;
return saveModel;
}

View File

@@ -8,16 +8,19 @@
*/
function ContentEditController($scope, $routeParams, contentResource) {
function scaffoldEmpty() {
return contentResource.getScaffold($routeParams.id, $routeParams.doctype);
}
function scaffoldBlueprint() {
return contentResource.getBlueprintScaffold($routeParams.blueprintId);
}
$scope.contentId = $routeParams.id;
$scope.saveMethod = contentResource.save;
$scope.getMethod = contentResource.getById;
$scope.getScaffoldMethod = $routeParams.blueprintId ? scaffoldBlueprint : scaffoldEmpty;
$scope.page = $routeParams.page;
$scope.createOptions = null;
if ($routeParams.create && $routeParams.doctype) {
$scope.createOptions = {
docType: $routeParams.doctype
}
}
$scope.isNew = $routeParams.create;
}
angular.module("umbraco").controller("Umbraco.Editors.Content.EditController", ContentEditController);

View File

@@ -4,6 +4,8 @@
page="page"
save-method="saveMethod"
get-method="getMethod"
tree-alias="content">
get-scaffold-method="getScaffoldMethod"
tree-alias="content"
is-new="isNew">
</content-editor>
</div>

View File

@@ -115,6 +115,11 @@ namespace Umbraco.Web.Editors
var content = Mapper.Map<IContent, ContentItemDisplay>(foundContent);
content.AllowPreview = false;
//set a custom path since the tree that renders this has the content type id as the parent
content.Path = string.Format("-1,{0},{1}", foundContent.ContentTypeId, content.Id);
content.AllowedActions = new[] {'A'};
var excludeProps = new[] {"_umb_urls", "_umb_releasedate", "_umb_expiredate", "_umb_template"};
@@ -184,6 +189,26 @@ namespace Umbraco.Web.Editors
return mapped;
}
[OutgoingEditorModelEvent]
public ContentItemDisplay GetEmpty(int blueprintId)
{
var blueprint = Services.ContentService.GetBlueprintById(blueprintId);
if (blueprint == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
blueprint.Id = 0;
blueprint.Name = string.Empty;
var mapped = Mapper.Map<ContentItemDisplay>(blueprint);
//remove this tab if it exists: umbContainerView
var containerTab = mapped.Tabs.FirstOrDefault(x => x.Alias == Constants.Conventions.PropertyGroups.ListViewGroupName);
mapped.Tabs = mapped.Tabs.Except(new[] { containerTab });
return mapped;
}
/// <summary>
/// Gets the Url for a given node ID
/// </summary>

View File

@@ -35,28 +35,48 @@ namespace Umbraco.Web.Trees
{
var nodes = new TreeNodeCollection();
//check if we're rendering the root
//get all blueprints
var entities = Services.EntityService.GetChildren(Constants.System.Root, UmbracoObjectTypes.DocumentBlueprint).ToArray();
//check if we're rendering the root in which case we'll render the content types that have blueprints
if (id == Constants.System.Root.ToInvariantString())
{
var altStartId = string.Empty;
//get all blueprint content types
var contentTypeAliases = entities.Select(x => ((UmbracoEntity) x).ContentTypeAlias).Distinct();
//get the ids
var contentTypeIds = Services.ContentTypeService.GetAllContentTypeIds(contentTypeAliases.ToArray());
//now get the entities ... it's a bit round about but still smaller queries than getting all document types
var docTypeEntities = Services.EntityService.GetAll(UmbracoObjectTypes.DocumentType, contentTypeIds.ToArray()).ToArray();
if (queryStrings.HasKey(TreeQueryStringParameters.StartNodeId))
altStartId = queryStrings.GetValue<string>(TreeQueryStringParameters.StartNodeId);
//check if a request has been made to render from a specific start node
if (string.IsNullOrEmpty(altStartId) == false && altStartId != "undefined" && altStartId != Constants.System.Root.ToString(CultureInfo.InvariantCulture))
{
id = altStartId;
}
var entities = Services.EntityService.GetChildren(Constants.System.Root, UmbracoObjectTypes.DocumentBlueprint).ToArray();
nodes.AddRange(entities
.Select(entity => CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprintGuid, id, queryStrings, "icon-blueprint", false))
.Where(node => node != null));
nodes.AddRange(docTypeEntities
.Select(entity =>
{
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprintGuid, id, queryStrings, "icon-item-arrangement", true);
treeNode.Path = string.Format("-1,{0}", entity.Id);
treeNode.NodeType = "contentType";
//TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
treeNode.AdditionalData["jsClickCallback"] = "javascript:void(0);";
return treeNode;
}));
return nodes;
}
else
{
var intId = id.TryConvertTo<int>();
//Get the content type
var ct = Services.ContentTypeService.GetContentType(intId.Result);
if (ct == null) return nodes;
var blueprintsForDocType = entities.Where(x => ct.Alias == ((UmbracoEntity) x).ContentTypeAlias);
nodes.AddRange(blueprintsForDocType
.Select(entity =>
{
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprintGuid, id, queryStrings, "icon-blueprint", false);
treeNode.Path = string.Format("-1,{0},{1}", ct.Id, entity.Id);
return treeNode;
}));
}
return nodes;
}
@@ -71,9 +91,13 @@ namespace Umbraco.Web.Trees
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
return menu;
}
var ct = Services.EntityService.Get(int.Parse(id), UmbracoObjectTypes.DocumentType);
//no menu if it's a content type
if (ct != null) return null;
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
return menu;
}