You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
10 KiB
TypeScript
340 lines
10 KiB
TypeScript
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { TranslateModule } from '@ngx-translate/core';
|
|
import { ExcelExportService } from '../shared/services/excel-export.service';
|
|
import { TRANSACTION_LOGS_FILE_NAME } from '../utils/app.constants';
|
|
import { pageSizeOptions } from '../utils/app.constants';
|
|
import { NgSelectModule } from '@ng-select/ng-select';
|
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
import { TableFilterPipe } from '../shared/pipes/table-filter.pipe';
|
|
import { TransactionLog } from "../models/user";
|
|
import { URIKey } from '../utils/uri-enums';
|
|
import { HttpParams } from '@angular/common/http';
|
|
import { HttpURIService } from '../app.http.uri.service';
|
|
import { formatDate } from '@angular/common';
|
|
import { Subject } from 'rxjs';
|
|
import { takeUntil, debounceTime } from 'rxjs/operators';
|
|
|
|
@Component({
|
|
selector: 'app-transaction-logs',
|
|
templateUrl: './transaction-logs.component.html',
|
|
styleUrls: ['./transaction-logs.component.scss'],
|
|
imports: [CommonModule, TranslateModule, NgSelectModule, FormsModule, ReactiveFormsModule, TableFilterPipe]
|
|
})
|
|
export class TransactionLogsComponent implements OnInit, OnDestroy {
|
|
currentPage: number = 1;
|
|
totalCount: number = 0;
|
|
renewalDataExpanded: boolean = true;
|
|
pageSizeOptions = pageSizeOptions;
|
|
itemsPerPage: number = 10;
|
|
transactionLog: TransactionLog[] = [];
|
|
isLoading = false;
|
|
errorMessage: string = '';
|
|
searchText: string = '';
|
|
allItems: TransactionLog[] = [];
|
|
transactionDataExpanded: boolean = true;
|
|
|
|
// Date range properties
|
|
fromDate: string = '';
|
|
toDate: string = '';
|
|
maxDate: string = '';
|
|
showDateFilters: boolean = false;
|
|
|
|
// Search subject for debouncing
|
|
private searchSubject = new Subject<string>();
|
|
private destroy$ = new Subject<void>();
|
|
|
|
constructor(
|
|
private excelExportService: ExcelExportService,
|
|
private httpService: HttpURIService,
|
|
) {}
|
|
|
|
ngOnInit(): void {
|
|
// Set max date to today
|
|
this.maxDate = formatDate(new Date(), 'yyyy-MM-dd', 'en-US');
|
|
|
|
// Set default date range (last 7 days)
|
|
const today = new Date();
|
|
const lastWeek = new Date();
|
|
lastWeek.setDate(today.getDate() - 7);
|
|
|
|
this.fromDate = formatDate(lastWeek, 'yyyy-MM-dd', 'en-US');
|
|
this.toDate = formatDate(today, 'yyyy-MM-dd', 'en-US');
|
|
|
|
// Set up search debouncing
|
|
this.setupSearchDebounce();
|
|
|
|
this.loadTransactionLogs();
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.destroy$.next();
|
|
this.destroy$.complete();
|
|
this.searchSubject.complete();
|
|
}
|
|
|
|
private setupSearchDebounce(): void {
|
|
this.searchSubject.pipe(
|
|
takeUntil(this.destroy$),
|
|
debounceTime(300)
|
|
).subscribe((searchValue: string) => {
|
|
this.searchText = searchValue;
|
|
this.currentPage = 1;
|
|
this.loadTransactionLogs();
|
|
});
|
|
}
|
|
|
|
loadTransactionLogs(): void {
|
|
this.isLoading = true;
|
|
this.errorMessage = '';
|
|
|
|
// Validate date range before making API call
|
|
if (!this.validateDateRange()) {
|
|
this.isLoading = false;
|
|
return;
|
|
}
|
|
|
|
// Build query parameters
|
|
let params = new HttpParams();
|
|
|
|
// Add pagination parameters
|
|
params = params.set('page', this.currentPage.toString());
|
|
params = params.set('limit', this.itemsPerPage.toString());
|
|
|
|
// Add date filters if provided
|
|
if (this.fromDate) {
|
|
params = params.set('fromDate', this.fromDate);
|
|
}
|
|
|
|
if (this.toDate) {
|
|
params = params.set('toDate', this.toDate);
|
|
}
|
|
|
|
// Add search filter if provided
|
|
if (this.searchText && this.searchText.trim() !== '') {
|
|
params = params.set('search', this.searchText.trim());
|
|
}
|
|
|
|
this.httpService
|
|
.requestGET<any>(URIKey.TRANSACTION_LOGS, params)
|
|
.subscribe({
|
|
next: (res) => {
|
|
const logs = Array.isArray(res) ? res : res?.data;
|
|
this.transactionLog = logs ?? [];
|
|
this.allItems = [...this.transactionLog];
|
|
|
|
// Get total count from response
|
|
if (res?.total !== undefined) {
|
|
this.totalCount = res.total;
|
|
} else if (res?.pagination?.total !== undefined) {
|
|
this.totalCount = res.pagination.total;
|
|
} else if (res?.meta?.total !== undefined) {
|
|
this.totalCount = res.meta.total;
|
|
} else {
|
|
this.totalCount = this.transactionLog.length;
|
|
}
|
|
|
|
this.isLoading = false;
|
|
},
|
|
error: (err) => {
|
|
console.error('Error fetching transaction logs:', err);
|
|
this.errorMessage = err.message || 'Failed to load transaction logs. Please try again.';
|
|
this.transactionLog = [];
|
|
this.allItems = [];
|
|
this.totalCount = 0;
|
|
this.isLoading = false;
|
|
},
|
|
complete: () => {
|
|
this.isLoading = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
private validateDateRange(): boolean {
|
|
if (this.fromDate && this.toDate) {
|
|
const from = new Date(this.fromDate);
|
|
const to = new Date(this.toDate);
|
|
|
|
if (from > to) {
|
|
this.errorMessage = 'From date cannot be after To date';
|
|
return false;
|
|
}
|
|
|
|
// Optional: Validate date range is not too wide
|
|
const diffTime = Math.abs(to.getTime() - from.getTime());
|
|
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
|
|
|
if (diffDays > 365) {
|
|
this.errorMessage = 'Date range cannot exceed 1 year';
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Date filter change handler
|
|
onDateFilterChange(): void {
|
|
this.currentPage = 1;
|
|
this.loadTransactionLogs();
|
|
}
|
|
|
|
// Clear date filters
|
|
clearDateFilters(): void {
|
|
this.fromDate = '';
|
|
this.toDate = '';
|
|
this.currentPage = 1;
|
|
this.loadTransactionLogs();
|
|
}
|
|
|
|
// Toggle date filter visibility
|
|
toggleDateFilters(): void {
|
|
this.showDateFilters = !this.showDateFilters;
|
|
}
|
|
|
|
// Apply default date range (Last 7 days)
|
|
applyLast7Days(): void {
|
|
const today = new Date();
|
|
const lastWeek = new Date();
|
|
lastWeek.setDate(today.getDate() - 7);
|
|
|
|
this.fromDate = formatDate(lastWeek, 'yyyy-MM-dd', 'en-US');
|
|
this.toDate = formatDate(today, 'yyyy-MM-dd', 'en-US');
|
|
this.onDateFilterChange();
|
|
}
|
|
|
|
// Apply default date range (Last 30 days)
|
|
applyLast30Days(): void {
|
|
const today = new Date();
|
|
const lastMonth = new Date();
|
|
lastMonth.setDate(today.getDate() - 30);
|
|
|
|
this.fromDate = formatDate(lastMonth, 'yyyy-MM-dd', 'en-US');
|
|
this.toDate = formatDate(today, 'yyyy-MM-dd', 'en-US');
|
|
this.onDateFilterChange();
|
|
}
|
|
|
|
// Apply default date range (This month)
|
|
applyThisMonth(): void {
|
|
const today = new Date();
|
|
const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
|
|
this.fromDate = formatDate(firstDay, 'yyyy-MM-dd', 'en-US');
|
|
this.toDate = formatDate(today, 'yyyy-MM-dd', 'en-US');
|
|
this.onDateFilterChange();
|
|
}
|
|
|
|
// Apply date range (Last 3 months)
|
|
applyLast3Months(): void {
|
|
const today = new Date();
|
|
const threeMonthsAgo = new Date();
|
|
threeMonthsAgo.setMonth(today.getMonth() - 3);
|
|
|
|
this.fromDate = formatDate(threeMonthsAgo, 'yyyy-MM-dd', 'en-US');
|
|
this.toDate = formatDate(today, 'yyyy-MM-dd', 'en-US');
|
|
this.onDateFilterChange();
|
|
}
|
|
|
|
toggleTableCard(): void {
|
|
this.transactionDataExpanded = !this.transactionDataExpanded;
|
|
}
|
|
|
|
itemsPerPageChanged(): void {
|
|
this.currentPage = 1;
|
|
this.loadTransactionLogs();
|
|
}
|
|
|
|
onSearch(value: string): void {
|
|
this.searchSubject.next(value);
|
|
}
|
|
|
|
totalPages(): number {
|
|
if (this.totalCount === 0) return 1;
|
|
return Math.ceil(this.totalCount / this.itemsPerPage);
|
|
}
|
|
|
|
previousPage(): void {
|
|
if (this.currentPage > 1) {
|
|
this.currentPage--;
|
|
this.loadTransactionLogs();
|
|
}
|
|
}
|
|
|
|
nextPage(): void {
|
|
if (this.currentPage < this.totalPages()) {
|
|
this.currentPage++;
|
|
this.loadTransactionLogs();
|
|
}
|
|
}
|
|
|
|
exportDataInExcel(): void {
|
|
// Build export parameters
|
|
let params = new HttpParams();
|
|
|
|
// Include date filters in export if they are set
|
|
if (this.fromDate) {
|
|
params = params.set('fromDate', this.fromDate);
|
|
}
|
|
|
|
if (this.toDate) {
|
|
params = params.set('toDate', this.toDate);
|
|
}
|
|
|
|
if (this.searchText && this.searchText.trim() !== '') {
|
|
params = params.set('search', this.searchText.trim());
|
|
}
|
|
|
|
// For large exports, you might want to fetch all data without pagination
|
|
params = params.set('limit', '10000'); // Adjust as needed
|
|
|
|
this.httpService
|
|
.requestGET<any>(URIKey.TRANSACTION_LOGS, params)
|
|
.subscribe({
|
|
next: (res) => {
|
|
const logs = Array.isArray(res) ? res : res?.data;
|
|
const dataToExport = logs ?? [];
|
|
|
|
if (dataToExport.length === 0) {
|
|
this.errorMessage = 'No data to export';
|
|
return;
|
|
}
|
|
|
|
// Generate filename with date range if applicable
|
|
let fileName = TRANSACTION_LOGS_FILE_NAME;
|
|
if (this.fromDate || this.toDate) {
|
|
const from = this.fromDate ? formatDate(new Date(this.fromDate), 'dd-MMM-yyyy', 'en-US') : 'All';
|
|
const to = this.toDate ? formatDate(new Date(this.toDate), 'dd-MMM-yyyy', 'en-US') : 'All';
|
|
fileName = `TransactionLogs_${from}_to_${to}`;
|
|
}
|
|
|
|
this.excelExportService.exportExcel(dataToExport, fileName);
|
|
},
|
|
error: (err) => {
|
|
console.error('Error exporting data:', err);
|
|
this.errorMessage = 'Failed to export data. Please try again.';
|
|
}
|
|
});
|
|
}
|
|
|
|
// Get filtered items for display (used in template)
|
|
get filteredItems(): TransactionLog[] {
|
|
return this.allItems;
|
|
}
|
|
|
|
// Format date for display
|
|
formatDateDisplay(dateString: string): string {
|
|
if (!dateString) return '';
|
|
return formatDate(new Date(dateString), 'MMM dd, yyyy', 'en-US');
|
|
}
|
|
|
|
// Check if date filter is active
|
|
get isDateFilterActive(): boolean {
|
|
return !!this.fromDate || !!this.toDate;
|
|
}
|
|
|
|
get pagedItems(): TransactionLog[] {
|
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
|
return this.allItems.slice(start, start + this.itemsPerPage);
|
|
}
|
|
|
|
} |