Files
2026-08-07 02:17:32 +03:00

113 lines
4.0 KiB
Plaintext

@using Tasks.Module.Models
@using Tasks.Module.Services
<MudExpansionPanel @bind-IsExpanded="_expanded" Class="category-item">
<TitleContent>
<div class="d-flex align-center justify-space-between" style="width: 100%;">
<div class="d-flex align-center">
@if (Category.Children.Count > 0)
{
<span class="expand-chevron" style="cursor: pointer; padding: 4px;"
@onclick:stopPropagation="true"
@onclick="@(() => { _expanded = !_expanded; })">
<MudIcon Icon="@(_expanded ? Icons.Material.Filled.KeyboardArrowDown : Icons.Material.Filled.KeyboardArrowRight)"
Size="Size.Small"
Class="mr-1"
Style="width: 20px; display: block;" />
</span>
}
else
{
<div style="width: 32px;"></div>
}
<MudIcon Icon="@Icons.Material.Filled.Folder" Color="Color.Default" Class="mr-2" />
<span class="task-title">@HighlightText(Category.Name)</span>
</div>
<div class="d-flex align-center gap-1">
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="mr-2">
@Category.Children.Count children
</MudText>
<MudIconButton Icon="@Icons.Material.Filled.Add"
Size="Size.Small"
Title="Add sub-category"
OnClick="() => OnAddChild.InvokeAsync(Category)" />
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="Size.Small"
Title="Edit"
OnClick="() => OnUpdate.InvokeAsync(Category)" />
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Size="Size.Small"
Color="Color.Error"
Title="Delete"
OnClick="() => OnDelete.InvokeAsync(Category)" />
</div>
</div>
</TitleContent>
<ChildContent>
<div class="pl-4">
@foreach (var child in Category.Children)
{
<CategoryTreeItem Category="child"
OnAddChild="OnAddChild"
OnDelete="OnDelete"
OnUpdate="OnUpdate"
SearchText="SearchText" />
}
</div>
</ChildContent>
</MudExpansionPanel>
@code {
[Parameter]
public CategoryDto Category { get; set; } = new();
[Parameter]
public EventCallback<CategoryDto> OnAddChild { get; set; }
[Parameter]
public EventCallback<CategoryDto> OnDelete { get; set; }
[Parameter]
public EventCallback<CategoryDto> OnUpdate { get; set; }
[Parameter]
public string SearchText { get; set; } = string.Empty;
private bool _expanded = false;
private RenderFragment HighlightText(string text)
{
if (string.IsNullOrEmpty(SearchText))
{
return @<span>@text</span>;
}
var parts = text.Split(new[] { SearchText }, StringSplitOptions.None);
return@<text>
@{
for (int i = 0; i < parts.Length; i++)
{
@parts[i]
if (i < parts.Length - 1)
{
<mark class="search-highlight">@SearchText</mark>
}
}
}
</text>;
}
}
<style>
.category-item {
border-bottom: 1px solid var(--mud-palette-lines-default);
}
.category-item:last-child {
border-bottom: none;
}
.search-highlight {
background-color: yellow;
padding: 0 2px;
}
</style>