Skip to content

Commit edb2b8b

Browse files
committed
update
1 parent 6a28abb commit edb2b8b

File tree

6 files changed

+274
-150
lines changed

6 files changed

+274
-150
lines changed

src/dataneo.TutorialLibs.Domain/Tutorials/Specifications/FilterByCategoryIdsSpecification.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using Ardalis.GuardClauses;
2+
using Ardalis.Specification;
3+
using dataneo.TutorialLibs.Domain.Categories;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace dataneo.TutorialLibs.Domain.Tutorials.Specifications
8+
{
9+
public class TutorialSearchSpecification : Specification<Tutorial>
10+
{
11+
public TutorialSearchSpecification FilterByCategories(IEnumerable<Category> categories, bool filterWithNoCategory = true)
12+
{
13+
Guard.Against.Null(categories, nameof(categories));
14+
var categoriesIdsSet = categories.Select(s => s.Id).ToHashSet();
15+
if (categoriesIdsSet.Count == 0)
16+
return this;
17+
18+
if (filterWithNoCategory)
19+
{
20+
Query.Where(tutorial => tutorial.Categories.Any() == false ||
21+
tutorial.Categories.Any(category => categoriesIdsSet.Contains(category.Id)));
22+
return this;
23+
}
24+
25+
Query.Where(tutorial => tutorial.Categories.Any(category => categoriesIdsSet.Contains(category.Id)));
26+
return this;
27+
}
28+
29+
public TutorialSearchSpecification Page(short page, short recordOnPage)
30+
{
31+
Guard.Against.NegativeOrZero(page, nameof(page));
32+
Guard.Against.NegativeOrZero(recordOnPage, nameof(recordOnPage));
33+
Query.Skip((page - 1) * recordOnPage)
34+
.Take(recordOnPage);
35+
return this;
36+
}
37+
38+
public TutorialSearchSpecification TutorialTitleSearch(string title)
39+
{
40+
if (string.IsNullOrWhiteSpace(title))
41+
return this;
42+
43+
Query.Where(w => w.Name.Contains(title));
44+
45+
return this;
46+
}
47+
48+
public TutorialSearchSpecification OrderByTitle()
49+
{
50+
Query.OrderBy(o => o.Name);
51+
return this;
52+
}
53+
54+
public TutorialSearchSpecification OrderByDateAdd()
55+
{
56+
Query.OrderByDescending(o => o.AddDate);
57+
return this;
58+
}
59+
60+
public TutorialSearchSpecification OrderByRating()
61+
{
62+
Query.OrderByDescending(o => o.Rating);
63+
return this;
64+
}
65+
66+
public TutorialSearchSpecification OrderByDateWatch()
67+
{
68+
Query.OrderByDescending(o => o.Folders.Max(m => m.Episodes.Max(m2 => m2.LastPlayedDate)));
69+
return this;
70+
}
71+
}
72+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Ardalis.GuardClauses;
2+
using dataneo.TutorialLibs.Domain.Categories;
3+
using dataneo.TutorialLibs.Domain.Settings;
4+
using Prism.Mvvm;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
9+
namespace dataneo.TutorialLibs.WPF.UI.TutorialList
10+
{
11+
internal sealed class CategoryManager : BindableBase
12+
{
13+
private readonly ICategoryRespositoryAsync _categoryRespositoryAsync;
14+
private readonly ISettingManager _settingManager;
15+
16+
public CategoryManager(ICategoryRespositoryAsync categoryRespositoryAsync, ISettingManager settingManager)
17+
{
18+
this._categoryRespositoryAsync = Guard.Against.Null(categoryRespositoryAsync, nameof(categoryRespositoryAsync));
19+
this._settingManager = Guard.Against.Null(settingManager, nameof(settingManager));
20+
}
21+
22+
private IEnumerable<CategoryMenuItem> _categories;
23+
public IEnumerable<CategoryMenuItem> Categories
24+
{
25+
get { return _categories; }
26+
set { _categories = value; RaisePropertyChanged(); }
27+
}
28+
29+
public async Task LoadCategoriesAsync()
30+
{
31+
var categories = await this._categoryRespositoryAsync.ListAllAsync();
32+
var savedSelectedCategories = await this._settingManager.GetValueIntCollectionAsync(SettingDefinition.LastCategory);
33+
var categoryMenuItems = CreateCategoryMenuItem(categories)
34+
.Concat(GetDefaultCategory())
35+
.ToArray();
36+
if (savedSelectedCategories.HasValue)
37+
SetStatusToCategories(categoryMenuItems, savedSelectedCategories.GetValueOrThrow());
38+
this.Categories = categoryMenuItems;
39+
}
40+
41+
public Task SaveCategoriesSelectAsync()
42+
=> this._settingManager.SetIntCollectionValueAsync(
43+
SettingDefinition.LastCategory,
44+
this.Categories.Where(w => w.IsChecked && w.FilterByCategory())
45+
.Select(s => s.GetCategoryId().Value)
46+
.Concat(this.Categories.Where(w => w.IsChecked && w.FilterByNone()).Take(1).Select(s => 0))
47+
.ToArray());
48+
49+
public IEnumerable<Category> GetFilteredCategories()
50+
=> this.Categories?.Where(w => w.IsChecked && w.FilterByCategory())
51+
.Select(s => s.GetCategory().GetValueOrThrow()) ?? Enumerable.Empty<Category>();
52+
53+
public bool IsFilterByNoCategory()
54+
=> this.Categories?.Any(a => a.FilterByNone()) ?? false;
55+
56+
private void SetStatusToCategories(IReadOnlyList<CategoryMenuItem> categoryMenuItems, IReadOnlyList<int> enabledCategoriesIds)
57+
{
58+
foreach (var category in categoryMenuItems)
59+
{
60+
category.IsChecked = category.GetCategoryId().HasValue &&
61+
enabledCategoriesIds.Contains(category.GetCategoryId().Value);
62+
63+
if (category.GetCategoryId().HasNoValue && enabledCategoriesIds.Contains(0))
64+
category.IsChecked = true;
65+
}
66+
}
67+
68+
private IEnumerable<CategoryMenuItem> CreateCategoryMenuItem(IReadOnlyList<Category> categories)
69+
=> categories
70+
.OrderBy(o => o.Name)
71+
.Select(category => new CategoryMenuItem(category));
72+
73+
private IEnumerable<CategoryMenuItem> GetDefaultCategory()
74+
{
75+
yield return CategoryMenuItem.CreateForNoCategory();
76+
}
77+
}
78+
}
Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,57 @@
1-
namespace dataneo.TutorialLibs.WPF.UI.TutorialList
1+
using Ardalis.Specification;
2+
using dataneo.TutorialLibs.Domain.Categories;
3+
using dataneo.TutorialLibs.Domain.Tutorials;
4+
using dataneo.TutorialLibs.Domain.Tutorials.Specifications;
5+
using System;
6+
using System.Collections.Generic;
7+
8+
namespace dataneo.TutorialLibs.WPF.UI.TutorialList
29
{
3-
public sealed class SpecificationBuilder
10+
internal sealed class SpecificationBuilder
411
{
12+
private readonly TutorialSearchSpecification _tutorialSearchSpecification = new TutorialSearchSpecification();
13+
14+
public SpecificationBuilder FilterByCategories(IEnumerable<Category> categories, bool filterWithNoCategory = true)
15+
{
16+
this._tutorialSearchSpecification.FilterByCategories(categories, filterWithNoCategory);
17+
return this;
18+
}
19+
20+
public SpecificationBuilder Page(short page, short recordOnPage)
21+
{
22+
this._tutorialSearchSpecification.Page(page, recordOnPage);
23+
return this;
24+
}
25+
26+
public SpecificationBuilder TutorialTitleSearch(string title)
27+
{
28+
this._tutorialSearchSpecification.TutorialTitleSearch(title);
29+
return this;
30+
}
31+
32+
public SpecificationBuilder OrderBy(TutorialsOrderType tutorialsOrderType)
33+
{
34+
switch (tutorialsOrderType)
35+
{
36+
case TutorialsOrderType.ByTitle:
37+
this._tutorialSearchSpecification.OrderByTitle();
38+
break;
39+
case TutorialsOrderType.ByDateAdd:
40+
this._tutorialSearchSpecification.OrderByDateAdd();
41+
break;
42+
case TutorialsOrderType.ByLastVisit:
43+
this._tutorialSearchSpecification.OrderByDateWatch();
44+
break;
45+
case TutorialsOrderType.ByRating:
46+
this._tutorialSearchSpecification.OrderByRating();
47+
break;
48+
default:
49+
throw new InvalidOperationException();
50+
}
51+
return this;
52+
}
553

54+
public ISpecification<Tutorial> GetSpecification()
55+
=> this._tutorialSearchSpecification;
656
}
757
}

src/dataneo.TutorialsLib.WPF/UI/TutorialList/TutorialListPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
</MenuItem>
183183
<MenuItem
184184
Header="{x:Static lang:UI.FILTER}"
185-
ItemsSource="{Binding Path=Categories, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
185+
ItemsSource="{Binding Path=CategoriesManager.Categories, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
186186
Style="{StaticResource menuItemColors}">
187187
<MenuItem.ItemContainerStyle>
188188
<Style TargetType="{x:Type MenuItem}">

0 commit comments

Comments
 (0)