From 9dad051a3d5069b774d125c8b1acae74f2f8000c Mon Sep 17 00:00:00 2001 From: Mark Otway Date: Tue, 31 Oct 2023 10:34:12 +0000 Subject: [PATCH] Add ability to clear individual filters --- .DS_Store | Bin 14340 -> 14340 bytes .../Damselfly.Core.DbModels.csproj | 2 - .../Interfaces/ISearchHint.cs | 9 ++ .../Interfaces/ISearchService.cs | 2 + .../Models/API Models/SearchHint.cs | 10 ++ .../BaseSearchService.cs | 100 ++++++++++++------ Damselfly.Web.Client/Shared/SearchBar.razor | 19 +++- Damselfly.Web.Client/wwwroot/css/site.css | 4 + Damselfly.Web.Client/wwwroot/version.js | 2 +- 9 files changed, 114 insertions(+), 34 deletions(-) create mode 100644 Damselfly.Core.DbModels/Interfaces/ISearchHint.cs create mode 100644 Damselfly.Core.DbModels/Models/API Models/SearchHint.cs diff --git a/.DS_Store b/.DS_Store index 674e5fa6871f7cb0ae7e0c67c3ca48a1fac7a8d5..3872ab331a7383b706ee1b0858305b41a62cb217 100644 GIT binary patch delta 41 jcmZoEXerpRS&iMo*i=Ws#C&ptu*2qGYCHMS1h^OhDoqV@ delta 43 kcmZoEXerpRS&hTc&`d|c)Y4*dqp - - diff --git a/Damselfly.Core.DbModels/Interfaces/ISearchHint.cs b/Damselfly.Core.DbModels/Interfaces/ISearchHint.cs new file mode 100644 index 00000000..3cb4a4e5 --- /dev/null +++ b/Damselfly.Core.DbModels/Interfaces/ISearchHint.cs @@ -0,0 +1,9 @@ +using System; + +namespace Damselfly.Core.ScopedServices.Interfaces; + +public interface ISearchHint +{ + Action Clear { get; set; } + string Description { get; set; } +} \ No newline at end of file diff --git a/Damselfly.Core.DbModels/Interfaces/ISearchService.cs b/Damselfly.Core.DbModels/Interfaces/ISearchService.cs index 2de2a4f1..9f556810 100644 --- a/Damselfly.Core.DbModels/Interfaces/ISearchService.cs +++ b/Damselfly.Core.DbModels/Interfaces/ISearchService.cs @@ -34,6 +34,8 @@ public interface ISearchService OrientationType? Orientation { get; set; } string SearchBreadcrumbs { get; } + IEnumerable SearchHints { get; } + void SetDateRange(DateTime? min, DateTime? max); void Refresh(); diff --git a/Damselfly.Core.DbModels/Models/API Models/SearchHint.cs b/Damselfly.Core.DbModels/Models/API Models/SearchHint.cs new file mode 100644 index 00000000..5b3670d5 --- /dev/null +++ b/Damselfly.Core.DbModels/Models/API Models/SearchHint.cs @@ -0,0 +1,10 @@ +using System; +using Damselfly.Core.ScopedServices.Interfaces; + +namespace Damselfly.Core.DbModels.Models.API_Models; + +public class SearchHint : ISearchHint +{ + public Action Clear { get; set; } + public string Description { get; set; } +} \ No newline at end of file diff --git a/Damselfly.Core.ScopedServices/BaseSearchService.cs b/Damselfly.Core.ScopedServices/BaseSearchService.cs index 860ce092..1c98d55d 100644 --- a/Damselfly.Core.ScopedServices/BaseSearchService.cs +++ b/Damselfly.Core.ScopedServices/BaseSearchService.cs @@ -1,6 +1,7 @@ -using System.Globalization; +using System.Globalization; using Damselfly.Core.Constants; using Damselfly.Core.DbModels; +using Damselfly.Core.DbModels.Models.API_Models; using Damselfly.Core.Models; using Damselfly.Core.ScopedServices.Interfaces; using Damselfly.Core.Utils; @@ -309,33 +310,58 @@ public OrientationType? Orientation public SearchQuery Query { get; } = new(); - public string SearchBreadcrumbs + public IEnumerable SearchHints { get { - var hints = new List(); + var hints = new List(); - if ( !string.IsNullOrEmpty(SearchText) ) - hints.Add($"Text: {SearchText}"); - - if ( Folder != null ) - hints.Add($"Folder: {Folder.Name}"); + if( !string.IsNullOrEmpty( SearchText) ) + { + var text = (TagsOnly ? "Text (tags only): " : "Text: ") + SearchText; + hints.Add( new SearchHint{ Description = text, Clear = () => SearchText = String.Empty }); + } - if ( Person != null ) - hints.Add($"Person: {Person.Name}"); + if( Folder != null ) + hints.Add( new SearchHint { Description = $"Folder: {Folder.Name}", Clear = () => Folder = null }); + + if( Person != null ) + hints.Add( new SearchHint { Description = $"Person: {Person.Name}", Clear = () => Person = null }); - if ( MinRating != null ) - hints.Add($"Rating: at least {MinRating} stars"); + if( Tag != null ) + hints.Add( new SearchHint { Description = $"Tag: {Tag.Keyword}", Clear = () => Tag = null }); + if( MinRating != null ) + hints.Add( new SearchHint { Description = $"Rating: at least {MinRating} stars", Clear = () => MinRating = null }); + if (SimilarToId != null) { var image = _imageCache.GetCachedImage(SimilarToId.Value).Result; if( image is not null ) - hints.Add($"Looks Like: {image.FileName}"); + hints.Add( new SearchHint { Description = $"Looks Like: {image.FileName}", Clear = () => SimilarToId = null } ); + } + + string dateString = string.Empty; + if( MaxSizeKB.HasValue && MinSizeKB.HasValue ) + { + dateString = $"Between {MinSizeKB.Value}KB and {MaxSizeKB.Value}KB"; } + else + { + if( MaxSizeKB.HasValue ) + dateString = $"Less than: {MaxSizeKB.Value}KB"; - if ( Tag != null ) - hints.Add($"Tag: {Tag.Keyword}"); + if( MinSizeKB.HasValue ) + dateString = $"At least: {MinSizeKB.Value}KB"; + } + + if( ! string.IsNullOrEmpty(dateString) ) + hints.Add( new SearchHint { Description = dateString, Clear = () => + { + MinSizeKB = null; + MaxSizeKB = null; + } + } ); var dateRange = string.Empty; if ( MinDate.HasValue ) @@ -350,39 +376,53 @@ public string SearchBreadcrumbs } if ( !string.IsNullOrEmpty(dateRange) ) - hints.Add($"Date: {dateRange}"); + hints.Add( new SearchHint {Description = $"Date: {dateRange}", Clear = () => + { + MinDate = null; + MaxDate = null; } + }); if ( UntaggedImages ) - hints.Add("Untagged images"); - - if (Month.HasValue) + hints.Add( new SearchHint {Description = "Untagged Images", Clear = () => UntaggedImages = false }); + + if( !IncludeChildFolders ) + hints.Add( new SearchHint {Description = "Exclude child folders", Clear = () => IncludeChildFolders = true }); + + if( Month.HasValue ) { string monthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(Month.Value); - hints.Add($"During {monthName}"); + hints.Add( new SearchHint { Description = $"During: {monthName}", Clear = () => Month = null } ); } - if ( FaceSearch.HasValue ) - hints.Add($"{FaceSearch.Humanize()}"); - - if ( Orientation.HasValue ) - hints.Add($"{Orientation.Humanize()}"); - if ( CameraId > 0 ) { var cam = _service.Cameras.FirstOrDefault(x => x.CameraId == CameraId); if ( cam != null ) - hints.Add($"Camera: {cam.Model}"); + hints.Add( new SearchHint{ Description = $"Camera: {cam.Model}", Clear = () => CameraId = null}); } if ( LensId > 0 ) { var lens = _service.Lenses.FirstOrDefault(x => x.LensId == LensId); if ( lens != null ) - hints.Add($"Lens: {lens.Model}"); + hints.Add( new SearchHint{ Description = $"Lens: {lens.Model}", Clear = () => LensId = null}); } + + if ( FaceSearch.HasValue ) + hints.Add( new SearchHint{ Description = FaceSearch.Humanize(), Clear = () => FaceSearch = null}); - if( !IncludeChildFolders ) - hints.Add( $"Exclude child folders" ); + if ( Orientation.HasValue ) + hints.Add( new SearchHint{ Description = Orientation.Humanize(), Clear = () => Orientation = null}); + + return hints; + } + } + + public string SearchBreadcrumbs + { + get + { + var hints = new List(); if( hints.Any() ) return string.Join(", ", hints); diff --git a/Damselfly.Web.Client/Shared/SearchBar.razor b/Damselfly.Web.Client/Shared/SearchBar.razor index 7e5850f2..f2c95446 100644 --- a/Damselfly.Web.Client/Shared/SearchBar.razor +++ b/Damselfly.Web.Client/Shared/SearchBar.razor @@ -34,7 +34,24 @@ - + @if( searchService.SearchHints.Any() ) + { +
+ + @foreach( var hint in searchService.SearchHints ) + { + + @hint.Description + + } + +
+ } + else + { + + } +
diff --git a/Damselfly.Web.Client/wwwroot/css/site.css b/Damselfly.Web.Client/wwwroot/css/site.css index da9ba69a..78f693db 100644 --- a/Damselfly.Web.Client/wwwroot/css/site.css +++ b/Damselfly.Web.Client/wwwroot/css/site.css @@ -33,6 +33,10 @@ html, body { font-weight: bold; } +.search-hints { + max-width: 700px; +} + .imagegrid-loader { width: 24px; height: 24px; diff --git a/Damselfly.Web.Client/wwwroot/version.js b/Damselfly.Web.Client/wwwroot/version.js index 0fa4406a..1cc44c4c 100644 --- a/Damselfly.Web.Client/wwwroot/version.js +++ b/Damselfly.Web.Client/wwwroot/version.js @@ -1 +1 @@ -const CACHE_VERSION='4.1.0-20231031073255' +const CACHE_VERSION='4.1.0-20231031103234'