@page "/tasks/view/{viewId}" @using Tasks.Module.Models @using Tasks.Module.Services @inject IViewService ViewService @inject ITodoService TodoService @inject IDialogService Dialog @inject NavigationManager Navigation @inject ISnackbar Snackbar
@* Header *@
Back to Tasks

@_viewName

Tasks matching this view's criteria

@* View Criteria Summary *@ @if (_view != null && HasCriteria(_view)) {
View Criteria
@if (_view.Priority.HasValue) { Priority: @GetPriorityLabel(_view.Priority.Value) } @if (_view.IsCompleted.HasValue) { Status: @(_view.IsCompleted.Value ? "Completed" : "Pending") } @if (!string.IsNullOrWhiteSpace(_view.ContainsText)) { Contains: "@_view.ContainsText" } @if (_view.DueDateFrom.HasValue) { Due from: @_view.DueDateFrom.Value.ToString("MMM dd") } @if (_view.DueDateTo.HasValue) { Due to: @_view.DueDateTo.Value.ToString("MMM dd") }
} @* Quick Add Input - Creates task with view criteria *@
@if (!string.IsNullOrWhiteSpace(_view?.ContainsText)) { New tasks will be checked for text: "@_view.ContainsText" }
Add Add Task
@* Stats *@ @if (!isLoading && tasks.Any()) {
@tasks.Count task@(tasks.Count != 1 ? "s" : "") @{ var completed = tasks.Count(t => t.IsCompleted); var pending = tasks.Count - completed; } @if (pending > 0) { @pending pending } @if (completed > 0) { @completed completed }
} @* Tasks List *@ @if (isLoading) {
} else if (tasks.Count == 0) {

No tasks match this view

Add a task using the form above to create one with this view's criteria

} else {
@foreach (var task in tasks) { }
}
@code { [Parameter] public string viewId { get; set; } = string.Empty; private TaskViewDto? _view; private string _viewName = string.Empty; private List tasks = new(); private bool isLoading = true; private CreateTodoItemDto editTask = new(); private string currentTaskId = string.Empty; private string quickAddTitle = string.Empty; private HashSet collapsedTasks = new(); protected override async Task OnInitializedAsync() { await LoadView(); } private async Task LoadView() { isLoading = true; try { _view = await ViewService.GetViewByIdAsync(viewId); if (_view != null) { _viewName = _view.Name; tasks = await ViewService.GetTasksByViewAsync(viewId); } } finally { isLoading = false; } } private bool HasCriteria(TaskViewDto view) { return view.Priority.HasValue || view.IsCompleted.HasValue || !string.IsNullOrWhiteSpace(view.ContainsText) || view.DueDateFrom.HasValue || view.DueDateTo.HasValue; } private string GetPriorityLabel(int priority) { return priority switch { 2 => "High", 1 => "Medium", _ => "Low" }; } private string GetPriorityChipClass(int priority) { return priority switch { 2 => "bg-red-100 text-red-700", 1 => "bg-yellow-100 text-yellow-700", _ => "bg-green-100 text-green-700" }; } private bool TaskMatchesTextCriteria(string title) { if (string.IsNullOrWhiteSpace(_view?.ContainsText)) return true; return title.Contains(_view.ContainsText, StringComparison.OrdinalIgnoreCase); } private async Task HandleQuickAdd(KeyboardEventArgs e) { if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(quickAddTitle)) { await QuickAddTask(); } } private async Task QuickAddTask() { if (string.IsNullOrWhiteSpace(quickAddTitle)) return; if (!TaskMatchesTextCriteria(quickAddTitle)) { var confirmed = await Dialog.ShowMessageBox( "Warning", $"This task doesn't contain '{_view?.ContainsText}'. Adding it will not show in this view. Continue?", yesText: "Yes, add it", cancelText: "No"); if (confirmed != true) return; } var newTask = new CreateTodoItemDto { Title = quickAddTitle.Trim(), Priority = 0 }; await ViewService.CreateTodoWithViewCriteriaAsync(viewId, newTask); quickAddTitle = string.Empty; await LoadView(); } private void ToggleCollapse(string taskId) { if (collapsedTasks.Contains(taskId)) collapsedTasks.Remove(taskId); else collapsedTasks.Add(taskId); } private async Task ToggleTask(string id) { await TodoService.ToggleCompleteAsync(id); await LoadView(); } private async Task DeleteTask(string id) { await TodoService.DeleteTodoAsync(id); await LoadView(); } private async Task OpenCreateDialog() { editTask = new CreateTodoItemDto(); var parameters = new DialogParameters { { x => x.Task, editTask }, { x => x.IsUpdate, false } }; var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true }; var dialog = await Dialog.ShowAsync("Create Task", parameters, options); var result = await dialog.Result; if (result is { Canceled: false }) { if (!TaskMatchesTextCriteria(editTask.Title)) { var confirmed = await Dialog.ShowMessageBox( "Warning", $"This task doesn't contain '{_view?.ContainsText}'. Adding it will not show in this view. Continue?", yesText: "Yes, add it", cancelText: "No"); if (confirmed != true) return; } await ViewService.CreateTodoWithViewCriteriaAsync(viewId, editTask); await LoadView(); } } private async Task OpenAddChildDialog(TodoItemDto parentTask) { editTask = new CreateTodoItemDto { ParentId = parentTask.Id }; var parameters = new DialogParameters { { x => x.Task, editTask }, { x => x.IsUpdate, false }, { x => x.IsChild, true }, { x => x.ParentTitle, parentTask.Title } }; var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true }; var dialog = await Dialog.ShowAsync("Add Sub-task", parameters, options); var result = await dialog.Result; if (result is { Canceled: false }) { if (!TaskMatchesTextCriteria(editTask.Title)) { var confirmed = await Dialog.ShowMessageBox( "Warning", $"This task doesn't contain '{_view?.ContainsText}'. Adding it will not show in this view. Continue?", yesText: "Yes, add it", cancelText: "No"); if (confirmed != true) return; } await ViewService.CreateTodoWithViewCriteriaAsync(viewId, editTask); await LoadView(); } } private async Task OpenUpdateDialog(TodoItemDto task) { var confirmed = await Dialog.ShowMessageBox( "Edit Task Warning", "Editing this task may remove it from this view if the changes don't match the view criteria. Continue?", yesText: "Continue", cancelText: "Cancel"); if (confirmed != true) return; currentTaskId = task.Id; editTask = new CreateTodoItemDto { Title = task.Title, Description = task.Description, Priority = task.Priority, DueDate = task.DueDate, ParentId = task.ParentId, CategoryId = task.CategoryId, TagIds = task.TagIds.ToList(), FileId = task.FileId }; var parameters = new DialogParameters { { x => x.Task, editTask }, { x => x.IsUpdate, true } }; var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true }; var dialog = await Dialog.ShowAsync("Update Task", parameters, options); var result = await dialog.Result; if (result is { Canceled: false }) { await TodoService.UpdateTodoAsync(new UpdateTodoItemDto { Id = currentTaskId, Title = editTask.Title, Description = editTask.Description, Priority = editTask.Priority, DueDate = editTask.DueDate, IsCompleted = task.IsCompleted, ParentId = editTask.ParentId, CategoryId = editTask.CategoryId, TagIds = editTask.TagIds, FileId = editTask.FileId }); await LoadView(); } } }