home page table filtering

This commit is contained in:
Cyril Joseph 2026-01-12 21:55:42 -04:00
parent 2402382297
commit 0da6daaa85
3 changed files with 143 additions and 4 deletions

View File

@ -19,6 +19,34 @@
</div>
<div class="table-actions">
<div class="filter-controls" *ngIf="dataSource.data.length > 0">
<!-- Column Selection Dropdown -->
<mat-form-field appearance="outline" class="filter-field">
<mat-label>Filter By</mat-label>
<mat-select [(value)]="selectedColumn" (selectionChange)="onColumnChange()">
<mat-option value=""></mat-option>
<mat-option *ngFor="let column of filterableColumns" [value]="column.value">
{{column.displayName}}
</mat-option>
</mat-select>
</mat-form-field>
<!-- Search Input -->
<mat-form-field appearance="outline" class="filter-field">
<mat-label>Search Value</mat-label>
<input matInput [(ngModel)]="filterValue" (keyup)="applyFilter()"
placeholder="Enter search term...">
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<!-- Clear Filter Button -->
<button mat-raised-button type="button" (click)="clearFilter()"
[disabled]="!selectedColumn && !filterValue">
<mat-icon>clear_all</mat-icon>
Clear Filter
</button>
</div>
<button mat-raised-button color="accent" (click)="exportData()" *ngIf="dataSource.data.length > 0"
matTooltip="Export to Excel" [disabled]="dataSource.data.length === 0">
<mat-icon>download</mat-icon> Export

View File

@ -12,10 +12,13 @@
.table-actions {
display: flex;
justify-content: end;
button {
justify-content: space-between;
margin-bottom: 16px;
.filter-controls {
display: flex;
gap: 16px;
align-items: center;
}
}

View File

@ -15,10 +15,11 @@ import { ApiErrorHandlerService } from '../core/services/common/api-error-handle
import { CommonService } from '../core/services/common/common.service';
import { NotificationService } from '../core/services/common/notification.service';
import * as XLSX from 'xlsx';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-home',
imports: [AngularMaterialModule, ChartComponent, RouterLink, CommonModule],
imports: [AngularMaterialModule, ChartComponent, RouterLink, CommonModule, FormsModule],
templateUrl: './home.component.html',
styleUrl: './home.component.scss',
providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }],
@ -30,6 +31,23 @@ export class HomeComponent {
userPreferences: UserPreferences;
carnetStatuses: CarnetStatus[] = [];
// table filter variables
selectedColumn: string = '';
filterValue: string = '';
filterableColumns: any[] = [
{ value: 'applicationName', displayName: 'Application Name' },
{ value: 'holderName', displayName: 'Holder Name' },
{ value: 'carnetNumber', displayName: 'Carnet Number' },
{ value: 'usSets', displayName: 'US Sets' },
{ value: 'foreignSets', displayName: 'Foreign Sets' },
{ value: 'transitSets', displayName: 'Transit Sets' },
{ value: 'carnetValue', displayName: 'Carnet Value' },
{ value: 'issueDate', displayName: 'Issue Date' },
{ value: 'expiryDate', displayName: 'Expiry Date' },
{ value: 'orderType', displayName: 'Order Type' },
{ value: 'carnetStatus', displayName: 'Carnet Status' }
];
dataSource = new MatTableDataSource<any>();
@ViewChild(MatPaginator, { static: false })
@ -86,6 +104,10 @@ export class HomeComponent {
onCarnetStatusClick(event: any): void {
this.isLoading = true;
this.showTable = false;
// Clear any existing filters when loading new data
this.clearFilter();
this.homeService.getCarnetDataByStatus(event.spid, event.carnetStatus).subscribe({
next: (carnetDetails) => {
this.isLoading = false;
@ -93,6 +115,9 @@ export class HomeComponent {
this.dataSource.data = carnetDetails;
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
// Reset filter after new data is loaded
this.dataSource.filter = '';
},
error: (error) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load carnet data for the selected status');
@ -144,4 +169,87 @@ export class HomeComponent {
const carnetStatus = this.carnetStatuses.find(t => t.value === value);
return carnetStatus ? carnetStatus.name : value;
}
applyFilter(): void {
if (!this.dataSource) return;
if (this.selectedColumn && this.filterValue) {
this.dataSource.filterPredicate = (data: any, filter: string) => {
const columnValue = data[this.selectedColumn];
const searchTerm = filter.toLowerCase().trim();
// Handle different column types
switch (this.selectedColumn) {
case 'issueDate':
case 'expiryDate':
// Filter by date
if (columnValue) {
const formattedDate = this.formatDateForDisplay(columnValue);
return formattedDate.toLowerCase().includes(searchTerm);
}
return false;
case 'carnetStatus':
// Filter by status label instead of value
const statusLabel = this.getCarnetStatusLabel(columnValue);
return statusLabel.toLowerCase().includes(searchTerm);
default:
// Default string/number filter
if (typeof columnValue === 'string') {
return columnValue.toLowerCase().includes(searchTerm);
} else if (typeof columnValue === 'number') {
return columnValue.toString().includes(searchTerm);
}
return false;
}
};
this.dataSource.filter = this.filterValue.trim();
} else if (!this.filterValue) {
this.clearFilterData();
}
}
onColumnChange(): void {
this.clearFilterData();
}
clearFilter(): void {
this.selectedColumn = '';
this.clearFilterData();
}
clearFilterData(): void {
this.filterValue = '';
if (this.dataSource) {
this.dataSource.filter = '';
}
}
private formatDateForDisplay(dateValue: any): string {
if (!dateValue) return '';
try {
const date = new Date(dateValue);
// Return in multiple formats for better filtering
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const fullMonthNames = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'];
const month = monthNames[date.getUTCMonth()];
const fullMonth = fullMonthNames[date.getUTCMonth()];
const day = date.getUTCDate();
const year = date.getUTCFullYear();
const monthNumber = date.getUTCMonth() + 1;
// Return multiple formats separated by delimiter for filtering
return `${month} ${day}, ${year}|${fullMonth} ${day}, ${year}|${monthNumber}/${day}/${year}|${year}-${monthNumber.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
} catch (error) {
return '';
}
}
}