278 lines
9.1 KiB
Plaintext
278 lines
9.1 KiB
Plaintext
@*
|
|
* dbMango
|
|
*
|
|
* Copyright 2025 Deutsche Bank AG
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*@
|
|
<div class="dropdown @Class">
|
|
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
@if (ShowSelectionText)
|
|
{
|
|
var s = string.Join(", ", _selectedValues.OrderBy(x => x).Select(x => string.IsNullOrWhiteSpace(x) ? DenoteEmptyString : x));
|
|
if ( s == string.Empty )
|
|
{
|
|
s = "(None)";
|
|
}
|
|
else if ( s.Length > 30 )
|
|
{
|
|
s = s[..20] + "...";
|
|
}
|
|
<span>@s</span>
|
|
}
|
|
else
|
|
{
|
|
@Name
|
|
}
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
|
@if (EnableDropdownMenu)
|
|
{
|
|
<div class="dropdown-item">
|
|
<span>
|
|
<button class="btn" @onclick="ToggleFilterable" title="toggle type-in filter">
|
|
<span class="m-auto ui-icon-font ui-icon-sm icon-search-sm"></span>
|
|
</button></span>
|
|
<span><button class="btn" @onclick="@CancelClicked" id="cancel" name="cancel" title="discard changes">Cancel</button></span>
|
|
<span><button class="btn" @onclick="@ApplyClicked" id="apply" name="apply" title="apply changes">Apply</button></span>
|
|
</div>
|
|
}
|
|
@if (Filterable)
|
|
{
|
|
<div class="dropdown-item">
|
|
<input class="form-control" @bind="FilterString" @bind:event="oninput"/>
|
|
</div>
|
|
}
|
|
<div class="dropdown-item">
|
|
@if (_allSelected)
|
|
{
|
|
<input type="checkbox" @onchange="_ => AllClicked()" checked id="all" name="all" value="all">
|
|
}
|
|
else
|
|
{
|
|
<input type="checkbox" @onchange="_ => AllClicked()" id="all" name="all" value="all">
|
|
}
|
|
<label for="all">(All)</label>
|
|
</div>
|
|
@foreach (var item in _filteredDropdown)
|
|
{
|
|
<div class="dropdown-item">
|
|
@if (_selectedValues.Contains(item))
|
|
{
|
|
<input type="checkbox" @onchange="eventArgs => { ItemCheckboxClicked(item, eventArgs.Value); }" checked id=@item name=@item value=@item>
|
|
}
|
|
else
|
|
{
|
|
<input type="checkbox" @onchange="eventArgs => { ItemCheckboxClicked(item, eventArgs.Value); }" id=@item name=@item value=@item>
|
|
}
|
|
<label for=@item>@item</label>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
@code
|
|
{
|
|
[Parameter] public string Name { get; set; } = "Select";
|
|
[Parameter] public string DenoteEmptyString { get; set; } = "(Blank)";
|
|
[Parameter] public string Class { get; set; } = "";
|
|
[Parameter] public bool ShowSelectionText { get; set; }
|
|
|
|
[Parameter]
|
|
public List<string> DropdownValues
|
|
{
|
|
get;
|
|
set
|
|
{
|
|
value ??= [];
|
|
if (field.SequenceEqual(value))
|
|
return;
|
|
|
|
field = value;
|
|
SetValues(BlankedDropdownValues);
|
|
UpdateAllSelected();
|
|
InvokeAsync(StateHasChanged);
|
|
}
|
|
} = [];
|
|
|
|
[Parameter] public EventCallback<List<string>> SelectionChanged { get; set; }
|
|
[Parameter] public bool EnableDropdownRefresh { get; set; }
|
|
[Parameter] public bool EnableDropdownMenu { get; set; } = true;
|
|
[Parameter] public bool Filterable { get; set; }
|
|
[Parameter] public bool ResetNow { get; set; }
|
|
[Parameter] public bool SelectAllByDefault { get; set; } = true;
|
|
|
|
[Parameter]
|
|
public string FilterString
|
|
{
|
|
get;
|
|
set
|
|
{
|
|
field = value;
|
|
_filterList = field.Split(",").Select(v => v.Trim()).Where(v => !string.IsNullOrWhiteSpace(v)).ToList();
|
|
RefreshFilter();
|
|
}
|
|
} = string.Empty;
|
|
|
|
private bool _allSelected = true;
|
|
private List<string> _dropdownValuesList = [];
|
|
private HashSet<string> _dropdownValuesSet = [];
|
|
private HashSet<string> _selectedValues = [];
|
|
private HashSet<string> _selectedValuesBackup = [];
|
|
private List<string> _filterList = [];
|
|
private List<string> _filteredDropdown = [];
|
|
|
|
IEnumerable<string> BlankedDropdownValues
|
|
=> DropdownValues?.Select(x => string.IsNullOrWhiteSpace(x) ? DenoteEmptyString : x) ?? Array.Empty<string>();
|
|
|
|
[Parameter] public HashSet<string> SelectedValues
|
|
{
|
|
get => _selectedValues;
|
|
set
|
|
{
|
|
if (value == null || ReferenceEquals(_selectedValues, value) || _selectedValues.SequenceEqual(value))
|
|
return;
|
|
_selectedValues = value;
|
|
SelectedValuesChanged.InvokeAsync(_selectedValues);
|
|
}
|
|
}
|
|
|
|
[Parameter] public EventCallback<HashSet<string>> SelectedValuesChanged { get; set; }
|
|
|
|
|
|
private void RefreshFilter()
|
|
{
|
|
_filteredDropdown.Clear();
|
|
if (_filterList.Count == 0)
|
|
_filteredDropdown.AddRange(BlankedDropdownValues);
|
|
else
|
|
_filteredDropdown.AddRange(
|
|
BlankedDropdownValues.Where(x =>
|
|
_filterList.Any(v => x.Contains(v, StringComparison.OrdinalIgnoreCase))));
|
|
}
|
|
|
|
private void SetValues(IEnumerable<string> values)
|
|
{
|
|
_dropdownValuesList.Clear();
|
|
_dropdownValuesList.AddRange(values);
|
|
_dropdownValuesSet.Clear();
|
|
_dropdownValuesSet.UnionWith(_dropdownValuesList);
|
|
}
|
|
|
|
private void ResetMenu(IEnumerable<string> values)
|
|
{
|
|
SetValues(values);
|
|
_selectedValues .Clear();
|
|
_selectedValues .UnionWith(_dropdownValuesSet);
|
|
_allSelected = true;
|
|
|
|
SelectedValuesChanged.InvokeAsync(_selectedValues);
|
|
}
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
if (SelectAllByDefault)
|
|
ResetMenu(BlankedDropdownValues);
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
|
|
if (!firstRender)
|
|
return;
|
|
|
|
if (!SelectAllByDefault)
|
|
{
|
|
SetValues(BlankedDropdownValues);
|
|
|
|
if ( UpdateAllSelected() )
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
|
|
private bool UpdateAllSelected()
|
|
{
|
|
var sel = _selectedValues.SetEquals(_dropdownValuesSet);
|
|
if (_allSelected != sel)
|
|
{
|
|
_allSelected = sel;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected override void OnParametersSet()
|
|
{
|
|
if (ResetNow)
|
|
{
|
|
ResetMenu(BlankedDropdownValues);
|
|
FilterString = string.Empty;
|
|
}
|
|
else if (EnableDropdownRefresh)
|
|
{
|
|
var newDropdownValues = new HashSet<string>(BlankedDropdownValues);
|
|
if (!newDropdownValues.SetEquals(_dropdownValuesSet))
|
|
ResetMenu(BlankedDropdownValues);
|
|
}
|
|
RefreshFilter();
|
|
}
|
|
|
|
public async Task AllClicked()
|
|
{
|
|
_allSelected = !_allSelected;
|
|
_selectedValues.Clear();
|
|
if (_allSelected)
|
|
_selectedValues.UnionWith(_dropdownValuesSet);
|
|
|
|
await SelectedValuesChanged.InvokeAsync(_selectedValues);
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
public void ItemCheckboxClicked(string item, object? checkedValue)
|
|
{
|
|
if (checkedValue is true)
|
|
_selectedValues.Add(item);
|
|
else
|
|
_selectedValues.Remove(item);
|
|
_allSelected = _selectedValues.SetEquals(_dropdownValuesSet);
|
|
|
|
SelectedValuesChanged.InvokeAsync(_selectedValues);
|
|
}
|
|
|
|
public void CancelClicked()
|
|
{
|
|
_selectedValues.Clear();
|
|
_selectedValues.UnionWith(_selectedValuesBackup);
|
|
_allSelected = _selectedValues.SetEquals(_dropdownValuesSet);
|
|
|
|
SelectedValuesChanged.InvokeAsync(_selectedValues);
|
|
}
|
|
|
|
public Task ApplyClicked()
|
|
{
|
|
_selectedValuesBackup.Clear();
|
|
_selectedValuesBackup.UnionWith(_selectedValues);
|
|
return SelectionChanged.InvokeAsync(_selectedValues.Select(x => x == DenoteEmptyString ? "" : x)
|
|
.ToList());
|
|
}
|
|
|
|
private void ToggleFilterable()
|
|
{
|
|
|
|
Filterable = !Filterable;
|
|
FilterString = string.Empty;
|
|
}
|
|
}
|