Refactor transaction logs UI and logic for clarity
Redesigned the transaction logs component to use a reactive form for date filtering, simplified the table and search logic, and improved pagination and export functionality. Updated SCSS for cleaner date input styling and adjusted i18n keys for new UI labels.mazdak/UX-transactionLogs
parent
9039567896
commit
cdec4e63ec
@ -1,139 +1,29 @@
|
|||||||
// Date filter section
|
.date-input-wrapper {
|
||||||
.date-filter-section {
|
position: relative;
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
.date-input-group {
|
input[type="date"] {
|
||||||
position: relative;
|
cursor: pointer;
|
||||||
|
padding-right: 35px;
|
||||||
.form-control {
|
|
||||||
padding-right: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-icon {
|
&::-webkit-calendar-picker-indicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.75rem;
|
left: 0;
|
||||||
top: 50%;
|
top: 0;
|
||||||
transform: translateY(-50%);
|
width: 100%;
|
||||||
color: #6c757d;
|
height: 100%;
|
||||||
}
|
margin: 0;
|
||||||
}
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
.quick-filter-btn {
|
opacity: 0;
|
||||||
&.active {
|
|
||||||
background-color: var(--bs-primary);
|
|
||||||
color: white;
|
|
||||||
border-color: var(--bs-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table styling
|
|
||||||
.table-responsive {
|
|
||||||
min-height: 400px;
|
|
||||||
|
|
||||||
table {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
|
|
||||||
th {
|
|
||||||
font-weight: 600;
|
|
||||||
white-space: nowrap;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 0.2rem 0.4rem;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
font-size: 0.7rem;
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Loading spinner
|
|
||||||
.spinner-border {
|
|
||||||
width: 3rem;
|
|
||||||
height: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search box
|
|
||||||
.search-box {
|
|
||||||
position: relative;
|
|
||||||
min-width: 200px;
|
|
||||||
|
|
||||||
.search-icon {
|
.calendar-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.75rem;
|
right: 10px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
color: #6c757d;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
color: #6c757d;
|
||||||
|
|
||||||
.form-control {
|
|
||||||
padding-right: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active filter badge
|
|
||||||
.active-filter-badge {
|
|
||||||
animation: fadeIn 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mobile responsive adjustments
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.date-filter-section {
|
|
||||||
.btn-group {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
padding: 0.375rem 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-responsive {
|
|
||||||
overflow-x: auto;
|
|
||||||
|
|
||||||
table {
|
|
||||||
min-width: 1200px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
min-width: 150px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dark mode support (if needed)
|
|
||||||
[data-bs-theme="dark"] {
|
|
||||||
.table-light {
|
|
||||||
background-color: #2d333b !important;
|
|
||||||
color: #adb5bd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box .search-icon {
|
|
||||||
color: #adb5bd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,340 +1,171 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule, DatePipe } from '@angular/common';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { ExcelExportService } from '../shared/services/excel-export.service';
|
import { ExcelExportService } from '../shared/services/excel-export.service';
|
||||||
import { TRANSACTION_LOGS_FILE_NAME } from '../utils/app.constants';
|
import { toDateAfterFromDateValidator, TRANSACTION_LOGS_FILE_NAME } from '../utils/app.constants';
|
||||||
import { pageSizeOptions } from '../utils/app.constants';
|
import { pageSizeOptions } from '../utils/app.constants';
|
||||||
import { NgSelectModule } from '@ng-select/ng-select';
|
import { NgSelectModule } from '@ng-select/ng-select';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { TableFilterPipe } from '../shared/pipes/table-filter.pipe';
|
import { TableFilterPipe } from '../shared/pipes/table-filter.pipe';
|
||||||
import { TransactionLog } from "../models/user";
|
import { TransactionLog } from "../models/user";
|
||||||
import { URIKey } from '../utils/uri-enums';
|
import { URIKey } from '../utils/uri-enums';
|
||||||
import { HttpParams } from '@angular/common/http';
|
import { HttpParams } from '@angular/common/http';
|
||||||
import { HttpURIService } from '../app.http.uri.service';
|
import { HttpURIService } from '../app.http.uri.service';
|
||||||
import { formatDate } from '@angular/common';
|
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { takeUntil, debounceTime } from 'rxjs/operators';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-transaction-logs',
|
selector: 'app-transaction-logs',
|
||||||
templateUrl: './transaction-logs.component.html',
|
templateUrl: './transaction-logs.component.html',
|
||||||
styleUrls: ['./transaction-logs.component.scss'],
|
styleUrls: ['./transaction-logs.component.scss'],
|
||||||
imports: [CommonModule, TranslateModule, NgSelectModule, FormsModule, ReactiveFormsModule, TableFilterPipe]
|
imports: [
|
||||||
})
|
TranslateModule,
|
||||||
export class TransactionLogsComponent implements OnInit, OnDestroy {
|
FormsModule,
|
||||||
currentPage: number = 1;
|
NgSelectModule,
|
||||||
totalCount: number = 0;
|
CommonModule,
|
||||||
renewalDataExpanded: boolean = true;
|
ReactiveFormsModule,
|
||||||
|
TableFilterPipe
|
||||||
|
],
|
||||||
|
providers: [DatePipe]})
|
||||||
|
export class TransactionLogsComponent implements OnInit {
|
||||||
|
logsSearchForm!: FormGroup;
|
||||||
|
|
||||||
pageSizeOptions = pageSizeOptions;
|
pageSizeOptions = pageSizeOptions;
|
||||||
itemsPerPage: number = 10;
|
itemsPerPage = 10;
|
||||||
transactionLog: TransactionLog[] = [];
|
currentPage = 1;
|
||||||
|
maxDate: string;
|
||||||
|
searchText = '';
|
||||||
|
|
||||||
|
logsDataExpanded = true;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
errorMessage: string = '';
|
|
||||||
searchText: string = '';
|
/** DATA LAYERS (do not mix these) */
|
||||||
allItems: TransactionLog[] = [];
|
allItems: TransactionLog[] = []; // raw API data
|
||||||
transactionDataExpanded: boolean = true;
|
filteredItems: TransactionLog[] = []; // after search
|
||||||
|
pagedItems: TransactionLog[] = []; // table view
|
||||||
// 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(
|
constructor(
|
||||||
private excelExportService: ExcelExportService,
|
private fb: FormBuilder,
|
||||||
private httpService: HttpURIService,
|
private httpService: HttpURIService,
|
||||||
) {}
|
private datePipe: DatePipe,
|
||||||
|
private excelExportService: ExcelExportService,
|
||||||
ngOnInit(): void {
|
) {
|
||||||
// Set max date to today
|
this.maxDate = new Date().toISOString().split('T')[0];
|
||||||
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 {
|
ngOnInit(): void {
|
||||||
this.destroy$.next();
|
this.logsSearchForm = this.fb.group(
|
||||||
this.destroy$.complete();
|
{
|
||||||
this.searchSubject.complete();
|
fromDate: ['', Validators.required],
|
||||||
|
toDate: ['', Validators.required],
|
||||||
|
},
|
||||||
|
{ validators: toDateAfterFromDateValidator },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupSearchDebounce(): void {
|
getlogsData(): void {
|
||||||
this.searchSubject.pipe(
|
if (this.logsSearchForm.invalid) return;
|
||||||
takeUntil(this.destroy$),
|
|
||||||
debounceTime(300)
|
|
||||||
).subscribe((searchValue: string) => {
|
|
||||||
this.searchText = searchValue;
|
|
||||||
this.currentPage = 1;
|
|
||||||
this.loadTransactionLogs();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadTransactionLogs(): void {
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.errorMessage = '';
|
|
||||||
|
const { fromDate, toDate } = this.logsSearchForm.value;
|
||||||
// Validate date range before making API call
|
|
||||||
if (!this.validateDateRange()) {
|
const params = new HttpParams()
|
||||||
this.isLoading = false;
|
.set('fromDate', this.datePipe.transform(fromDate, 'dd-MM-yyyy')!)
|
||||||
return;
|
.set('toDate', this.datePipe.transform(toDate, 'dd-MM-yyyy')!);
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
this.httpService
|
||||||
.requestGET<any>(URIKey.TRANSACTION_LOGS, params)
|
.requestGET<TransactionLog[]>(URIKey.TRANSACTION_LOGS, params)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (res) => {
|
next: (response) => {
|
||||||
const logs = Array.isArray(res) ? res : res?.data;
|
this.allItems = response ?? [];
|
||||||
this.transactionLog = logs ?? [];
|
this.filteredItems = [...this.allItems];
|
||||||
this.allItems = [...this.transactionLog];
|
this.currentPage = 1;
|
||||||
|
this.updatePagedItems();
|
||||||
// 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;
|
this.isLoading = false;
|
||||||
},
|
},
|
||||||
error: (err) => {
|
error: () => {
|
||||||
console.error('Error fetching transaction logs:', err);
|
|
||||||
this.errorMessage = err.message || 'Failed to load transaction logs. Please try again.';
|
|
||||||
this.transactionLog = [];
|
|
||||||
this.allItems = [];
|
this.allItems = [];
|
||||||
this.totalCount = 0;
|
this.filteredItems = [];
|
||||||
|
this.pagedItems = [];
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
},
|
},
|
||||||
complete: () => {
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private validateDateRange(): boolean {
|
/** SEARCH — filters DATA, not DOM */
|
||||||
if (this.fromDate && this.toDate) {
|
applySearch(): void {
|
||||||
const from = new Date(this.fromDate);
|
const value = this.searchText.toLowerCase().trim();
|
||||||
const to = new Date(this.toDate);
|
|
||||||
|
if (!value) {
|
||||||
if (from > to) {
|
this.filteredItems = [...this.allItems];
|
||||||
this.errorMessage = 'From date cannot be after To date';
|
} else {
|
||||||
return false;
|
this.filteredItems = this.allItems.filter((item) =>
|
||||||
}
|
[
|
||||||
|
'logId',
|
||||||
// Optional: Validate date range is not too wide
|
'porOrgacode',
|
||||||
const diffTime = Math.abs(to.getTime() - from.getTime());
|
'transactionID',
|
||||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
'drMbmbkmsnumber',
|
||||||
|
'crMbmbkmsnumber',
|
||||||
if (diffDays > 365) {
|
'crPcaglacode',
|
||||||
this.errorMessage = 'Date range cannot exceed 1 year';
|
'drPcaGlacode',
|
||||||
return false;
|
'amount',
|
||||||
}
|
'paymentMode',
|
||||||
|
'ppmPymdcode',
|
||||||
|
'sgtGntrdate',
|
||||||
|
'channelCode',
|
||||||
|
'createdAt',
|
||||||
|
'transactionUri',
|
||||||
|
'transactionCode',
|
||||||
|
].some((key) =>
|
||||||
|
String((item as any)[key] ?? '')
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(value),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date filter change handler
|
|
||||||
onDateFilterChange(): void {
|
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
this.loadTransactionLogs();
|
this.updatePagedItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear date filters
|
updatePagedItems(): void {
|
||||||
clearDateFilters(): void {
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
this.fromDate = '';
|
const end = start + this.itemsPerPage;
|
||||||
this.toDate = '';
|
this.pagedItems = this.filteredItems.slice(start, end);
|
||||||
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 {
|
totalPages(): number {
|
||||||
if (this.totalCount === 0) return 1;
|
return Math.ceil(this.filteredItems.length / this.itemsPerPage);
|
||||||
return Math.ceil(this.totalCount / this.itemsPerPage);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
previousPage(): void {
|
previousPage(): void {
|
||||||
if (this.currentPage > 1) {
|
if (this.currentPage > 1) {
|
||||||
this.currentPage--;
|
this.currentPage--;
|
||||||
this.loadTransactionLogs();
|
this.updatePagedItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextPage(): void {
|
nextPage(): void {
|
||||||
if (this.currentPage < this.totalPages()) {
|
if (this.currentPage < this.totalPages()) {
|
||||||
this.currentPage++;
|
this.currentPage++;
|
||||||
this.loadTransactionLogs();
|
this.updatePagedItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
itemsPerPageChanged(): void {
|
||||||
get filteredItems(): TransactionLog[] {
|
this.currentPage = 1;
|
||||||
return this.allItems;
|
this.updatePagedItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format date for display
|
toggleTableCard(): void {
|
||||||
formatDateDisplay(dateString: string): string {
|
this.logsDataExpanded = !this.logsDataExpanded;
|
||||||
if (!dateString) return '';
|
|
||||||
return formatDate(new Date(dateString), 'MMM dd, yyyy', 'en-US');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if date filter is active
|
exportDataInExcel(): void {
|
||||||
get isDateFilterActive(): boolean {
|
this.excelExportService.exportExcel(
|
||||||
return !!this.fromDate || !!this.toDate;
|
this.allItems,
|
||||||
|
TRANSACTION_LOGS_FILE_NAME,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get pagedItems(): TransactionLog[] {
|
|
||||||
const start = (this.currentPage - 1) * this.itemsPerPage;
|
|
||||||
return this.allItems.slice(start, start + this.itemsPerPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue