public IActionResult GetLibrary([FromBody] ProfileTypeDefFilterModel model) { if (model == null) { _logger.LogWarning("ProfileTypeDefinitionController|GetLibrary|Invalid model"); return(BadRequest("ProfileTypeDefinitionController|Library|Invalid model")); } var userToken = UserExtension.DalUserToken(User); // { UserId = User.GetUserID() }; //search on some pre-determined fields var orderByExprs = _profileUtils.BuildSearchOrderByExpressions(User.GetUserID(), (SearchCriteriaSortByEnum)model.SortByEnum); var result = _dal.Where(BuildPredicate(model, userToken), userToken, model.Skip, model.Take, true, false, orderByExprs.ToArray()); //TBD - come back to this - //This is used when user clicks on View Type Defs for a single profile. //Add support to return list or profiles if the front end begins to support filtering by multiple profiles var profileCategory = model.Filters == null ? null : model.Filters.Find(c => c.ID.Value == (int)SearchCriteriaCategoryEnum.Profile); var profileFilters = profileCategory == null ? null : profileCategory.Items.Where(x => x.Selected).Select(x => x.ID.Value).ToList(); return(Ok(new ProfileTypeDefinitionSearchResult <ProfileTypeDefinitionModel>() { Count = result.Count, Data = result.Data, SummaryData = result.SummaryData, //return the profiles used in the filter -null, one or many Profiles = profileFilters == null ? null : _dalProfile.Where(x => profileFilters.Contains(x.ID.Value), userToken).Data })); }
public IActionResult GetSearchCriteria() //[FromBody] LookupGroupByModel model) { //populate specific types var userToken = UserExtension.DalUserToken(User); var filters = new List <LookupGroupByModel>(); // separate section for my type - follow the same structure for flexibility but only including one hardcoded type filters.Add(new LookupGroupByModel() { Name = SearchCriteriaCategoryEnum.Author.ToString(), ID = (int)SearchCriteriaCategoryEnum.Author, Items = new List <LookupItemFilterModel>() { new LookupItemFilterModel() { ID = User.GetUserID(), Name = "My Types" } } }); // separate section for popular - follow the same structure for flexibility but only including one hardcoded type filters.Add(new LookupGroupByModel() { Name = SearchCriteriaCategoryEnum.Popular.ToString(), ID = (int)SearchCriteriaCategoryEnum.Popular, Items = new List <LookupItemFilterModel>() { new LookupItemFilterModel() { ID = -1, Name = "Popular", Visible = true //until we implement a popular calculator, leave this off the display } } }); //group the result by lookup type List <int?> excludeList = new List <int?> { (int)ProfileItemTypeEnum.Class }; excludeList = excludeList.Union(ProfileMapperUtil.ExcludedProfileTypes).ToList(); var allItems = _dal.GetAll(userToken).Where(x => !excludeList.Contains(x.ID) && x.LookupType == LookupTypeEnum.ProfileType); var grpItems = allItems.GroupBy(x => new { EnumValue = x.LookupType, Name = x.LookupType.ToString() }); foreach (var item in grpItems) { filters.Add(new LookupGroupByModel { Name = SearchCriteriaCategoryEnum.TypeDefinitionType.ToString(), ID = (int)SearchCriteriaCategoryEnum.TypeDefinitionType, Items = item.ToList().Select(itm => new LookupItemFilterModel { ID = itm.ID, Name = itm.Name, IsActive = itm.IsActive, DisplayOrder = itm.DisplayOrder }).ToList() }); } // separate section for profile - follow the same structure for flexibility var profiles = _dalProfile.GetAll(userToken); filters.Add(new LookupGroupByModel() { Name = SearchCriteriaCategoryEnum.Profile.ToString(), ID = (int)SearchCriteriaCategoryEnum.Profile, Items = profiles.OrderBy(p => p.Namespace).Select(p => new LookupItemFilterModel { ID = p.ID, Name = p.Namespace + (string.IsNullOrEmpty(p.Version) ? "" : $" ({p.Version})"), IsActive = true, Visible = false, //don't show in UI but can be set selected on View Type Definitions scenario DisplayOrder = 999 }).ToList() }); //leave query null, skip, take defaults var result = new ProfileTypeDefFilterModel() { Filters = filters, }; //return result return(Ok(result)); }
private List <Expression <Func <ProfileTypeDefinition, bool> > > BuildPredicate(ProfileTypeDefFilterModel model, UserToken userToken) { model.Query = string.IsNullOrEmpty(model.Query) ? null : model.Query.ToLower(); //init var userId = User.GetUserID(); List <Expression <Func <ProfileTypeDefinition, bool> > > result = new List <Expression <Func <ProfileTypeDefinition, bool> > >(); var paramExpr = Expression.Parameter(typeof(ProfileTypeDefinition), "x"); //Build collection of expressions - various parts depend on existence of values incoming in the model. //Dal will loop over predicates and call query = query.where(predicate) which will //create AND between each predicate //Part 0 - Always exclude some types that are behind the scenes type result.Add(x => !ProfileMapperUtil.ExcludedProfileTypes.Contains(x.ProfileTypeId)); //Part 0 - string contains if (!string.IsNullOrEmpty(model.Query)) { result.Add(x => x.Name.ToLower().Contains(model.Query) || x.Description.ToLower().Contains(model.Query) || (x.Profile != null && x.Profile.Namespace.ToLower().Contains(model.Query)) || (x.Author != null && x.Author.FirstName.ToLower().Contains(model.Query)) || (x.Author != null && x.Author.LastName.ToLower().Contains(model.Query)) || (x.Author != null && (x.Author.FirstName.ToLower() + x.Author.LastName.ToLower()).Contains(model.Query.Replace(" ", ""))) || (x.ExternalAuthor != null && x.ExternalAuthor.ToLower().Contains(model.Query)) || x.MetaTags.ToLower().Contains(model.Query)); } //Part 1 - Mine OR Popular - This will be an OR clause within this portion //TBD - weave in popular with author var filterAuthors = model.Filters == null?null: model.Filters.Find(c => c.ID.Value == (int)SearchCriteriaCategoryEnum.Author) .Items.Where(x => x.Selected).ToList(); if (filterAuthors != null && filterAuthors.Count() > 0) { Expression <Func <ProfileTypeDefinition, bool> > predAuthor = null; foreach (var filterAuthor in filterAuthors) { Expression <Func <ProfileTypeDefinition, bool> > fnz = x => !x.Profile.StandardProfileID.HasValue && x.Profile.AuthorId.Value.Equals(filterAuthor.ID.Value); predAuthor = predAuthor.OrExtension(fnz); } //append to predicate list result.Add(predAuthor); } //Part 1a - Filter on popular var filtersPopular = model.Filters == null ? null : model.Filters.Find(c => c.ID.Value == (int)SearchCriteriaCategoryEnum.Popular) .Items.Where(x => x.Selected).ToList(); if (filtersPopular != null && filtersPopular.Count() > 0) { //for popular, there is only one item in collection so we don't loop over filtersPopular //get list of type defs we characterize as popular - top 30 var popularProfiles = _profileUtils.GetPopularItems(userToken); Expression <Func <ProfileTypeDefinition, bool> > predPopular = null; Expression <Func <ProfileTypeDefinition, bool> > fnz = x => popularProfiles.Any(z => z.Equals(x.ID.Value)); predPopular = predPopular.OrExtension(fnz); //append to predicate list result.Add(predPopular); } //Part 2 - Filter on Profile - Typedefs associated with a specific profile - none, one or many var filterProfiles = model.Filters == null ? null : model.Filters.Find(c => c.ID.Value == (int)SearchCriteriaCategoryEnum.Profile) .Items.Where(x => x.Selected).ToList(); if (filterProfiles != null && filterProfiles.Count() > 0) { Expression <Func <ProfileTypeDefinition, bool> > predProfile = null; foreach (var filterProfile in filterProfiles) { Expression <Func <ProfileTypeDefinition, bool> > fnz = x => x.ProfileId.Value.Equals(filterProfile.ID.Value); predProfile = predProfile.OrExtension(fnz); } //append to predicate list result.Add(predProfile); } //Part 3 - Filter on typeDef types (object, variable type, structure, enumeration) associated with a specific profile //Expression<Func<ProfileTypeDefinition, bool>> predicate3 = null; var filterTypes = model.Filters == null ? null : model.Filters.Find(c => c.ID.Value == (int)SearchCriteriaCategoryEnum.TypeDefinitionType) .Items.Where(x => x.Selected).ToList(); if (filterTypes != null && filterTypes.Count() > 0) { Expression <Func <ProfileTypeDefinition, bool> > predTypeId = null; foreach (var filterType in filterTypes) { Expression <Func <ProfileTypeDefinition, bool> > fnz = x => x.ProfileTypeId.Value.Equals(filterType.ID.Value); predTypeId = predTypeId.OrExtension(fnz); } result.Add(predTypeId); } //append to predicate list //if (predicate3 != null) result.Add(predicate3); return(result); }