U4-9849 Query Builder not working in template editor. Always returns Model.Content.Site().Children()

adding missing nullchecks in the endpoint action.
ensuring promise returns before setting init data - the unresolved promise was being used on the query model instead of the actual text string the promise returns - causing the endpoint to fail to bind the model.
This commit is contained in:
Claus
2017-05-04 15:08:37 +02:00
parent 751dc8df23
commit e7eaf6959f
2 changed files with 100 additions and 105 deletions

View File

@@ -1,14 +1,13 @@
(function () {
(function() {
"use strict";
function QueryBuilderOverlayController($scope, templateQueryResource, localizationService) {
var everything = localizationService.localize("template_allContent");
var myWebsite = localizationService.localize("template_websiteRoot");
var everything = "";
var myWebsite = "";
var ascendingTranslation = "";
var descendingTranslation = "";
var ascendingTranslation = localizationService.localize("template_ascending");
var descendingTranslation = localizationService.localize("template_descending");
var vm = this;
vm.properties = [];
@@ -21,34 +20,6 @@
format: "YYYY-MM-DD"
};
vm.query = {
contentType: {
name: everything
},
source: {
name: myWebsite
},
filters: [
{
property: undefined,
operator: undefined
}
],
sort: {
property: {
alias: "",
name: "",
},
direction: "ascending", //This is the value for sorting sent to server
translation: {
currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog
ascending: ascendingTranslation,
descending: descendingTranslation
}
}
};
vm.chooseSource = chooseSource;
vm.getPropertyOperators = getPropertyOperators;
vm.addFilter = addFilter;
@@ -63,21 +34,48 @@
function onInit() {
vm.query = {
contentType: {
name: everything
},
source: {
name: myWebsite
},
filters: [
{
property: undefined,
operator: undefined
}
],
sort: {
property: {
alias: "",
name: "",
},
direction: "ascending", //This is the value for sorting sent to server
translation: {
currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog
ascending: ascendingTranslation,
descending: descendingTranslation
}
}
};
templateQueryResource.getAllowedProperties()
.then(function (properties) {
.then(function(properties) {
vm.properties = properties;
});
templateQueryResource.getContentTypes()
.then(function (contentTypes) {
.then(function(contentTypes) {
vm.contentTypes = contentTypes;
});
templateQueryResource.getFilterConditions()
.then(function (conditions) {
.then(function(conditions) {
vm.conditions = conditions;
});
throttledFunc();
}
@@ -111,10 +109,11 @@
}
function getPropertyOperators(property) {
var conditions = _.filter(vm.conditions, function (condition) {
var index = condition.appliesTo.indexOf(property.type);
return index >= 0;
});
var conditions = _.filter(vm.conditions,
function(condition) {
var index = condition.appliesTo.indexOf(property.type);
return index >= 0;
});
return conditions;
}
@@ -123,10 +122,8 @@
}
function trashFilter(query, filter) {
for (var i = 0; i < query.filters.length; i++)
{
if (query.filters[i] == filter)
{
for (var i = 0; i < query.filters.length; i++) {
if (query.filters[i] == filter) {
query.filters.splice(i, 1);
}
}
@@ -173,7 +170,7 @@
function setFilterTerm(filter, term) {
filter.term = term;
if(filter.constraintValue) {
if (filter.constraintValue) {
throttledFunc();
}
}
@@ -183,22 +180,32 @@
}
function datePickerChange(event, filter) {
if(event.date && event.date.isValid()) {
if (event.date && event.date.isValid()) {
filter.constraintValue = event.date.format(vm.datePickerConfig.format);
throttledFunc();
}
}
var throttledFunc = _.throttle(function () {
templateQueryResource.postTemplateQuery(vm.query)
.then(function (response) {
$scope.model.result = response;
});
var throttledFunc = _.throttle(function() {
}, 200);
templateQueryResource.postTemplateQuery(vm.query)
.then(function(response) {
$scope.model.result = response;
});
onInit();
},
200);
localizationService.localizeMany([
"template_allContent", "template_websiteRoot", "template_ascending", "template_descending"
])
.then(function(res) {
everything = res[0];
myWebsite = res[1];
ascendingTranslation = res[2];
descendingTranslation = res[3];
onInit();
});
}
angular.module("umbraco").controller("Umbraco.Overlays.QueryBuilderController", QueryBuilderOverlayController);

View File

@@ -3,7 +3,6 @@ using System.Linq;
using System.Text;
using Umbraco.Core.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi.Filters;
using Umbraco.Web.WebApi;
using System;
using System.Diagnostics;
@@ -13,8 +12,6 @@ using Umbraco.Core.Services;
namespace Umbraco.Web.Editors
{
/// <summary>
/// The API controller used for building content queries within the template
/// </summary>
@@ -26,10 +23,9 @@ namespace Umbraco.Web.Editors
{ }
public TemplateQueryController(UmbracoContext umbracoContext)
:base(umbracoContext)
: base(umbracoContext)
{ }
private IEnumerable<OperathorTerm> Terms
{
get
@@ -77,20 +73,19 @@ namespace Umbraco.Web.Editors
var sb = new StringBuilder();
var indention = Environment.NewLine + "\t\t\t\t\t\t";
sb.Append("Model.Content.Site()");
var timer = new Stopwatch();
timer.Start();
var currentPage = umbraco.TypedContentAtRoot().FirstOrDefault();
timer.Stop();
var pointerNode = currentPage;
// adjust the "FROM"
if (model != null && model.Source.Id > 0)
if (model != null && model.Source != null && model.Source.Id > 0)
{
var targetNode = umbraco.TypedContent(model.Source.Id);
@@ -120,10 +115,10 @@ namespace Umbraco.Web.Editors
}
}
}
// TYPE to return if filtered by type
// TYPE to return if filtered by type
IEnumerable<IPublishedContent> contents;
if (model != null && string.IsNullOrEmpty(model.ContentType.Alias) == false)
if (model != null && model.ContentType != null && string.IsNullOrEmpty(model.ContentType.Alias) == false)
{
timer.Start();
@@ -154,13 +149,13 @@ namespace Umbraco.Web.Editors
foreach (var condition in model.Filters)
{
if(string.IsNullOrEmpty( condition.ConstraintValue)) continue;
if (string.IsNullOrEmpty(condition.ConstraintValue)) continue;
//x is passed in as the parameter alias for the linq where statement clause
var operation = condition.BuildCondition("x");
var tokenizedOperation = condition.BuildTokenizedCondition(token);
clause = string.IsNullOrEmpty(clause) ? operation : string.Concat(new[] { clause, " && ", operation });
clause = string.IsNullOrEmpty(clause) ? operation : string.Concat(new[] { clause, " && ", operation });
tokenizedClause = string.IsNullOrEmpty(tokenizedClause) ? tokenizedOperation : string.Concat(new[] { tokenizedClause, " && ", tokenizedOperation });
token++;
@@ -168,7 +163,6 @@ namespace Umbraco.Web.Editors
if (string.IsNullOrEmpty(clause) == false)
{
timer.Start();
//trial-run the tokenized clause to time the execution
@@ -178,14 +172,13 @@ namespace Umbraco.Web.Editors
timer.Stop();
//the query to output to the editor
sb.Append(indention);
sb.Append(".Where(x => x.IsVisible())");
sb.Append(indention);
sb.AppendFormat(".Where(x => {0})", clause);
}
else
{
@@ -197,7 +190,6 @@ namespace Umbraco.Web.Editors
sb.Append(indention);
sb.Append(".Where(x => x.IsVisible())");
}
if (model.Sort != null && string.IsNullOrEmpty(model.Sort.Property.Alias) == false)
@@ -231,20 +223,19 @@ namespace Umbraco.Web.Editors
queryResult.ExecutionTime = timer.ElapsedMilliseconds;
queryResult.ResultCount = contents.Count();
queryResult.SampleResults = contents.Take(20).Select(x => new TemplateQueryResult()
{
Icon = "icon-file",
Name = x.Name
});
{
Icon = "icon-file",
Name = x.Name
});
return queryResult;
return queryResult;
}
private object GetConstraintValue(QueryCondition condition)
{
switch (condition.Property.Type)
{
case "int" :
case "int":
return int.Parse(condition.ConstraintValue);
case "datetime":
DateTime dt;
@@ -254,42 +245,41 @@ namespace Umbraco.Web.Editors
}
}
private IEnumerable<IPublishedContent> SortByDefaultPropertyValue(IEnumerable<IPublishedContent> contents, SortExpression sortExpression)
private IEnumerable<IPublishedContent> SortByDefaultPropertyValue(IEnumerable<IPublishedContent> contents, SortExpression sortExpression)
{
switch (sortExpression.Property.Alias)
{
case "id" :
case "id":
return sortExpression.Direction == "ascending"
? contents.OrderBy(x => x.Id)
: contents.OrderByDescending(x => x.Id);
case "createDate" :
? contents.OrderBy(x => x.Id)
: contents.OrderByDescending(x => x.Id);
case "createDate":
return sortExpression.Direction == "ascending"
? contents.OrderBy(x => x.CreateDate)
: contents.OrderByDescending(x => x.CreateDate);
? contents.OrderBy(x => x.CreateDate)
: contents.OrderByDescending(x => x.CreateDate);
case "publishDate":
return sortExpression.Direction == "ascending"
? contents.OrderBy(x => x.UpdateDate)
: contents.OrderByDescending(x => x.UpdateDate);
? contents.OrderBy(x => x.UpdateDate)
: contents.OrderByDescending(x => x.UpdateDate);
case "name":
return sortExpression.Direction == "ascending"
? contents.OrderBy(x => x.Name)
: contents.OrderByDescending(x => x.Name);
default :
? contents.OrderBy(x => x.Name)
: contents.OrderByDescending(x => x.Name);
default:
return sortExpression.Direction == "ascending"
? contents.OrderBy(x => x.Name)
: contents.OrderByDescending(x => x.Name);
? contents.OrderBy(x => x.Name)
: contents.OrderByDescending(x => x.Name);
}
}
private IEnumerable<string> GetChildContentTypeAliases(IPublishedContent targetNode, IPublishedContent current)
{
var aliases = new List<string>();
if (targetNode.Id == current.Id) return aliases;
if (targetNode == null || targetNode.Id == current.Id) return aliases;
if (targetNode.Id != current.Id)
{
aliases.Add(targetNode.DocumentTypeAlias);
@@ -309,7 +299,7 @@ namespace Umbraco.Web.Editors
{
var contentTypes =
ApplicationContext.Services.ContentTypeService.GetAllContentTypes()
.Select(x => new ContentTypeModel() { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name } ) })
.Select(x => new ContentTypeModel() { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name }) })
.OrderBy(x => x.Name).ToList();
contentTypes.Insert(0, new ContentTypeModel() { Alias = string.Empty, Name = Services.TextService.Localize("template/allContent") });
@@ -332,7 +322,5 @@ namespace Umbraco.Web.Editors
{
return Terms;
}
}
}