182 lines
4.9 KiB
Dart
182 lines
4.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:marco/helpers/services/api_service.dart';
|
|
import 'package:marco/model/document/document_filter_model.dart';
|
|
import 'package:marco/model/document/documents_list_model.dart';
|
|
|
|
class DocumentController extends GetxController {
|
|
// ------------------ Observables ---------------------
|
|
var isLoading = false.obs;
|
|
var documents = <DocumentItem>[].obs;
|
|
var filters = Rxn<DocumentFiltersData>();
|
|
|
|
// ✅ Selected filters (multi-select support)
|
|
var selectedUploadedBy = <String>[].obs;
|
|
var selectedCategory = <String>[].obs;
|
|
var selectedType = <String>[].obs;
|
|
var selectedTag = <String>[].obs;
|
|
|
|
// Pagination state
|
|
var pageNumber = 1.obs;
|
|
final int pageSize = 20;
|
|
var hasMore = true.obs;
|
|
|
|
// Error message
|
|
var errorMessage = "".obs;
|
|
|
|
// NEW: show inactive toggle
|
|
var showInactive = false.obs;
|
|
|
|
// NEW: search
|
|
var searchQuery = ''.obs;
|
|
var searchController = TextEditingController();
|
|
// New filter fields
|
|
var isUploadedAt = true.obs;
|
|
var isVerified = RxnBool();
|
|
var startDate = Rxn<String>();
|
|
var endDate = Rxn<String>();
|
|
|
|
// ------------------ API Calls -----------------------
|
|
|
|
/// Fetch Document Filters for an Entity
|
|
Future<void> fetchFilters(String entityTypeId) async {
|
|
try {
|
|
isLoading.value = true;
|
|
final response = await ApiService.getDocumentFilters(entityTypeId);
|
|
|
|
if (response != null && response.success) {
|
|
filters.value = response.data;
|
|
} else {
|
|
errorMessage.value = response?.message ?? "Failed to fetch filters";
|
|
}
|
|
} catch (e) {
|
|
errorMessage.value = "Error fetching filters: $e";
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
/// Toggle document active/inactive state
|
|
Future<bool> toggleDocumentActive(
|
|
String id, {
|
|
required bool isActive,
|
|
required String entityTypeId,
|
|
required String entityId,
|
|
}) async {
|
|
try {
|
|
isLoading.value = true;
|
|
final success =
|
|
await ApiService.deleteDocumentApi(id: id, isActive: isActive);
|
|
|
|
if (success) {
|
|
// 🔥 Always fetch fresh list after toggle
|
|
await fetchDocuments(
|
|
entityTypeId: entityTypeId,
|
|
entityId: entityId,
|
|
reset: true,
|
|
);
|
|
return true;
|
|
} else {
|
|
errorMessage.value = "Failed to update document state";
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
errorMessage.value = "Error updating document: $e";
|
|
return false;
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
/// Permanently delete a document (or deactivate depending on API)
|
|
Future<bool> deleteDocument(String id, {bool isActive = false}) async {
|
|
try {
|
|
isLoading.value = true;
|
|
final success =
|
|
await ApiService.deleteDocumentApi(id: id, isActive: isActive);
|
|
|
|
if (success) {
|
|
// remove from local list immediately for better UX
|
|
documents.removeWhere((doc) => doc.id == id);
|
|
return true;
|
|
} else {
|
|
errorMessage.value = "Failed to delete document";
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
errorMessage.value = "Error deleting document: $e";
|
|
return false;
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
/// Fetch Documents for an entity
|
|
Future<void> fetchDocuments({
|
|
required String entityTypeId,
|
|
required String entityId,
|
|
String? filter,
|
|
String? searchString,
|
|
bool reset = false,
|
|
}) async {
|
|
try {
|
|
if (reset) {
|
|
pageNumber.value = 1;
|
|
documents.clear();
|
|
hasMore.value = true;
|
|
}
|
|
|
|
if (!hasMore.value) return;
|
|
|
|
isLoading.value = true;
|
|
|
|
final response = await ApiService.getDocumentListApi(
|
|
entityTypeId: entityTypeId,
|
|
entityId: entityId,
|
|
filter: filter ?? "",
|
|
searchString: searchString ?? searchQuery.value,
|
|
pageNumber: pageNumber.value,
|
|
pageSize: pageSize,
|
|
isActive: !showInactive.value,
|
|
);
|
|
|
|
if (response != null && response.success) {
|
|
if (response.data.data.isNotEmpty) {
|
|
documents.addAll(response.data.data);
|
|
pageNumber.value++;
|
|
} else {
|
|
hasMore.value = false;
|
|
}
|
|
} else {
|
|
errorMessage.value = response?.message ?? "Failed to fetch documents";
|
|
}
|
|
} catch (e) {
|
|
errorMessage.value = "Error fetching documents: $e";
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// ------------------ Helpers -----------------------
|
|
|
|
/// Clear selected filters
|
|
void clearFilters() {
|
|
selectedUploadedBy.clear();
|
|
selectedCategory.clear();
|
|
selectedType.clear();
|
|
selectedTag.clear();
|
|
isUploadedAt.value = true;
|
|
isVerified.value = null;
|
|
startDate.value = null;
|
|
endDate.value = null;
|
|
}
|
|
|
|
/// Check if any filters are active (for red dot indicator)
|
|
bool hasActiveFilters() {
|
|
return selectedUploadedBy.isNotEmpty ||
|
|
selectedCategory.isNotEmpty ||
|
|
selectedType.isNotEmpty ||
|
|
selectedTag.isNotEmpty;
|
|
}
|
|
}
|