LibSelector.razor 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. @inject IJSRuntime js
  2. @code {
  3. [Parameter, Required] public FeLibrary CurrentLibrary { get; set; }
  4. [Parameter] public EventCallback<FeLibrary> OnValueChanged { get; set; }
  5. }
  6. <div class="row collapse show" id="LibSelectorListCollapsed">
  7. <div class="col">
  8. <div class="d-flex flex-row align-items-center">
  9. <span>Library (@FnzDataSet.AllLibrary.Length):&nbsp;</span>
  10. <button class="btn btn-primary p-1" type="button" @onclick="ShowLibraryList">@($"{CurrentLibrary?.Name} ({CurrentLibrary?.Discs.Length})")</button>
  11. </div>
  12. </div>
  13. </div>
  14. <div class="row collapse" id="LibSelectorList">
  15. <div class="col">
  16. <fieldset class="border rounded-3 p-2">
  17. <legend class="float-none w-auto px-2 d-flex flex-row align-items-center">
  18. <span>Library (@FnzDataSet.AllLibrary.Length):&nbsp;</span>
  19. <button class="btn btn-primary p-1" type="button" @onclick="HideLibraryList">@($"{CurrentLibrary?.Name} ({CurrentLibrary?.Discs.Length})")</button>
  20. </legend>
  21. <div class="mt-0">
  22. <div class="d-flex">
  23. <div class="">
  24. Filter:&nbsp;
  25. </div>
  26. <div class="col flex-fill">
  27. <InputText id="LibSelectorInput" class="w-100" Value="@SearchValue" ValueExpression="@(()=>SearchValue)" @oninput="SearchChanged" @onkeydown="SearchKeydown"></InputText>
  28. </div>
  29. </div>
  30. </div>
  31. @foreach (var lib in (ListDataSource).KeepNoEmpty())
  32. {
  33. if (lib == null)
  34. {
  35. <button class="btn btn-secondary p-1 m-1" type="button" disabled>No result</button>
  36. }
  37. else
  38. {
  39. <button class="btn btn-secondary p-1 m-1" type="button" @onclick="()=>SelectLib(lib)">@($"{lib?.Name} ({lib?.Discs.Length})")</button>
  40. }
  41. }
  42. </fieldset>
  43. </div>
  44. </div>
  45. @code {
  46. private ValueTask ExpandLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList", true);
  47. private ValueTask CollapseLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList", false);
  48. private ValueTask ToggleLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList");
  49. private string SearchValue { get; set; }
  50. private FeLibrary[] ListDataSource => FnzDataSet.AllLibrary?.OrderBy(p => p.Key).Where(p => string.IsNullOrEmpty(SearchValue) || p.Name.Contains(SearchValue, StringComparison.OrdinalIgnoreCase)).ToArray();
  51. private async Task ShowLibraryList()
  52. {
  53. await ExpandLibraryList();
  54. }
  55. private async Task HideLibraryList()
  56. {
  57. await CollapseLibraryList();
  58. }
  59. private void SearchChanged(ChangeEventArgs e)
  60. {
  61. SearchValue = e.Value.ToString();
  62. StateHasChanged();
  63. }
  64. private void SearchKeydown(KeyboardEventArgs e)
  65. {
  66. if (e.Code == "Enter")
  67. {
  68. var arr = ListDataSource;
  69. if (arr?.Any() == true)
  70. {
  71. SelectLib(arr.First());
  72. }
  73. }
  74. }
  75. private void SelectLib(FeLibrary lib)
  76. {
  77. OnValueChanged.InvokeAsync(lib);
  78. CollapseLibraryList();
  79. StateHasChanged();
  80. }
  81. private async Task<List<FeLibrary>> FilterLibrary(IReadOnlyCollection<FeLibrary> source, string input, CancellationToken ct)
  82. {
  83. var result = new List<FeLibrary>();
  84. foreach (var item in source.Where(p => p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase))) result.Add(item);
  85. foreach (var item in source.Where(p => !p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase) && p.Name.Contains(input, StringComparison.OrdinalIgnoreCase))) result.Add(item);
  86. return result;
  87. }
  88. }