private bool FilterMatches(IssueViewModel vm)
        {
            if (string.IsNullOrEmpty(_filter))
            {
                return(true);
            }

            if (vm.Title.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            if (vm.IdFull.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            if (vm.Author.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            foreach (var label in vm.Labels)
            {
                if (label.Text.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool IsVisible(IssueViewModel vm)
        {
            if (!FilterMatches(vm))
            {
                return(false);
            }

            if (!vm.Milestone.IsChecked)
            {
                return(false);
            }

            return(true);
        }
        public async void Refresh()
        {
            var reposText = ConfigurationManager.AppSettings["Repos"];
            var repos     = OrgAndRepo.ParseList(reposText).ToArray();

            var existingMilestones = _milestones?.ToDictionary(m => m.Text) ?? new Dictionary <string, MilestoneViewModel>();

            var github     = GitHubClientFactory.Create();
            var viewModels = new List <IssueViewModel>();
            var milestones = new Dictionary <string, MilestoneViewModel>();

            foreach (var(org, repo) in repos)
            {
                var request = new RepositoryIssueRequest
                {
                    Filter = IssueFilter.All,
                    State  = ItemStateFilter.Open
                };
                request.Labels.Add("api-ready-for-review");

                var issues = await github.Issue.GetAllForRepository(org, repo, request);

                foreach (var issue in issues)
                {
                    var milestoneTitle = issue.Milestone?.Title ?? "(None)";
                    if (!milestones.TryGetValue(milestoneTitle, out var milestoneViewModel))
                    {
                        milestoneViewModel = new MilestoneViewModel(this, milestoneTitle);
                        milestones.Add(milestoneViewModel.Text, milestoneViewModel);

                        if (existingMilestones.TryGetValue(milestoneTitle, out var em))
                        {
                            milestoneViewModel.IsChecked = em.IsChecked;
                        }
                    }

                    var viewModel = new IssueViewModel(org, repo, issue, milestoneViewModel);
                    viewModels.Add(viewModel);
                }
            }

            var sortedViewModels = viewModels
                                   .OrderByDescending(vm => vm.IsBlocking)
                                   .ThenBy(vm => vm.Model.CreatedAt)
                                   .ToArray();

            Milestones = new ReadOnlyCollection <MilestoneViewModel>(milestones.Values.OrderBy(vm => vm.Text).ToArray());
            Issues     = new ReadOnlyCollection <IssueViewModel>(sortedViewModels);

            // Count status

            var numberOfOrgs   = repos.Select(r => r.OrgName).Distinct().Count();
            var numberOfRepos  = repos.Length;
            var numberOfIssues = viewModels.Count;

            CountStatus = $"{numberOfIssues:N0} issues across {numberOfOrgs:N0} orgs and {numberOfRepos:N0} repos";

            // Time status
            TimeStatus = $"Last updated {DateTime.Now}";

            UpdateCollectionView();
        }