added export data in excel and added som validations in logger manager screen #32

Merged
naeem.ullah merged 1 commits from aconnect-UX/1942 into dev-pending-01-01-2026 3 weeks ago

@ -27,13 +27,16 @@
"@ngx-translate/core": "^17.0.0",
"@ngx-translate/http-loader": "^16.0.1",
"@types/crypto-js": "^4.2.2",
"@types/file-saver": "^2.0.7",
"bootstrap": "^5.3.8",
"crypto-js": "^4.2.0",
"express": "^4.18.2",
"file-saver": "^2.0.5",
"ngx-spinner": "^19.0.0",
"ngx-toastr": "^19.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"xlsx": "^0.18.5",
"zone.js": "~0.15.0"
},
"devDependencies": {

@ -60,7 +60,7 @@
maxlength="500" appNoWhitespaces rows="3" />
<div class="text-danger" *ngIf="
logsSearchForm.get('toDate')?.touched &&
(logsSearchForm.get('toDate')?.invalid || logsSearchForm.errors?.['toDateInvalid'])
(logsSearchForm.get('toDate')?.invalid || logsSearchForm.errors?.['toDateInvalid'] || logsSearchForm.errors?.['toDateGreaterThanToday'])
">
<div
*ngIf="logsSearchForm.get('toDate')?.hasError('required')">
@ -71,6 +71,10 @@
*ngIf="logsSearchForm.errors?.['toDateInvalid']">
{{ 'toDateInvalidError' | translate }}
</div>
<div
*ngIf="logsSearchForm.errors?.['toDateGreaterThanToday']">
{{ 'toDateGreaterThanToday' | translate }}
</div>
</div>
@ -122,6 +126,9 @@
placeholder="{{ 'search' | translate }}">
<i class="fas fa-search search-icon"></i>
</div>
<i (click)="exportDataInExcel()" id="downloadReport" class="fa fa-download"></i>
<i class="materialdesignicons" (click)="toggleTableCard()">
<ng-container *ngIf="logsDataExpanded; else collapsedIcon">
<i class="dripicons-chevron-up float-end"></i>

@ -2,13 +2,14 @@ import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { TranslateModule } from '@ngx-translate/core';
import { pageSizeOptions, toDateAfterFromDateValidator } from '../utils/app.constants';
import { LOGGING_DETAILS_FILE_NAME, pageSizeOptions, toDateAfterFromDateValidator } from '../utils/app.constants';
import { CommonModule, DatePipe } from '@angular/common';
import { HttpParams } from '@angular/common/http';
import { URIKey } from '../utils/uri-enums';
import { HttpURIService } from '../app.http.uri.service';
import { LogsManagementResponse } from '../utils/app.interfaces';
import { TableFilterPipe } from '../shared/pipes/table-filter.pipe';
import { ExcelExportService } from '../shared/services/excel-export.service';
@Component({
selector: 'app-logging',
@ -34,7 +35,8 @@ export class LoggingComponent implements OnInit {
constructor(
private fb: FormBuilder,
private httpService: HttpURIService,
private datePipe: DatePipe
private datePipe: DatePipe,
private excelExportServic: ExcelExportService
) { }
ngOnInit() {
@ -73,7 +75,7 @@ export class LoggingComponent implements OnInit {
this.isLoading = false;
},
error: (err) => {
console.error('Error fetching BOD data:', err);
console.error('Error fetching logging details data:', err);
this.logsList = [];
this.isLoading = false;
}
@ -113,4 +115,8 @@ export class LoggingComponent implements OnInit {
this.logsDataExpanded = !this.logsDataExpanded;
}
exportDataInExcel(){
this.excelExportServic.exportExcel(this.logsList, LOGGING_DETAILS_FILE_NAME)
}
}

@ -1,92 +0,0 @@
import { Injectable } from '@angular/core';
import { tap } from 'rxjs/operators';
import { HttpService } from '../shared/services/http.service';
import { MiscService } from '../shared/services/misc.service';
import { Router } from '@angular/router';
import { User } from '../models/user';
import { HttpErrorResponse } from '@angular/common/http';
import { CONSTANTS } from '../utils/app.constants';
import { StorageService } from '../shared/services/storage.service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor(private httpService: HttpService, private miscService: MiscService, private router: Router, private storageService: StorageService) { }
firstLogin: boolean = false;
private token: string = "";
async login(User_Data: User) {
let login = false;
let userId = User_Data.Username;
let password = User_Data.Password;
let data = { "userId": userId, "password": password};
let url = '/authentication/login';
let response: any = await this.httpService.postRequest(url, data)!.toPromise();
if (!(response instanceof HttpErrorResponse)) {
if ((await response["errorMessage"] == undefined)) {
if (response) {
login = true;
localStorage.setItem('userId', userId);
let res = JSON.parse(JSON.stringify(response));
// let permission = JSON.parse(res['userPermission']);
// localStorage.setItem('SIDENAV', res['userPermission']);
localStorage.setItem('userFullname', res.user.userFullname);
localStorage.setItem('userId', res.user.userId);
localStorage.setItem('token', res.token);
this.firstLogin = response.requiresPasswordChange;
this.storageService.setItem('firstLogin', this.firstLogin ? 'true' : 'false');
return res;
}
}
let res = response;
return res;
}
}
IsLoggedIn() {
if (this.storageService.getItem('userId') !== null)
return true;
else
return false;
}
logout() {
window.history.state;
localStorage.clear();
this.router.navigate(['login'])
}
getToken(): string {
this.token = localStorage.getItem('token') || "";
return this.token;
}
setToken(token: string) {
this.token = token;
localStorage.setItem('token', token);
}
refreshToken() {
let uCreds = { token: this.getToken() };
let porOrgacode = CONSTANTS.POR_ORGACODE;
let refreshTokenData: any = {
cmpUserId: localStorage.getItem('userId'),
token: uCreds.token,
porOrgacode: porOrgacode
}
return this.httpService.postRequest("/refreshToken", refreshTokenData)!.pipe(
tap((response: any) => {
localStorage.removeItem('token')
localStorage.setItem('token', JSON.stringify(response.token));
this.setToken(response.token);
})
);
}
}

@ -0,0 +1,28 @@
import { Injectable } from '@angular/core';
import { saveAs } from 'file-saver';
import * as XLSX from 'xlsx';
import { EXCEL_FILE_EXTENSION, EXCEL_FILE_TYPE } from '../../utils/app.constants';
@Injectable({
providedIn: 'root'
})
export class ExcelExportService {
constructor() { }
private fileType = EXCEL_FILE_TYPE;
private fileExtension = EXCEL_FILE_EXTENSION;
public exportExcel(jsonData: any[], fileName: string): void {
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(jsonData);
const wb: XLSX.WorkBook = { Sheets: { 'data': ws }, SheetNames: ['data'] };
const excelBuffer: any = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
this.saveExcelFile(excelBuffer, fileName);
}
private saveExcelFile(buffer: any, fileName: string): void {
const data: Blob = new Blob([buffer], {type: this.fileType});
saveAs.saveAs(data, fileName + this.fileExtension);
}
}

@ -16,11 +16,23 @@ export const toDateAfterFromDateValidator: ValidatorFn = (
const fromDate = group.get('fromDate')?.value;
const toDate = group.get('toDate')?.value;
const currentDate = new Date().toISOString();
if (!fromDate || !toDate) {
return null;
}
return toDate >= fromDate
? null
: { toDateInvalid: true };
if(toDate < fromDate)
return { toDateInvalid: true }
else if(toDate >= currentDate)
return { toDateGreaterThanToday: true }
else
return null
};
export const EXCEL_FILE_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
export const EXCEL_FILE_EXTENSION = '.xlsx';
export const LOGGING_DETAILS_FILE_NAME = 'logging-manager-details'

@ -251,5 +251,7 @@
"noLoggingDetailsFound": "لم يتم العثور على تفاصيل التسجيل",
"ERR_SEC_0001": "البريد الإلكتروني موجود بالفعل",
"ERR_SEC_0002": "اسم المستخدم موجود بالفعل",
"ERR_SEC_0003": "كلمة المرور القديمة غير صحيحة"
"ERR_SEC_0003": "كلمة المرور القديمة غير صحيحة",
"toDateGreaterThanToday": "يجب أن يكون التاريخ الحالي أقل من التاريخ الحالي",
"fromDateGreaterThanToday": "يجب أن يكون تاريخ البدء أقل من التاريخ الحالي"
}

@ -251,5 +251,7 @@
"noLoggingDetailsFound": "No Logging Details found",
"ERR_SEC_0001": "Email already exists",
"ERR_SEC_0002": "Username already exists",
"ERR_SEC_0003": "Old Password is not correct"
"ERR_SEC_0003": "Old Password is not correct",
"toDateGreaterThanToday": "To Date must be less than Current Date",
"fromDateGreaterThanToday": "From Date must be less than Current Date"
}

@ -169,3 +169,34 @@ ng-select.form-select-sm {
width: 98% !important;
}
#downloadReport {
width: 30px;
height: 30px;
border: 2px solid #64B5F6;
border-radius: 50%;
background: transparent;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0;
transition: all 0.25s ease;
}
#downloadReport i {
color: #64B5F6;
font-size: 16px;
}
#downloadReport:hover {
background-color: #64B5F6;
}
#downloadReport:hover i {
color: #ffffff;
}
#downloadReport:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.35);
}
Loading…
Cancel
Save