I have an Angular component consisting of the following files:
HTML File:
<ngx-loading [show]="loading" [config]="{ backdropBorderRadius: '3px', fullScreenBackdrop: true }"></ngx-loading>
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="card mb-4 shadow-sm border rounded ">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="caption">
<h3 class="card-title fw-bolder text-gray-900 m-0">List Elog Management</h3>
</div>
<div class="actions">
<a [routerLink]="['/SuperAdminElogManagement/add']" class="btn btn-danger-gradient">
<i class="bi bi-plus"></i> Add
</a>
</div>
</div>
<div class="card-body p-2 m-2 rounded">
<div class="table-responsive table-pane" *ngIf="filteredData.length > 0">
<table #elogManagementTableOne class="table table-bordered table-hover table-sm align-middle w-100 app-table"></table>
</div>
<p class="text-center" *ngIf="filteredData.length === 0 && !loading">No data available for the selected range.</p>
</div>
</div>
</div>
</div>
</div>
TypeScript File:
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { first, Subscription } from 'rxjs';
import { DeviceMagicJsonTemplate } from 'src/app/models/super-admin-elog-management.model';
import { SuperAdminElogManagementService } from 'src/app/services/superadminElogManagement.service';
import { AppInsightsService } from 'src/app/services/AppInsights.service';
declare const DataTable: any;
@Component({
selector: 'app-superadminelogmanagement',
templateUrl: './superadminelogmanagement.component.html',
styleUrls: ['./superadminelogmanagement.component.scss', './../../../../app.component.scss']
})
export class SuperadminelogmanagementComponent implements OnInit, AfterViewInit, OnDestroy {
private tableRef?: ElementRef<HTMLTableElement>;
@ViewChild('elogManagementTableOne') set leadBoardTable(el: ElementRef<HTMLTableElement> | undefined) {
this.tableRef = el;
}
loading: any = null;
elogsData: any[] = [];
filteredData: any[] = [];
sortColumn: string = '';
sortDirection: 'asc' | 'desc' = 'asc';
searchTerms: { [key: string]: string } = {
Title: '',
ClientName: '',
RS_Name: '',
DEP_Name: '',
ElogTemplateTypeId: ''
};
private subscriptions: Subscription = new Subscription();
private dt: any;
private dtInitializing = false;
constructor(
private superAdminElogManagementService: SuperAdminElogManagementService,
private cd: ChangeDetectorRef,
private appInsights: AppInsightsService
) { }
ngAfterViewInit(): void {
this.initDataTableIfNeeded();
}
ngOnInit() {
this.loading = true;
this.appInsights.trackTrace({
message: 'Track Feature',
properties: { message: 'Elog Management - View Page is Opened', Feature: 'Elog Management', FeatureAction: 'View' }
});
this.GetElogsList();
}
GetElogsList() {
const sub = this.superAdminElogManagementService.getElogsList()
.pipe(first())
.subscribe({
next: (result: Array<DeviceMagicJsonTemplate>) => {
this.elogsData = result;
this.filteredData = this.elogsData;
this.loading = false;
this.cd.markForCheck();
setTimeout(() => this.initDataTableIfNeeded());
},
error: (error) => {
console.error('Error fetching Elogs list:', error);
this.loading = false;
this.cd.markForCheck();
}
});
this.subscriptions.add(sub);
}
private initDataTableIfNeeded(): void {
if (this.dt || this.dtInitializing) return; // already initialized or in progress
if (!this.tableRef) return; // table not in DOM yet
if (!this.filteredData || this.filteredData.length === 0) return; // no data yet
// Initialize DataTable with object rows and TS-defined headers
this.dtInitializing = true;
this.dt = new DataTable(this.tableRef.nativeElement, {
retrieve: true,
autoWidth: true,
data: this.filteredData,
rowId: 'title',
columns: [
{ title: '<strong>Title</strong>', className: 'dt-left', data: 'Title', defaultContent: '', width: '20%', searchable: true, },
{ title: '<strong>Client Name</strong>', className: 'dt-left', data: 'ClientName', defaultContent: '', width: '20%', searchable: false, },
{ title: '<strong>RS Name</strong>', className: 'dt-left', data: 'RS_Name', defaultContent: '', width: '20%', searchable: false, },
{ title: '<strong>DEP Name</strong>', className: 'dt-left', data: 'DEP_Name', defaultContent: '', width: '20%', searchable: false, },
{
title: '<strong>Elog Template Type</strong>', className: 'dt-left', data: 'ElogTemplateTypeId', defaultContent: '', width: '10%',
render: (_d: any, _type: any, row: any) => {
const name = row?.ElogTemplateTypeId == 0 ? 'SuperAdmin' : 'User';
return `<span>${name}</span>`;
}
},
{
title: '<strong>Actions</strong>', className: 'dt-left', orderable: false, searchable: false, data: null, width: '10%',
render: (_d: any, _type: any, row: any) => {
return `<a href="/SuperAdminElogManagement/edit/${row.DMPJT_ID}" class="btn btn-icon btn-active-light-primary w-30px h-30px me-3" title="Edit">
<i class="ki-duotone ki-pencil fs-3"><span class="path1"></span><span class="path2"></span></i>
</a>`;
}
}
],
columnControl: [
{ target: 0, content: ['order'] },
{ target: 1, content: ['search'] },
],
paging: true,
ordering: { indicators: true, handler: true },
scrollX: true,
layout: {
topEnd: {
buttons: [
'csv',
'excel',
{ extend: 'pdfHtml5', title: 'Transaction History', orientation: 'landscape', pageSize: 'letter' },
]
},
},
fixedColumns: { start: 1, end: 1 },
scrollCollapse: true,
});
this.cd.markForCheck();
// Adjust after init to handle hidden/resized containers
this.adjustAfterVisible();
this.dtInitializing = false;
}
// Defer column/layout recalculation until container is visible
private adjustAfterVisible(): void {
if (!this.dt) return;
setTimeout(() => {
try {
if (this.dt.columns && typeof this.dt.columns.adjust === 'function') {
this.dt.columns.adjust().draw(false);
} else if (this.dt.draw) {
this.dt.draw(false);
}
const fc = (this.dt.fixedColumns && typeof this.dt.fixedColumns === 'function') ? this.dt.fixedColumns() : null;
if (fc && typeof fc.relayout === 'function') {
fc.relayout();
}
} catch {
// ignore
}
}, 0);
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
this.loading = null;
this.elogsData = [];
this.filteredData = [];
this.sortColumn = '';
this.sortDirection = 'asc';
this.searchTerms = { Title: '', ClientName: '', RS_Name: '', DEP_Name: '', ElogTemplateTypeId: '' };
this.cd.detach();
}
}
I want to improve the UI of this component by making it look modern, clean, and attractive. Please ensure:
The layout is responsive and adapts well to different screen sizes (mobile, tablet, desktop).
The UI components are visually appealing with modern design patterns (e.g., clean typography, consistent spacing, minimalist design).
The colors are aesthetically pleasing, with clear contrast for readability and accessibility (you can suggest a color scheme).
Utilize smooth animations or transitions where appropriate to enhance user interaction.
The SCSS should be organized and use reusable classes/mixins to maintain clean code.
The HTML should follow best practices for accessibility and semantic structure.
Please optimize the component for performance and make sure the UI adheres to the latest design trends while maintaining simplicity.