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

273 lines
9.9 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 DocumentsPage : ContentPage
{
private readonly ObservableCollection<Document> _documents;
private List<Document> _allDocuments = new();
private string _currentFilter = "all";
private string _searchText = string.Empty;
public DocumentsPage()
{
try
{
Trace.WriteLine("=== DOCUMENTS PAGE CONSTRUCTOR START ===");
Trace.WriteLine("[DocumentsPage] >>> Вызов InitializeComponent");
InitializeComponent();
Trace.WriteLine("[DocumentsPage] >>> InitializeComponent завершен");
_documents = new ObservableCollection<Document>();
DocumentsCollectionView.ItemsSource = _documents;
Trace.WriteLine("[DocumentsPage] >>> Запуск LoadDocumentsAsync");
// Загружаем документы
_ = LoadDocumentsAsync();
Trace.WriteLine("=== DOCUMENTS PAGE CONSTRUCTOR END ===");
}
catch (Exception ex)
{
Trace.WriteLine("=== DOCUMENTS PAGE CONSTRUCTOR ERROR ===");
Trace.WriteLine($"[DocumentsPage] ❌ Тип ошибки: {ex.GetType().FullName}");
Trace.WriteLine($"[DocumentsPage] ❌ Сообщение: {ex.Message}");
Trace.WriteLine($"[DocumentsPage] ❌ 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("Ошибка DocumentsPage",
$"Ошибка инициализации:\n{ex.Message}\n\nStackTrace:\n{ex.StackTrace}", "OK");
}
}
});
throw;
}
}
private async Task LoadDocumentsAsync()
{
try
{
Trace.WriteLine("[DocumentsPage] >>> LoadDocumentsAsync START");
LoadingIndicator.IsVisible = true;
LoadingIndicator.IsRunning = true;
Trace.WriteLine("[DocumentsPage] >>> Вызов GetAllDocumentsAsync");
_allDocuments = await ServiceProvider.ApiService.GetAllDocumentsAsync();
Trace.WriteLine($"[DocumentsPage] >>> Получено документов: {_allDocuments.Count}");
ApplyFilters();
Trace.WriteLine($"[DocumentsPage] ✅ Документы загружены успешно");
}
catch (Exception ex)
{
Trace.WriteLine($"[DocumentsPage] ❌ Ошибка загрузки: {ex.GetType().Name}");
Trace.WriteLine($"[DocumentsPage] Message: {ex.Message}");
Trace.WriteLine($"[DocumentsPage] StackTrace: {ex.StackTrace}");
await DisplayAlert("Ошибка", $"Не удалось загрузить список документов:\n{ex.Message}", "OK");
}
finally
{
LoadingIndicator.IsVisible = false;
LoadingIndicator.IsRunning = false;
RefreshView.IsRefreshing = false;
}
}
private void ApplyFilters()
{
IEnumerable<Document> filtered = _allDocuments;
// Фильтр по статусу ознакомления
filtered = _currentFilter switch
{
"acknowledged" => filtered.Where(d => d.IsAcknowledged),
"not_acknowledged" => filtered.Where(d => !d.IsAcknowledged),
_ => filtered
};
// Фильтр по поиску
if (!string.IsNullOrWhiteSpace(_searchText))
{
string search = _searchText.ToLower();
filtered = filtered.Where(d =>
d.Title.ToLower().Contains(search) ||
d.Description.ToLower().Contains(search) ||
d.UploaderName.ToLower().Contains(search));
}
// Сортировка по дате загрузки (новые сверху)
filtered = filtered.OrderByDescending(d => d.UploadedAt);
_documents.Clear();
foreach (var document in filtered)
{
_documents.Add(document);
}
Trace.WriteLine($"[DocumentsPage] >>> Отображено документов: {_documents.Count}");
}
private async void OnRefreshing(object sender, EventArgs e)
{
await LoadDocumentsAsync();
}
private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
{
_searchText = e.NewTextValue ?? string.Empty;
ApplyFilters();
}
private async void OnDocumentSelected(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.FirstOrDefault() is Document selectedDocument)
{
// Сбрасываем выделение
DocumentsCollectionView.SelectedItem = null;
Trace.WriteLine($"[DocumentsPage] >>> Выбран документ: {selectedDocument.Title}");
// Показываем диалог с выбором действия
string action = await DisplayActionSheet(
selectedDocument.Title,
"Отмена",
null,
"📥 Открыть документ",
"ℹ️ Информация о документе");
if (action == "📥 Открыть документ")
{
await OpenDocumentAsync(selectedDocument);
}
else if (action == "ℹ️ Информация о документе")
{
await ShowDocumentInfoAsync(selectedDocument);
}
}
}
private async Task OpenDocumentAsync(Document document)
{
try
{
if (string.IsNullOrEmpty(document.FileUrl))
{
await DisplayAlert("Ошибка", "URL документа не найден", "OK");
return;
}
Trace.WriteLine($"[DocumentsPage] >>> Открытие документа: {document.FileUrl}");
// Открываем документ в браузере
await Launcher.OpenAsync(new Uri(document.FileUrl));
}
catch (Exception ex)
{
Trace.WriteLine($"[DocumentsPage] ❌ Ошибка открытия документа: {ex.Message}");
await DisplayAlert("Ошибка", $"Не удалось открыть документ:\n{ex.Message}", "OK");
}
}
private async Task ShowDocumentInfoAsync(Document document)
{
string info = $"📄 {document.Title}\n\n";
if (!string.IsNullOrEmpty(document.Description))
{
info += $"📝 Описание:\n{document.Description}\n\n";
}
info += $"👤 Загрузил: {document.UploaderName}\n";
info += $"📅 Дата загрузки: {document.DisplayUploadedAt}\n";
info += $"📁 Тип файла: {document.FileExtension.ToUpper()}\n";
info += $"📨 Для всех: {(document.SentToAll ? "Да" : "Нет")}\n";
info += $"{document.AcknowledgedIcon} Статус: {document.AcknowledgedText}";
await DisplayAlert("Информация о документе", info, "OK");
}
private async void OnBackClicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("..");
}
#region Фильтры
private void OnFilterAllTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("all");
ApplyFilters();
}
private void OnFilterAcknowledgedTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("acknowledged");
ApplyFilters();
}
private void OnFilterNotAcknowledgedTapped(object sender, TappedEventArgs e)
{
SetActiveFilter("not_acknowledged");
ApplyFilters();
}
private void SetActiveFilter(string filter)
{
_currentFilter = filter;
// Получаем стили из Application.Current.Resources
Style? chipButton = Application.Current?.Resources["ChipButton"] as Style;
Style? chipButtonActive = Application.Current?.Resources["ChipButtonActive"] as Style;
Color? grayColor = Application.Current?.Resources["Gray700"] as Color ?? Colors.Gray;
// Сбрасываем все фильтры на неактивные
if (chipButton != null)
{
FilterAll.Style = chipButton;
FilterAcknowledged.Style = chipButton;
FilterNotAcknowledged.Style = chipButton;
}
// Обновляем цвет текста у неактивных
if (FilterAll.Content is Label allLabel)
allLabel.TextColor = grayColor;
if (FilterAcknowledged.Content is Label acknowledgedLabel)
acknowledgedLabel.TextColor = grayColor;
if (FilterNotAcknowledged.Content is Label notAcknowledgedLabel)
notAcknowledgedLabel.TextColor = grayColor;
// Активируем выбранный фильтр
Border activeFilter = filter switch
{
"acknowledged" => FilterAcknowledged,
"not_acknowledged" => FilterNotAcknowledged,
_ => FilterAll
};
if (chipButtonActive != null)
activeFilter.Style = chipButtonActive;
if (activeFilter.Content is Label activeLabel)
activeLabel.TextColor = Colors.White;
}
#endregion
}