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
            }));
        }
Ejemplo n.º 2
0
        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);
        }