Merge remote-tracking branch 'origin/temp-content-blueprints' into temp-content-blueprints
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user