diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj index f474e79876..64fef90ffa 100644 --- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj +++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj @@ -116,7 +116,6 @@ - @@ -136,10 +135,6 @@ - - - - diff --git a/src/Umbraco.Web.UI.Client/src/common/services/search.service.js b/src/Umbraco.Web.UI.Client/src/common/services/search.service.js index ad30e48335..c692fda7ba 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/search.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/search.service.js @@ -120,8 +120,12 @@ angular.module('umbraco.services') return entityResource.searchAll(args.term, args.canceler).then(function (data) { _.each(data, function (resultByType) { - + + //we need to format the search result data to include things like the subtitle, urls, etc... + // this is done with registered angular services as part of the SearchableTreeAttribute, if that + // is not found, than we format with the default formatter var formatterMethod = searchResultFormatter.configureDefaultResult; + //check if a custom formatter is specified... if (resultByType.jsSvc) { var searchFormatterService = $injector.get(resultByType.jsSvc); if (searchFormatterService) { @@ -135,10 +139,11 @@ angular.module('umbraco.services') } } } - + //now apply the formatter for each result _.each(resultByType.results, function (item) { formatterMethod.apply(this, [item, resultByType.treeAlias, resultByType.appAlias]); - }); + }); + }); return data; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/searchresultformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/searchresultformatter.service.js new file mode 100644 index 0000000000..9bf9f3762c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/searchresultformatter.service.js @@ -0,0 +1,37 @@ + +function searchResultFormatter(umbRequestHelper) { + + function configureDefaultResult(content, treeAlias, appAlias) { + content.editorPath = appAlias + "/" + treeAlias + "/edit/" + content.id; + angular.extend(content.metaData, { treeAlias: treeAlias }); + } + + function configureContentResult(content, treeAlias, appAlias) { + content.menuUrl = umbRequestHelper.getApiUrl("contentTreeBaseUrl", "GetMenu", [{ id: content.id }, { application: appAlias }]); + content.editorPath = appAlias + "/" + treeAlias + "/edit/" + content.id; + angular.extend(content.metaData, { treeAlias: treeAlias }); + content.subTitle = content.metaData.Url; + } + + function configureMemberResult(member, treeAlias, appAlias) { + member.menuUrl = umbRequestHelper.getApiUrl("memberTreeBaseUrl", "GetMenu", [{ id: member.id }, { application: appAlias }]); + member.editorPath = appAlias + "/" + treeAlias + "/edit/" + (member.key ? member.key : member.id); + angular.extend(member.metaData, { treeAlias: treeAlias }); + member.subTitle = member.metaData.Email; + } + + function configureMediaResult(media, treeAlias, appAlias) { + media.menuUrl = umbRequestHelper.getApiUrl("mediaTreeBaseUrl", "GetMenu", [{ id: media.id }, { application: appAlias }]); + media.editorPath = appAlias + "/" + treeAlias + "/edit/" + media.id; + angular.extend(media.metaData, { treeAlias: treeAlias }); + } + + return { + configureContentResult: configureContentResult, + configureMemberResult: configureMemberResult, + configureMediaResult: configureMediaResult, + configureDefaultResult: configureDefaultResult + }; +} + +angular.module('umbraco.services').factory('searchResultFormatter', searchResultFormatter); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/controllers/search.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/search.controller.js index 54519f353b..d5d1ca58e2 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/search.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/search.controller.js @@ -15,21 +15,21 @@ function SearchController($scope, searchService, $log, $location, navigationServ $scope.selectedResult = -1; - $scope.navigateResults = function(ev){ + $scope.navigateResults = function (ev) { //38: up 40: down, 13: enter - switch(ev.keyCode){ + switch (ev.keyCode) { case 38: - iterateResults(true); + iterateResults(true); break; case 40: - iterateResults(false); + iterateResults(false); break; case 13: if ($scope.selectedItem) { $location.path($scope.selectedItem.editorPath); navigationService.hideSearch(); - } + } break; } }; @@ -39,50 +39,50 @@ function SearchController($scope, searchService, $log, $location, navigationServ var groupIndex = -1; var itemIndex = -1; $scope.selectedItem = undefined; - - function iterateResults(up){ + + function iterateResults(up) { //default group - if(!group){ + if (!group) { group = $scope.groups[0]; groupIndex = 0; } - if(up){ - if(itemIndex === 0){ - if(groupIndex === 0){ - gotoGroup($scope.groups.length-1, true); - }else{ - gotoGroup(groupIndex-1, true); + if (up) { + if (itemIndex === 0) { + if (groupIndex === 0) { + gotoGroup($scope.groups.length - 1, true); + } else { + gotoGroup(groupIndex - 1, true); } - }else{ - gotoItem(itemIndex-1); + } else { + gotoItem(itemIndex - 1); } - }else{ - if(itemIndex < group.results.length-1){ - gotoItem(itemIndex+1); - }else{ - if(groupIndex === $scope.groups.length-1){ + } else { + if (itemIndex < group.results.length - 1) { + gotoItem(itemIndex + 1); + } else { + if (groupIndex === $scope.groups.length - 1) { gotoGroup(0); - }else{ - gotoGroup(groupIndex+1); + } else { + gotoGroup(groupIndex + 1); } } } } - function gotoGroup(index, up){ + function gotoGroup(index, up) { groupIndex = index; group = $scope.groups[groupIndex]; - - if(up){ - gotoItem(group.results.length-1); - }else{ - gotoItem(0); + + if (up) { + gotoItem(group.results.length - 1); + } else { + gotoItem(0); } } - function gotoItem(index){ + function gotoItem(index) { itemIndex = index; $scope.selectedItem = group.results[itemIndex]; } @@ -91,7 +91,7 @@ function SearchController($scope, searchService, $log, $location, navigationServ var canceler = null; $scope.$watch("searchTerm", _.debounce(function (newVal, oldVal) { - $scope.$apply(function() { + $scope.$apply(function () { if ($scope.searchTerm) { if (newVal !== null && newVal !== undefined && newVal !== oldVal) { $scope.isSearching = true; @@ -107,8 +107,16 @@ function SearchController($scope, searchService, $log, $location, navigationServ canceler = $q.defer(); } - searchService.searchAll({ term: $scope.searchTerm, canceler: canceler }).then(function(result) { - $scope.groups = _.filter(result, function (group) { return group.results.length > 0; }); + searchService.searchAll({ term: $scope.searchTerm, canceler: canceler }).then(function (result) { + + //result is a dictionary of group Title and it's results + var filtered = {}; + _.each(result, function (value, key) { + if (value.results.length > 0) { + filtered[key] = value; + } + }); + $scope.groups = filtered; //set back to null so it can be re-created canceler = null; }); diff --git a/src/Umbraco.Web.UI.Client/src/less/tree.less b/src/Umbraco.Web.UI.Client/src/less/tree.less index df1bc4114a..e5d367bbd2 100644 --- a/src/Umbraco.Web.UI.Client/src/less/tree.less +++ b/src/Umbraco.Web.UI.Client/src/less/tree.less @@ -53,22 +53,21 @@ border-color: @turquoise-d1; } -.umb-tree li.root > div { - padding: 0; +.umb-tree li.root > div:first-child { + padding: 0; } -.umb-tree li.root > div h5 { - margin: 0; - width: 100%; - - display: flex; - align-items: center; +.umb-tree li.root > div h5, .umb-tree li.root > div h6 { + margin: 0; + width: 100%; + display: flex; + align-items: center; } -.umb-tree li.root > div h5 > a, .umb-tree-header { - display: flex; - padding: 20px 0 20px 20px; - box-sizing: border-box; +.umb-tree li.root > div:first-child h5 > a, .umb-tree-header { + display: flex; + padding: 20px 0 20px 20px; + box-sizing: border-box; } .umb-tree * { @@ -96,14 +95,22 @@ text-decoration: none } -.umb-tree div { +/*.umb-tree div.tree-node { padding: 5px 0 5px 0; position: relative; overflow: hidden; display: flex; flex-wrap: nowrap; align-items: center; +}*/ +.umb-tree div { + padding: 5px 0 5px 0; + position: relative; + overflow: hidden; + display: flex; + flex-wrap: nowrap; + align-items: center; } .umb-tree a.noSpr { @@ -192,6 +199,21 @@ /*color:@turquoise;*/ } +.umb-tree div.umb-search-group { + position: inherit; + display: inherit; +} + +.umb-tree div.umb-search-group:hover { + background: inherit; +} +.umb-tree div.umb-search-group h6 { + /*color: @gray-5;*/ + padding: 10px 0 10px 20px; + font-weight: inherit; + background:@gray-10; +} + .umb-tree .umb-search-group-item { padding-left: 20px; } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html index db8fd92008..4f07a2b976 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html @@ -1,104 +1,106 @@
+ ng-mouseleave="leaveTree($event)" ng-mouseenter="enterTree($event)"> - - + + - -