diff --git a/BTCPayServer.Tests/FastTests.cs b/BTCPayServer.Tests/FastTests.cs index 58cc75cfe5..d5d38e26c5 100644 --- a/BTCPayServer.Tests/FastTests.cs +++ b/BTCPayServer.Tests/FastTests.cs @@ -1299,17 +1299,22 @@ public void CanParseFilter() filter = "status:abed, status:abed2"; search = new SearchString(filter); - Assert.Equal("", search.TextSearch); + Assert.Null(search.TextSearch); + Assert.Null(search.TextFilters); Assert.Equal("status:abed, status:abed2", search.ToString()); Assert.Throws(() => search.Filters["test"]); Assert.Equal(2, search.Filters["status"].Count); Assert.Equal("abed", search.Filters["status"].First()); Assert.Equal("abed2", search.Filters["status"].Skip(1).First()); - filter = "StartDate:2019-04-25 01:00 AM, hekki"; + filter = "StartDate:2019-04-25 01:00 AM, hekki,orderid:MYORDERID,orderid:MYORDERID_2"; search = new SearchString(filter); Assert.Equal("2019-04-25 01:00 AM", search.Filters["startdate"].First()); Assert.Equal("hekki", search.TextSearch); + Assert.Equal("orderid:MYORDERID,orderid:MYORDERID_2", search.TextFilters); + Assert.Equal("orderid:MYORDERID,orderid:MYORDERID_2,hekki", search.TextCombined); + Assert.Equal("StartDate:2019-04-25 01:00 AM", search.WithoutSearchText()); + Assert.Equal(filter, search.ToString()); // modify search filter = $"status:settled,exceptionstatus:paidLate,unusual:true, fulltext searchterm, storeid:{storeId},startdate:2019-04-25 01:00:00"; diff --git a/BTCPayServer/Controllers/UIInvoiceController.UI.cs b/BTCPayServer/Controllers/UIInvoiceController.UI.cs index af1e6c66ce..f99d71f2e7 100644 --- a/BTCPayServer/Controllers/UIInvoiceController.UI.cs +++ b/BTCPayServer/Controllers/UIInvoiceController.UI.cs @@ -1111,7 +1111,7 @@ public async Task ListInvoices(InvoicesModel? model = null) storeIds.Add(i); } model.Search = fs; - model.SearchText = fs.TextSearch; + model.SearchText = fs.TextCombined; var apps = await _appService.GetAllApps(GetUserId(), false, storeId); InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, apps, timezoneOffset); diff --git a/BTCPayServer/SearchString.cs b/BTCPayServer/SearchString.cs index 004084bc86..03d9348f32 100644 --- a/BTCPayServer/SearchString.cs +++ b/BTCPayServer/SearchString.cs @@ -9,7 +9,8 @@ public class SearchString { private const char FilterSeparator = ','; private const char ValueSeparator = ':'; - + private static readonly string[] StripFilters = ["status", "exceptionstatus", "unusual", "includearchived", "appid", "startdate", "enddate"]; + private readonly string _originalString; private readonly int _timezoneOffset; @@ -27,12 +28,18 @@ public SearchString(string str, int timezoneOffset = 0) .Where(kv => kv.Length == 2) .Select(kv => new KeyValuePair(UnifyKey(kv[0]), kv[1])) .ToMultiValueDictionary(o => o.Key, o => o.Value); - - var val = splitted.FirstOrDefault(a => a.IndexOf(ValueSeparator, StringComparison.OrdinalIgnoreCase) == -1); - TextSearch = val != null ? val.Trim() : string.Empty; + // combine raw search term and filters which don't have a special UI (e.g. orderid) + var textFilters = Filters + .Where(f => !StripFilters.Contains(f.Key)) + .Select(f => string.Join(FilterSeparator, f.Value.Select(v => $"{f.Key}{ValueSeparator}{v}"))).ToList(); + TextFilters = textFilters.Any() ? string.Join(FilterSeparator, textFilters) : null; + TextSearch = splitted.FirstOrDefault(a => a.IndexOf(ValueSeparator, StringComparison.OrdinalIgnoreCase) == -1)?.Trim(); } public string TextSearch { get; private set; } + public string TextFilters { get; private set; } + + public string TextCombined => string.Join(FilterSeparator, new []{ TextFilters, TextSearch }.Where(x => !string.IsNullOrEmpty(x))); public MultiValueDictionary Filters { get; } @@ -82,9 +89,10 @@ public string Toggle(string key, string value) public string WithoutSearchText() { - return string.IsNullOrEmpty(TextSearch) - ? Finalize(ToString()) - : Finalize(ToString()).Replace(TextSearch, string.Empty); + var txt = ToString(); + if (!string.IsNullOrEmpty(TextSearch)) txt = Finalize(txt.Replace(TextSearch, string.Empty)); + if (!string.IsNullOrEmpty(TextFilters)) txt = Finalize(txt.Replace(TextFilters, string.Empty)); + return Finalize(txt).Trim(); } public string[] GetFilterArray(string key) @@ -144,7 +152,7 @@ private string UnifyKey(string key) private static string Finalize(string str) { - var value = str.TrimStart(FilterSeparator).TrimEnd(FilterSeparator); + var value = str.Trim().TrimStart(FilterSeparator).TrimEnd(FilterSeparator); return string.IsNullOrEmpty(value) ? " " : value; } }