LibSelector.razor 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. @inherits FnzComponentBase
  2. @code {
  3. [Parameter, Required] public FeLibrary CurrentLibrary { get; set; }
  4. [Parameter] public EventCallback<FeLibrary> OnValueChanged { get; set; }
  5. private FnzBootstrapCollapse SmallUi;
  6. private FnzBootstrapCollapse BigUi;
  7. private InputText FilterTextBox;
  8. }
  9. <FnzBootstrapCollapse @ref="SmallUi" CssClass="row show" OnHidden="()=>BigUi.Show()" OnShown="@(()=>{ JSRuntime.InvokeVoidAsync("fnz.scrollIntoViewById","MainNavBar"); })">
  10. <div class="col">
  11. <div class="d-flex flex-row align-items-center">
  12. <span>Library (@DataSet.AllLibrary.Length):&nbsp;</span>
  13. <button class="btn btn-primary p-1" type="button" @onclick="()=>SmallUi.Hide()">@($"{CurrentLibrary?.Name} ({CurrentLibrary?.Discs.Length})")</button>
  14. </div>
  15. </div>
  16. </FnzBootstrapCollapse>
  17. <FnzBootstrapCollapse @ref="BigUi" CssClass="row" OnHidden="()=>SmallUi.Show()" OnShown="()=>FilterTextBox.Element.Value.FocusAsync()">
  18. <div class="col">
  19. <fieldset class="border rounded-3 p-2">
  20. <legend class="float-none w-auto px-2 d-flex flex-row align-items-center">
  21. <span>Library (@DataSet.AllLibrary.Length):&nbsp;</span>
  22. <button class="btn btn-primary p-1" type="button" @onclick="()=>BigUi.Hide()">@($"{CurrentLibrary?.Name} ({CurrentLibrary?.Discs.Length})")</button>
  23. </legend>
  24. <div class="form-floating">
  25. <InputText @ref="FilterTextBox" type="search" placeholder="Filter" class="form-control" Value="@SearchValue" ValueExpression="@(()=>SearchValue)" @oninput="SearchChanged" onsearch="@SearchDone"></InputText>
  26. <label>Filter</label>
  27. </div>
  28. @foreach (var lib in (ListDataSource).KeepNoEmpty())
  29. {
  30. if (lib == null)
  31. {
  32. <button class="btn btn-secondary p-1 m-1" type="button" disabled>No result</button>
  33. }
  34. else
  35. {
  36. <button class="btn btn-secondary p-1 m-1" type="button" @onclick="()=>SelectLib(lib)">@($"{lib?.Name} ({lib?.Discs.Length})")</button>
  37. }
  38. }
  39. </fieldset>
  40. </div>
  41. </FnzBootstrapCollapse>
  42. @code {
  43. private string SearchValue { get; set; }
  44. private FeLibrary[] ListDataSource => DataSet.AllLibrary?.OrderBy(p => p.Key).Where(p => string.IsNullOrEmpty(SearchValue) || p.Name.Contains(SearchValue, StringComparison.OrdinalIgnoreCase)).ToArray();
  45. private void SearchChanged(ChangeEventArgs e)
  46. {
  47. SearchValue = e.Value.ToString();
  48. StateHasChanged();
  49. }
  50. private void SearchDone()
  51. {
  52. var arr = ListDataSource;
  53. if (arr?.Any() == true)
  54. {
  55. SelectLib(arr.First());
  56. }
  57. }
  58. private void SelectLib(FeLibrary lib)
  59. {
  60. OnValueChanged.InvokeAsync(lib);
  61. BigUi.Hide();
  62. StateHasChanged();
  63. }
  64. private async Task<List<FeLibrary>> FilterLibrary(IReadOnlyCollection<FeLibrary> source, string input, CancellationToken ct)
  65. {
  66. var result = new List<FeLibrary>();
  67. foreach (var item in source.Where(p => p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase))) result.Add(item);
  68. foreach (var item in source.Where(p => !p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase) && p.Name.Contains(input, StringComparison.OrdinalIgnoreCase))) result.Add(item);
  69. return result;
  70. }
  71. }