From 0264a7276255676558ef8aed8fb317de4135bc50 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 19 Sep 2014 09:47:42 +1000 Subject: [PATCH] Ensures default list view data types are installed by default, includes these in the upgrade script. Now the default list views are used when rendering them per type (content, media, member). Updated the member tree to list nodes by member type and 'all members', each of these now renders a list view containing the members which is fully paged and searchable. Updates list view prop editor to deal with members appropriately. --- src/Umbraco.Core/Constants-Conventions.cs | 5 + .../Migrations/Initial/BaseDataCreation.cs | 6 +- .../Repositories/MemberRepository.cs | 99 +++---------------- src/Umbraco.Core/Services/IContentService.cs | 4 +- src/Umbraco.Core/Services/IMediaService.cs | 4 +- src/Umbraco.Core/Services/IMemberService.cs | 17 ++++ src/Umbraco.Core/Services/MemberService.cs | 15 +++ .../editors/umbcontentname.directive.js | 3 +- .../src/common/resources/member.resource.js | 58 +++++++++++ .../views/content/content.edit.controller.js | 3 +- .../datatype/datatype.edit.controller.js | 3 +- .../src/views/datatype/edit.html | 3 +- .../views/directives/umb-content-name.html | 1 + .../src/views/media/media.edit.controller.js | 1 - .../src/views/member/list.html | 27 +++++ .../views/member/member.edit.controller.js | 1 - .../views/member/member.list.controller.js | 43 ++++++++ .../includeproperties.prevalues.controller.js | 12 ++- .../listview/listview.controller.js | 46 ++++++--- .../listview/sortby.prevalues.controller.js | 9 ++ src/Umbraco.Web/Editors/MemberController.cs | 56 +++++++++++ .../Models/ContentEditing/DataTypeDisplay.cs | 8 ++ .../Models/ContentEditing/MemberDisplay.cs | 8 ++ .../Models/Mapping/DataTypeModelMapper.cs | 10 +- .../Mapping/TabsAndPropertiesResolver.cs | 2 +- .../PropertyEditors/ListViewPropertyEditor.cs | 6 +- .../EnsureListViewDataTypeIsCreated.cs | 6 +- src/Umbraco.Web/Trees/MemberTreeController.cs | 79 +++------------ 28 files changed, 348 insertions(+), 187 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/member/list.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/member/member.list.controller.js diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index da08bd631a..11255af8e2 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -11,6 +11,11 @@ namespace Umbraco.Core /// public static class Conventions { + public static class DataTypes + { + public const string ListViewPrefix = "List View - "; + } + public static class PropertyGroups { public const string ListViewGroupName = "umbContainerView"; diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 13f47cf85b..8debd76056 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -112,9 +112,9 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -38, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-38", SortOrder = 2, UniqueId = new Guid("fd9f1447-6c61-4a7c-9595-5aa39147d318"), Text = "Folder Browser", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultContentListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-95", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = "List View - Content", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMediaListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-96", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = "List View - Media", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMembersListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-97", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = "List View - Members", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultContentListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-95", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMediaListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-96", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMembersListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-97", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = new Guid(Constants.ObjectTypes.MediaType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = new Guid(Constants.ObjectTypes.MediaType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = new Guid(Constants.ObjectTypes.MediaType), CreateDate = DateTime.Now }); diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 2c43a90773..d65b04b9e0 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -72,11 +72,6 @@ namespace Umbraco.Core.Persistence.Repositories return content; - //var dtos = - // Database.Fetch( - // new PropertyDataRelator().Map, sql); - - //return BuildFromDto(dtos, sql); } protected override IEnumerable PerformGetAll(params int[] ids) @@ -88,20 +83,7 @@ namespace Umbraco.Core.Persistence.Repositories } return ProcessQuery(sql); - - //var sql = GetBaseQuery(false); - //if (ids.Any()) - //{ - // var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x))); - // sql.Where(statement); - //} - //sql.OrderByDescending(x => x.VersionDate); - - //var dtos = - // Database.Fetch( - // new PropertyDataRelator().Map, sql); - - //return BuildFromDtos(dtos, sql); + } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -112,6 +94,7 @@ namespace Umbraco.Core.Persistence.Repositories var query1 = query as Query; if (query1 == null) throw new Exception("Query cannot be null"); + var wheres = query1.WhereClauses(); //this is a pretty rudimentary check but wil work, we just need to know if this query requires property // level queries @@ -135,21 +118,6 @@ namespace Umbraco.Core.Persistence.Repositories return ProcessQuery(sql); } - - - //var sqlSubquery = GetSubquery(); - //var translator = new SqlTranslator(sqlSubquery, query); - //var subquery = translator.Translate(); - //var sql = GetBaseQuery(false) - // .Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments)) - // .OrderByDescending(x => x.VersionDate) - // .OrderBy(x => x.SortOrder); - - //var dtos = - // Database.Fetch( - // new PropertyDataRelator().Map, sql); - - //return BuildFromDtos(dtos, sql); } #endregion @@ -164,45 +132,16 @@ namespace Umbraco.Core.Persistence.Repositories .InnerJoin() .On(left => left.NodeId, right => right.NodeId) .InnerJoin() - .On(left => left.NodeId, right => right.NodeId) + .On(left => left.NodeId, right => right.NodeId) + //We're joining the type so we can do a query against the member type - not sure if this adds much overhead or not? + // the execution plan says it doesn't so we'll go with that and in that case, it might be worth joining the content + // types by default on the document and media repo's so we can query by content type there too. + .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) .InnerJoin() .On(left => left.NodeId, right => right.NodeId) .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; - //var sql = new Sql(); - - //if (isCount) - //{ - // sql.Select("COUNT(*)") - // .From() - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .Where(x => x.NodeObjectType == NodeObjectTypeId); - // return sql; - //} - - //sql.Select("umbracoNode.*", "cmsContent.contentType", "cmsContentType.alias AS ContentTypeAlias", "cmsContentVersion.VersionId", - // "cmsContentVersion.VersionDate", "cmsContentVersion.LanguageLocale", "cmsMember.Email", - // "cmsMember.LoginName", "cmsMember.Password", "cmsPropertyData.id AS PropertyDataId", "cmsPropertyData.propertytypeid", - // "cmsPropertyData.dataDate", "cmsPropertyData.dataInt", "cmsPropertyData.dataNtext", "cmsPropertyData.dataNvarchar", - // "cmsPropertyType.id", "cmsPropertyType.Alias", "cmsPropertyType.Description", - // "cmsPropertyType.Name", "cmsPropertyType.mandatory", "cmsPropertyType.validationRegExp", - // "cmsPropertyType.helpText", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", "cmsPropertyType.propertyTypeGroupId", - // "cmsPropertyType.dataTypeId", "cmsDataType.propertyEditorAlias", "cmsDataType.dbType") - // .From() - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .InnerJoin().On(left => left.NodeId, right => right.ContentTypeId) - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .InnerJoin().On(left => left.NodeId, right => right.NodeId) - // .LeftJoin().On(left => left.ContentTypeId, right => right.ContentTypeId) - // .LeftJoin().On(left => left.DataTypeId, right => right.DataTypeId) - // .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) - // .Append("AND cmsPropertyData.versionId = cmsContentVersion.VersionId") - // .Where(x => x.NodeObjectType == NodeObjectTypeId); - //return sql; } protected override string GetBaseWhereClause() @@ -506,15 +445,6 @@ namespace Umbraco.Core.Persistence.Repositories ((Entity)media).ResetDirtyProperties(false); return media; - //var sql = GetBaseQuery(false); - //sql.Where(x => x.VersionId == versionId); - //sql.OrderByDescending(x => x.VersionDate); - - //var dtos = - // Database.Fetch( - // new PropertyDataRelator().Map, sql); - - //return BuildFromDto(dtos, sql); } protected override void PerformDeleteVersion(int id, Guid versionId) @@ -591,18 +521,14 @@ namespace Umbraco.Core.Persistence.Repositories var subQuery = new Sql().Select("Member").From().Where(dto => dto.MemberGroup == memberGroup.Id); var sql = GetBaseQuery(false) - //TODO: This is NOT great!, do an inner join! + //TODO: An inner join would be better, though I've read that the query optimizer will always turn a + // subquery with an IN clause into an inner join anyways. .Append(new Sql("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments)) .OrderByDescending(x => x.VersionDate) .OrderBy(x => x.SortOrder); return ProcessQuery(sql); - //var dtos = - // Database.Fetch( - // new PropertyDataRelator().Map, sql); - - //return BuildFromDtos(dtos, sql); } public bool Exists(string username) @@ -653,7 +579,8 @@ namespace Umbraco.Core.Persistence.Repositories ProcessQuery, orderBy, orderDirection, filter.IsNullOrWhiteSpace() ? (Func) null - : () => "AND (cmsMember.LoginName LIKE '%" + filter + "%')"); + : () => "AND ((umbracoNode. " + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + " LIKE '%" + filter + "%') " + + "OR (cmsMember.LoginName LIKE '%" + filter + "%'))"); } public void AddOrUpdateContentXml(IMember content, Func xml) @@ -733,7 +660,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Private method to create a member object from a MemberDto /// - /// + /// /// /// /// @@ -755,7 +682,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Private method to create a member object from a MemberDto /// - /// + /// /// /// /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 3cfd97d32e..8408a61296 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -117,10 +117,10 @@ namespace Umbraco.Core.Services /// Page size /// Total records query would return without paging /// Field to order by - /// Direction to order by + /// Direction to order by /// Search text filter /// An Enumerable list of objects - IEnumerable GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren, + IEnumerable GetPagedChildren(int id, int pageIndex, int pageSize, out int totalRecords, string orderBy, Direction orderDirection, string filter = ""); /// diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index aa7d5c49e6..bfef76b1ec 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -70,10 +70,10 @@ namespace Umbraco.Core.Services /// Page size /// Total records query would return without paging /// Field to order by - /// Direction to order by + /// Direction to order by /// Search text filter /// An Enumerable list of objects - IEnumerable GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren, + IEnumerable GetPagedChildren(int id, int pageIndex, int pageSize, out int totalRecords, string orderBy, Direction orderDirection, string filter = ""); /// diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index 82c21dd2fc..49a3612f30 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Services @@ -10,6 +12,21 @@ namespace Umbraco.Core.Services /// public interface IMemberService : IMembershipMemberService { + /// + /// Gets a list of paged objects + /// + /// An can be of type + /// Current page index + /// Size of the page + /// Total number of records found (out) + /// + /// + /// + /// + /// + IEnumerable GetAll(int pageIndex, int pageSize, out int totalRecords, + string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = ""); + /// /// Creates an object without persisting it /// diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index 6002086189..5322bb667e 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -659,6 +659,21 @@ namespace Umbraco.Core.Services } } + public IEnumerable GetAll(int pageIndex, int pageSize, out int totalRecords, + string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "") + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMemberRepository(uow)) + { + if (memberTypeAlias == null) + { + return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filter); + } + var query = new Query().Where(x => x.ContentTypeAlias == memberTypeAlias); + return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filter); + } + } + /// /// Gets the count of Members by an optional MemberType alias /// diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/editors/umbcontentname.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/editors/umbcontentname.directive.js index fb1daabea3..02f78d8611 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/editors/umbcontentname.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/editors/umbcontentname.directive.js @@ -15,7 +15,8 @@ angular.module("umbraco.directives") templateUrl: 'views/directives/umb-content-name.html', scope: { placeholder: '@placeholder', - model: '=ngModel' + model: '=ngModel', + ngDisabled: '=' }, link: function(scope, element, attrs, ngModel) { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js index 65a53d233d..381019fb5b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js @@ -23,7 +23,65 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { return { + getPagedResults: function (memberTypeAlias, options) { + + if (memberTypeAlias === 'all-members') { + memberTypeAlias = null; + } + + var defaults = { + pageSize: 25, + pageNumber: 1, + filter: '', + orderDirection: "Ascending", + orderBy: "LoginName" + }; + if (options === undefined) { + options = {}; + } + //overwrite the defaults if there are any specified + angular.extend(defaults, options); + //now copy back to the options we will use + options = defaults; + //change asc/desct + if (options.orderDirection === "asc") { + options.orderDirection = "Ascending"; + } + else if (options.orderDirection === "desc") { + options.orderDirection = "Descending"; + } + + var params = [ + { pageNumber: options.pageNumber }, + { pageSize: options.pageSize }, + { orderBy: options.orderBy }, + { orderDirection: options.orderDirection }, + { filter: options.filter } + ]; + if (memberTypeAlias != null) { + params.push({ memberTypeAlias: memberTypeAlias }); + } + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "memberApiBaseUrl", + "GetPagedResults", + params)), + 'Failed to retrieve member paged result'); + }, + getListNode: function (listName) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "memberApiBaseUrl", + "GetListNodeDisplay", + [{ listName: listName }])), + 'Failed to retrieve data for member list ' + listName); + }, + /** * @ngdoc method * @name umbraco.resources.memberResource#getByKey diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js index f4f71c19d0..709bcd7fce 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js @@ -10,8 +10,7 @@ function ContentEditController($scope, $rootScope, $routeParams, $q, $timeout, $ //setup scope vars $scope.defaultButton = null; - $scope.subButtons = []; - $scope.nav = navigationService; + $scope.subButtons = []; $scope.currentSection = appState.getSectionState("currentSection"); $scope.currentNode = null; //the editors affiliated node diff --git a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js index 7f713c0322..9731e6a63f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js @@ -8,8 +8,7 @@ */ function DataTypeEditController($scope, $routeParams, $location, appState, navigationService, treeService, dataTypeResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, formHelper, editorState) { - //setup scope vars - $scope.nav = navigationService; + //setup scope vars $scope.currentSection = appState.getSectionState("currentSection"); $scope.currentNode = null; //the editors affiliated node diff --git a/src/Umbraco.Web.UI.Client/src/views/datatype/edit.html b/src/Umbraco.Web.UI.Client/src/views/datatype/edit.html index b27d326088..4d365174fb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatype/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatype/edit.html @@ -7,8 +7,9 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/umb-content-name.html b/src/Umbraco.Web.UI.Client/src/views/directives/umb-content-name.html index 314015f91b..85929d1e1b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/directives/umb-content-name.html +++ b/src/Umbraco.Web.UI.Client/src/views/directives/umb-content-name.html @@ -2,6 +2,7 @@
+ + + +
+

{{content.name}}

+
+ +
+ + + +
+ + + + + +
+
+ +
+
+ \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js index bafa29bfd9..d610441b9c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js @@ -9,7 +9,6 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appState, memberResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper, umbModelMapper, editorState) { //setup scope vars - $scope.nav = navigationService; $scope.currentSection = appState.getSectionState("currentSection"); $scope.currentNode = null; //the editors affiliated node diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.list.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.list.controller.js new file mode 100644 index 0000000000..7b4d30bae6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.list.controller.js @@ -0,0 +1,43 @@ +/** + * @ngdoc controller + * @name Umbraco.Editors.Member.ListController + * @function + * + * @description + * The controller for the member list view + */ +function MemberListController($scope, $routeParams, $location, $q, $window, appState, memberResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper, umbModelMapper, editorState) { + + //setup scope vars + $scope.currentSection = appState.getSectionState("currentSection"); + $scope.currentNode = null; //the editors affiliated node + + //build a path to sync the tree with + function buildTreePath(data) { + var path = data.name[0].toLowerCase() + "," + data.key; + return path; + } + + //we are editing so get the content item from the server + memberResource.getListNode($routeParams.id) + .then(function (data) { + $scope.loaded = true; + $scope.content = data; + + editorState.set($scope.content); + + var path = buildTreePath(data); + + navigationService.syncTree({ tree: "member", path: path.split(",") }).then(function (syncArgs) { + $scope.currentNode = syncArgs.node; + }); + + //in one particular special case, after we've created a new item we redirect back to the edit + // route but there might be server validation errors in the collection which we need to display + // after the redirect, so we will bind all subscriptions which will show the server validation errors + // if there are any and then clear them so the collection no longer persists them. + serverValidationManager.executeAndClearAllSubscriptions(); + }); +} + +angular.module("umbraco").controller("Umbraco.Editors.Member.ListController", MemberListController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js index 48f443b660..a9863e28ab 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js @@ -42,7 +42,7 @@ function includePropsPreValsController($rootScope, $scope, localizationService, $scope.removeField = function(e) { $scope.model.value = _.reject($scope.model.value, function (x) { return x.alias === e.alias; - }); + }); } //now we'll localize these strings, for some reason the directive doesn't work inside of the select group with an ng-model declared @@ -50,6 +50,16 @@ function includePropsPreValsController($rootScope, $scope, localizationService, var key = $scope.getLocalizedKey(e.value); localizationService.localize(key).then(function (v) { e.name = v; + + switch (e.value) { + case "updater": + e.name += " (Content only)"; + break; + case "published": + e.name += " (Content only)"; + break; + } + }); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 5c68ad5b03..cd41745613 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -9,19 +9,35 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific return; } - //Now we need to check if this is for media or content because that will depend on the resources we use - //TODO: Check for members!! - var contentResource, contentTypeResource; + //Now we need to check if this is for media, members or content because that will depend on the resources we use + var contentResource, getContentTypesCallback, getListResultsCallback, deleteItemCallback, getIdCallback; - if ($scope.model.config.entityType && $scope.model.config.entityType === "media") { - contentResource = $injector.get('mediaResource'); - contentTypeResource = $injector.get('mediaTypeResource'); - $scope.entityType = "media"; + if ($scope.model.config.entityType && $scope.model.config.entityType === "member") { + contentResource = $injector.get('memberResource'); + getContentTypesCallback = $injector.get('memberTypeResource').getTypes; + getListResultsCallback = contentResource.getPagedResults; + deleteItemCallback = contentResource.deleteByKey; + getIdCallback = function(selected) { + return selected.key; + } + $scope.entityType = "member"; } else { - contentResource = $injector.get('contentResource'); - contentTypeResource = $injector.get('contentTypeResource'); - $scope.entityType = "content"; + if ($scope.model.config.entityType && $scope.model.config.entityType === "media") { + contentResource = $injector.get('mediaResource'); + getContentTypesCallback = $injector.get('mediaTypeResource').getAllowedTypes; + $scope.entityType = "media"; + } + else { + contentResource = $injector.get('contentResource'); + getContentTypesCallback = $injector.get('contentTypeResource').getAllowedTypes; + $scope.entityType = "content"; + } + getListResultsCallback = contentResource.getChildren; + deleteItemCallback = contentResource.deleteById; + getIdCallback = function (selected) { + return selected.id; + } } $scope.isNew = false; @@ -116,7 +132,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific with simple values */ $scope.reloadView = function(id) { - contentResource.getChildren(id, $scope.options).then(function(data) { + getListResultsCallback(id, $scope.options).then(function (data) { $scope.listViewResultSet = data; //update all values for display @@ -196,7 +212,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific for (var i = 0; i < selected.length; i++) { $scope.bulkStatus = "Deleted doc " + current + " out of " + total + " documents"; - contentResource.deleteById(selected[i].id).then(function(data) { + deleteItemCallback(getIdCallback(selected[i])).then(function (data) { if (current === total) { notificationsService.success("Bulk action", "Deleted " + total + "documents"); $scope.bulkStatus = ""; @@ -226,7 +242,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific for (var i = 0; i < selected.length; i++) { $scope.bulkStatus = "Publishing " + current + " out of " + total + " documents"; - contentResource.publishById(selected[i].id) + contentResource.publishById(getIdCallback(selected[i])) .then(function(content) { if (current == total) { notificationsService.success("Bulk action", "Published " + total + "documents"); @@ -269,7 +285,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific for (var i = 0; i < selected.length; i++) { $scope.bulkStatus = "Unpublishing " + current + " out of " + total + " documents"; - contentResource.unPublish(selected[i].id) + contentResource.unPublish(getIdCallback(selected[i])) .then(function(content) { if (current == total) { @@ -356,7 +372,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific function initView() { if ($routeParams.id) { $scope.pagination = new Array(10); - $scope.listViewAllowedTypes = contentTypeResource.getAllowedTypes($routeParams.id); + $scope.listViewAllowedTypes = getContentTypesCallback($routeParams.id); $scope.contentId = $routeParams.id; $scope.isTrashed = $routeParams.id === "-20" || $routeParams.id === "-21"; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js index b79dd62256..08e0c95376 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js @@ -15,6 +15,15 @@ function sortByPreValsController($rootScope, $scope, localizationService) { _.each($scope.sortByFields, function (e, i) { localizationService.localize(e.key).then(function (v) { e.name = v; + + switch (e.value) { + case "Updater": + e.name += " (Content only)"; + break; + case "Published": + e.name += " (Content only)"; + break; + } }); }); diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 1c9486c67d..8c8768f37d 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -18,8 +18,10 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Web.Models.Mapping; using Umbraco.Web.WebApi; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; @@ -70,6 +72,60 @@ namespace Umbraco.Web.Editors get { return Services.MemberService.GetMembershipScenario(); } } + public PagedResult> GetPagedResults( + int pageNumber = 1, + int pageSize = 100, + string orderBy = "Name", + Direction orderDirection = Direction.Ascending, + string filter = "", + string memberTypeAlias = null) + { + int totalChildren; + IMember[] children; + if (pageNumber > 0 && pageSize > 0) + { + children = Services.MemberService.GetAll((pageNumber - 1), pageSize, out totalChildren, orderBy, orderDirection, memberTypeAlias, filter).ToArray(); + } + else + { + throw new NotSupportedException("Both pageNumber and pageSize must be greater than zero"); + } + + if (totalChildren == 0) + { + return new PagedResult>(0, 0, 0); + } + + var pagedResult = new PagedResult>(totalChildren, pageNumber, pageSize); + pagedResult.Items = children + .Select(Mapper.Map>); + + return pagedResult; + } + + /// + /// Returns a display node with a list view to render members + /// + /// + /// + public MemberListDisplay GetListNodeDisplay(string listName) + { + var display = new MemberListDisplay + { + ContentTypeAlias = listName, + ContentTypeName = listName, + Id = listName, + IsContainer = true, + Name = listName, + Path = "-1," + listName, + ParentId = -1 + }; + + TabsAndPropertiesResolver.AddListView(display, "member", Services.DataTypeService); + + return display; + } + /// /// Gets the content json for the member /// diff --git a/src/Umbraco.Web/Models/ContentEditing/DataTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/DataTypeDisplay.cs index 2c7e3d1c17..b58773a621 100644 --- a/src/Umbraco.Web/Models/ContentEditing/DataTypeDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/DataTypeDisplay.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; @@ -34,5 +35,12 @@ namespace Umbraco.Web.Models.ContentEditing ///
[DataMember(Name = "notifications")] public List Notifications { get; private set; } + + /// + /// Whether or not this is a system data type, in which case it cannot be deleted + /// + [DataMember(Name = "isSystem")] + [ReadOnly(true)] + public bool IsSystemDataType { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MemberDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/MemberDisplay.cs index a295e7718f..e98191fc7e 100644 --- a/src/Umbraco.Web/Models/ContentEditing/MemberDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/MemberDisplay.cs @@ -6,6 +6,14 @@ using Umbraco.Core.Models.Membership; namespace Umbraco.Web.Models.ContentEditing { + /// + /// A model representing a member list to be displayed in the back office + /// + [DataContract(Name = "content", Namespace = "")] + public class MemberListDisplay : ContentItemDisplayBase + { + } + /// /// A model representing a member to be displayed in the back office /// diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs index e1f5cc4508..2ec97b6b3b 100644 --- a/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs @@ -27,6 +27,13 @@ namespace Umbraco.Web.Models.Mapping config.CreateMap() .ForMember(x => x.Value, expression => expression.Ignore()); + var systemIds = new[] + { + Constants.System.DefaultContentListViewDataTypeId, + Constants.System.DefaultMediaListViewDataTypeId, + Constants.System.DefaultMembersListViewDataTypeId + }; + config.CreateMap() .ForMember(display => display.AvailableEditors, expression => expression.ResolveUsing()) .ForMember(display => display.PreValues, expression => expression.ResolveUsing( @@ -35,7 +42,8 @@ namespace Umbraco.Web.Models.Mapping definition => definition.PropertyEditorAlias.IsNullOrWhiteSpace() ? null : definition.PropertyEditorAlias)) .ForMember(x => x.Notifications, expression => expression.Ignore()) .ForMember(x => x.Icon, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()); + .ForMember(x => x.Alias, expression => expression.Ignore()) + .ForMember(x => x.IsSystemDataType, expression => expression.MapFrom(definition => systemIds.Contains(definition.Id))); //gets a list of PreValueFieldDisplay objects from the data type definition config.CreateMap>() diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index a354718ffb..62e7bc58e4 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -130,7 +130,7 @@ namespace Umbraco.Web.Models.Mapping case "media": dtdId = Constants.System.DefaultMediaListViewDataTypeId; break; - case "members": + case "member": dtdId = Constants.System.DefaultMembersListViewDataTypeId; break; default: diff --git a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs index fb179435db..09dfacc94f 100644 --- a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs @@ -44,13 +44,15 @@ namespace Umbraco.Web.PropertyEditors [PreValueField("pageSize", "Page Size", "number", Description = "Number of items per page")] public int PageSize { get; set; } - [PreValueField("orderBy", "Order By", "views/propertyeditors/listview/sortby.prevalues.html")] + [PreValueField("orderBy", "Order By", "views/propertyeditors/listview/sortby.prevalues.html", + Description = "The default sort order for the list")] public int OrderBy { get; set; } [PreValueField("orderDirection", "Order Direction", "views/propertyeditors/listview/orderdirection.prevalues.html")] public int OrderDirection { get; set; } - [PreValueField("includeProperties", "Include Properties", "views/propertyeditors/listview/includeproperties.prevalues.html")] + [PreValueField("includeProperties", "Columns Displayed", "views/propertyeditors/listview/includeproperties.prevalues.html", + Description = "The properties that will be displayed for each column")] public object IncludeProperties { get; set; } } diff --git a/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs b/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs index fd79462a81..09d636d153 100644 --- a/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs +++ b/src/Umbraco.Web/Strategies/Migrations/EnsureListViewDataTypeIsCreated.cs @@ -65,9 +65,9 @@ namespace Umbraco.Web.Strategies.Migrations if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert()) e.MigrationContext.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName("umbracoNode")))); - e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultContentListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-95", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = "List View - Content", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMediaListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-96", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = "List View - Media", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMembersListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-97", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = "List View - Members", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultContentListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-95", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMediaListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-96", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + e.MigrationContext.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultMembersListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-97", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); //Turn off identity insert if db provider is not mysql if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert()) diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index 8e4bed8d7f..a0c126bc25 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -11,13 +11,10 @@ using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; using umbraco; using umbraco.BusinessLogic.Actions; -using umbraco.cms.businesslogic.member; using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees { - //TODO: Upgrade thsi to use the new Member Service! - //We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered // this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here. [UmbracoApplicationAuthorize( @@ -33,9 +30,11 @@ namespace Umbraco.Web.Trees public MemberTreeController() { _provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); + _isUmbracoProvider = _provider.IsUmbracoMembershipProvider(); } - private MembershipProvider _provider; + private readonly MembershipProvider _provider; + private readonly bool _isUmbracoProvider; protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { @@ -43,55 +42,16 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { - //list out all the letters - for (var i = 97; i < 123; i++) - { - var charString = ((char) i).ToString(CultureInfo.InvariantCulture); - var folder = CreateTreeNode(charString, id, queryStrings, charString, "icon-folder-close", true); - folder.NodeType = "member-folder"; - nodes.Add(folder); - } - //list out 'Others' if the membership provider is umbraco - if (_provider.IsUmbracoMembershipProvider()) - { - var folder = CreateTreeNode("others", id, queryStrings, "Others", "icon-folder-close", true); - folder.NodeType = "member-folder"; - nodes.Add(folder); - } - } - else - { - //if it is a letter - if (id.Length == 1 && char.IsLower(id, 0)) - { - if (_provider.IsUmbracoMembershipProvider()) - { - int totalRecs; - var foundMembers = Services.MemberService.FindMembersByDisplayName( - id.ToCharArray()[0].ToString(CultureInfo.InvariantCulture), 0, int.MaxValue, out totalRecs, StringPropertyMatchType.StartsWith) - .ToArray(); + nodes.Add( + CreateTreeNode("all-members", id, queryStrings, "All Members", "icon-users", false, + queryStrings.GetValue("application") + TreeAlias.EnsureStartsWith('/') + "/list/all-members")); - //get the members from our member data layer - nodes.AddRange( - foundMembers - .Select(m => CreateTreeNode(m.Key.ToString("N"), id, queryStrings, m.Name, "icon-user"))); - } - else - { - //get the members from the provider - int total; - nodes.AddRange( - FindUsersByName(char.Parse(id)).Cast() - .Select(m => CreateTreeNode(GetNodeIdForCustomProvider(m.ProviderUserKey), id, queryStrings, m.UserName, "icon-user"))); - } - } - else if (id == "others") + if (_isUmbracoProvider) { - //others will only show up when in umbraco membership mode - //TODO: We don't have a new API for this because we want to get rid of how this is displayed - nodes.AddRange( - Member.getAllOtherMembers() - .Select(m => CreateTreeNode(m.UniqueId.ToString("N"), id, queryStrings, m.Text, "icon-user"))); + nodes.AddRange(Services.MemberTypeService.GetAll() + .Select(memberType => + CreateTreeNode(memberType.Alias, id, queryStrings, memberType.Name, "icon-users", false, + queryStrings.GetValue("application") + TreeAlias.EnsureStartsWith('/') + "/list/" + memberType.Alias))); } } return nodes; @@ -115,10 +75,10 @@ namespace Umbraco.Web.Trees } else { - //the AD provider - and potentiall all other providers will use the asterisk syntax. + //the AD provider - and potentially all other providers will use the asterisk syntax. return _provider.FindUsersByName(letter + "*", 0, 9999, out total); } - + } /// @@ -155,7 +115,7 @@ namespace Umbraco.Web.Trees else { //Create a custom create action - this does not launch a dialog, it just navigates to the create screen - // we'll create it baesd on the ActionNew so it maintains the same icon properties, name, etc... + // we'll create it based on the ActionNew so it maintains the same icon properties, name, etc... var createMenuItem = new MenuItem(ActionNew.Instance); //we want to go to this route: /member/member/edit/-1?create=true createMenuItem.NavigateToRoute("/member/member/edit/-1?create=true"); @@ -166,15 +126,8 @@ namespace Umbraco.Web.Trees return menu; } - Guid guid; - if (Guid.TryParse(id, out guid)) - { - menu.Items.Add(ui.Text("actions", ActionDelete.Instance.Alias)); - } - else - { - menu.Items.Add(ui.Text("actions", ActionRefresh.Instance.Alias), false); - } + menu.Items.Add(ui.Text("actions", ActionRefresh.Instance.Alias), false); + return menu; } }