corp-app/CORP-MAUI/Pages/RequestsPage.xaml.cs

286 lines
10 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.ObjectModel;
using System.Diagnostics;
using CORP_MAUI.Models;
namespace CORP_MAUI.Pages;
public partial class RequestsPage : ContentPage
{
private readonly ObservableCollection<Request> _requests;
private List<Request> _allRequests = new();
private string _currentFilter = "all";
private string _searchText = string.Empty;
public RequestsPage()
{
try
{
Trace.WriteLine("=== REQUESTSPAGE CONSTRUCTOR START ===");
Trace.WriteLine("[RequestsPage] >>> Вызов InitializeComponent");
InitializeComponent();
Trace.WriteLine("[RequestsPage] >>> InitializeComponent завершен");
_requests = new ObservableCollection<Request>();
RequestsCollectionView.ItemsSource = _requests;
Trace.WriteLine("[RequestsPage] >>> Запуск LoadRequestsAsync");
// Загружаем заявления
_ = LoadRequestsAsync();
Trace.WriteLine("=== REQUESTSPAGE CONSTRUCTOR END ===");
}
catch (Exception ex)
{
Trace.WriteLine("=== REQUESTSPAGE CONSTRUCTOR ERROR ===");
Trace.WriteLine($"[RequestsPage] ❌ Тип ошибки: {ex.GetType().FullName}");
Trace.WriteLine($"[RequestsPage] ❌ Сообщение: {ex.Message}");
Trace.WriteLine($"[RequestsPage] ❌ StackTrace: {ex.StackTrace}");
// Показываем ошибку напрямую
Task.Run(async () =>
{
await Task.Delay(100);
if (Application.Current?.Windows.Count > 0)
{
Page? mainPage = Application.Current.Windows[0].Page;
if (mainPage != null)
{
await mainPage.DisplayAlert("Ошибка RequestsPage",
$"Ошибка инициализации:\n{ex.Message}\n\nStackTrace:\n{ex.StackTrace}", "OK");
}
}
});
throw;
}
}
private async Task LoadRequestsAsync()
{
try
{
Trace.WriteLine("[RequestsPage] >>> LoadRequestsAsync START");
LoadingIndicator.IsVisible = true;
LoadingIndicator.IsRunning = true;
Trace.WriteLine("[RequestsPage] >>> Вызов GetAllRequestsAsync");
_allRequests = await ServiceProvider.ApiService.GetAllRequestsAsync();
Trace.WriteLine($"[RequestsPage] >>> Получено заявлений: {_allRequests.Count}");
ApplyFilters();
Trace.WriteLine($"[RequestsPage] ✅ Заявления загружены успешно");
}
catch (Exception ex)
{
Trace.WriteLine($"[RequestsPage] ❌ Ошибка загрузки: {ex.GetType().Name}");
Trace.WriteLine($"[RequestsPage] Message: {ex.Message}");
Trace.WriteLine($"[RequestsPage] StackTrace: {ex.StackTrace}");
await DisplayAlert("Ошибка", $"Не удалось загрузить список заявлений:\n{ex.Message}", "OK");
}
finally
{
LoadingIndicator.IsVisible = false;
LoadingIndicator.IsRunning = false;
RefreshView.IsRefreshing = false;
}
}
private void ApplyFilters()
{
IEnumerable<Request> filtered = _allRequests;
// Фильтр по статусу
filtered = _currentFilter switch
{
"pending" => filtered.Where(r =>
r.Status.Equals("pending", StringComparison.OrdinalIgnoreCase) ||
r.Status.Equals("waiting", StringComparison.OrdinalIgnoreCase)),
"approved" => filtered.Where(r =>
r.Status.Equals("approved", StringComparison.OrdinalIgnoreCase) ||
r.Status.Equals("accepted", StringComparison.OrdinalIgnoreCase)),
"rejected" => filtered.Where(r =>
r.Status.Equals("rejected", StringComparison.OrdinalIgnoreCase) ||
r.Status.Equals("declined", StringComparison.OrdinalIgnoreCase) ||
r.Status.Equals("cancelled", StringComparison.OrdinalIgnoreCase)),
_ => filtered
};
// Фильтр по поиску
if (!string.IsNullOrWhiteSpace(_searchText))
{
string search = _searchText.ToLower();
filtered = filtered.Where(r =>
r.DisplayType.ToLower().Contains(search) ||
r.DisplayStatus.ToLower().Contains(search) ||
r.DisplayDescription.ToLower().Contains(search) ||
r.EmployeeName.ToLower().Contains(search));
}
// Сортировка по дате (новые сверху)
filtered = filtered.OrderByDescending(r => r.CreatedAt);
_requests.Clear();
foreach (var request in filtered)
{
_requests.Add(request);
}
Trace.WriteLine($"[RequestsPage] >>> Отображено заявлений: {_requests.Count}");
}
private async void OnRefreshing(object sender, EventArgs e)
{
await LoadRequestsAsync();
}
private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
{
_searchText = e.NewTextValue ?? string.Empty;
ApplyFilters();
}
private async void OnRequestSelected(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.FirstOrDefault() is Request selectedRequest)
{
// Сбрасываем выбор
RequestsCollectionView.SelectedItem = null;
// Показываем детали заявления
await ShowRequestDetails(selectedRequest);
}
}
private async Task ShowRequestDetails(Request request)
{
string details = $"Тип: {request.DisplayType}\n" +
$"Статус: {request.DisplayStatus}\n" +
$"Дата создания: {request.DisplayCreatedAt}\n";
if (!string.IsNullOrEmpty(request.DisplayPeriod))
details += $"Период: {request.DisplayPeriod}\n";
details += $"\nОт кого: {request.EmployeeName}\n";
if (!string.IsNullOrEmpty(request.Comment))
details += $"\nОписание:\n{request.Comment}\n";
// Получатели
if (request.Recipients != null && request.Recipients.Count > 0)
{
details += $"\n📬 Получатели ({request.Recipients.Count}):\n";
foreach (var recipient in request.Recipients)
{
details += $" • {recipient.FullName}\n";
}
}
else if (request.RecipientCount > 0)
{
details += $"\n📬 Получателей: {request.RecipientCount}\n";
}
// В копии
if (request.CcUsers != null && request.CcUsers.Count > 0)
{
details += $"\n📋 В копии ({request.CcUsers.Count}):\n";
foreach (var ccUser in request.CcUsers)
{
details += $" • {ccUser.FullName}\n";
}
}
else if (request.CcCount > 0)
{
details += $"\n📋 В копии: {request.CcCount}\n";
}
// Решение
if (request.Approver != null)
details += $"\n✍️ Решение принял: {request.ApproverName}";
if (request.DecidedAt.HasValue)
details += $"\n📅 Дата решения: {request.DecidedAt.Value:dd.MM.yyyy HH:mm}";
await DisplayAlert($"{request.TypeIcon} {request.DisplayType}", details, "Закрыть");
}
// ================================
// Обработчики фильтров
// ================================
private void OnFilterAllTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("all");
}
private void OnFilterPendingTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("pending");
}
private void OnFilterApprovedTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("approved");
}
private void OnFilterRejectedTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("rejected");
}
private void SetActiveFilter(string filter)
{
_currentFilter = filter;
// Обновляем визуальное состояние кнопок
UpdateFilterButtonStyles();
// Применяем фильтры
ApplyFilters();
}
private void UpdateFilterButtonStyles()
{
// Сбрасываем все кнопки
FilterAll.BackgroundColor = Colors.White;
FilterAll.Stroke = Color.FromArgb("#D1D5DB");
if (FilterAll.Content is Label labelAll)
labelAll.TextColor = Color.FromArgb("#374151");
FilterPending.BackgroundColor = Colors.White;
FilterPending.Stroke = Color.FromArgb("#D1D5DB");
if (FilterPending.Content is Label labelPending)
labelPending.TextColor = Color.FromArgb("#374151");
FilterApproved.BackgroundColor = Colors.White;
FilterApproved.Stroke = Color.FromArgb("#D1D5DB");
if (FilterApproved.Content is Label labelApproved)
labelApproved.TextColor = Color.FromArgb("#374151");
FilterRejected.BackgroundColor = Colors.White;
FilterRejected.Stroke = Color.FromArgb("#D1D5DB");
if (FilterRejected.Content is Label labelRejected)
labelRejected.TextColor = Color.FromArgb("#374151");
// Активируем выбранную кнопку
Border activeButton = _currentFilter switch
{
"pending" => FilterPending,
"approved" => FilterApproved,
"rejected" => FilterRejected,
_ => FilterAll
};
activeButton.BackgroundColor = (Color)Application.Current!.Resources["Primary"];
activeButton.Stroke = Colors.Transparent;
if (activeButton.Content is Label activeLabel)
activeLabel.TextColor = Colors.White;
}
}