1- import { Component , OnInit } from '@angular/core' ;
2- import { LoginReportService } from './login-report.service' ;
3- import { SelectItem } from 'primeng/api' ;
4- import { saveAs } from 'file-saver' ;
5- import { parse } from 'json2csv' ;
1+ import { Component , OnInit } from '@angular/core' ;
2+ import { LoginReportService } from './login-report.service' ;
3+ import { SelectItem } from 'primeng/api' ;
4+ import { saveAs } from 'file-saver' ;
65import { enUS } from 'date-fns/locale' ;
76import 'chartjs-adapter-date-fns' ;
87interface TimeSelection {
98 days : number ;
109}
1110
1211@Component ( {
13- selector : 'app-login-reports' ,
14- templateUrl : './login-reports.component.html' ,
15- styleUrls : [ './login-reports.component.scss' ] ,
16- standalone : false
12+ selector : 'app-login-reports' ,
13+ templateUrl : './login-reports.component.html' ,
14+ styleUrls : [ './login-reports.component.scss' ] ,
15+ standalone : false
1716} )
1817
1918export class LoginReportsComponent implements OnInit {
@@ -34,15 +33,15 @@ export class LoginReportsComponent implements OnInit {
3433 this . today . setHours ( 0 , 0 , 0 , 0 ) ; // dates from db don't include timestamp, so remove that from our 'today' var
3534
3635 this . timeSelection = [
37- { label : 'Show 7 days' , value : { days : 7 } } ,
38- { label : 'Show 14 days' , value : { days : 14 } } ,
39- { label : 'Show 30 days' , value : { days : 30 } } ,
40- { label : 'Show 60 days' , value : { days : 60 } } ,
41- { label : 'Show 90 days' , value : { days : 90 } } ,
42- { label : 'Show 180 days' , value : { days : 180 } } ,
43- { label : 'Show 365 days' , value : { days : 365 } }
36+ { label : 'Show 7 days' , value : { days : 7 } } ,
37+ { label : 'Show 14 days' , value : { days : 14 } } ,
38+ { label : 'Show 30 days' , value : { days : 30 } } ,
39+ { label : 'Show 60 days' , value : { days : 60 } } ,
40+ { label : 'Show 90 days' , value : { days : 90 } } ,
41+ { label : 'Show 180 days' , value : { days : 180 } } ,
42+ { label : 'Show 365 days' , value : { days : 365 } }
4443 ] ;
45- this . selection = { days : 30 } ;
44+ this . selection = { days : 30 } ;
4645
4746 this . chartOptions = {
4847 plugins : {
@@ -59,9 +58,9 @@ export class LoginReportsComponent implements OnInit {
5958 }
6059 } ,
6160 x : {
62- adapters : {
61+ adapters : {
6362 date : {
64- locale : enUS ,
63+ locale : enUS ,
6564 } ,
6665 } ,
6766 display : true ,
@@ -80,11 +79,11 @@ export class LoginReportsComponent implements OnInit {
8079
8180
8281 this . userChartCols = [
83- { field : 'email' , header : 'Email Address' } ,
84- { field : 'lastLogin' , header : 'Last Login' } ,
85- { field : 'sevenDays' , header : 'Logins Last 7 Days' } ,
86- { field : 'thirtyDays' , header : 'Logins Last 30 Days' } ,
87- { field : 'totalLogins' , header : 'Total Logins All Time' }
82+ { field : 'email' , header : 'Email Address' } ,
83+ { field : 'lastLogin' , header : 'Last Login' } ,
84+ { field : 'sevenDays' , header : 'Logins Last 7 Days' } ,
85+ { field : 'thirtyDays' , header : 'Logins Last 30 Days' } ,
86+ { field : 'totalLogins' , header : 'Total Logins All Time' }
8887 ] ;
8988
9089 loginReportService . getLoginReport ( )
@@ -117,9 +116,9 @@ export class LoginReportsComponent implements OnInit {
117116 labels : [ ] ,
118117 datasets : [
119118 {
120- label : 'User Logins' ,
121- data : [ ] ,
122- fill : false ,
119+ label : 'User Logins' ,
120+ data : [ ] ,
121+ fill : false ,
123122 backgroundColor : '#2C81C0'
124123 } ] ,
125124 } ;
@@ -129,31 +128,31 @@ export class LoginReportsComponent implements OnInit {
129128 let current_date = new Date ( ) ;
130129 current_date . setHours ( 0 , 0 , 0 , 0 ) ;
131130 let empty_dates = [ ] ;
132-
133- for ( let i = 0 ; i <= this . selection . days ; i ++ ) {
131+
132+ for ( let i = 0 ; i <= this . selection . days ; i ++ ) {
134133 empty_dates . push ( new Date ( current_date ) ) ;
135134 current_date . setDate ( current_date . getDate ( ) - 1 ) ;
136135 }
137-
136+
138137 return empty_dates . reverse ( ) ;
139138 } ) ( ) ;
140139
141140 let chartLoginData = Array ( this . selection . days ) . fill ( 0 ) ;
142141
143142 this . loginData . labels = chartLabelData ;
144-
143+
145144 this . readerSupplement = '<table style="border: 1px black solid"><thead><tr><th>Date</th><th>Login Count</th></tr></thead>' ;
146145
147146 Object . keys ( data ) . forEach ( date => {
148147 const dateLogin = new Date ( date ) ;
149-
148+
150149 let index ;
151- if ( ( index = chartLabelData . findIndex (
150+ if ( ( index = chartLabelData . findIndex (
152151 function ( x ) {
153- // Need to look at Value of Date because the Date object is different
154- return x . valueOf ( ) === dateLogin . valueOf ( ) ;
155- }
156- ) ) != - 1 ) {
152+ // Need to look at Value of Date because the Date object is different
153+ return x . valueOf ( ) === dateLogin . valueOf ( ) ;
154+ }
155+ ) ) != - 1 ) {
157156 let loginsForDay = 0 ;
158157 Object . keys ( data [ date ] ) . forEach ( email => {
159158 loginsForDay += data [ date ] [ email ] ;
@@ -185,8 +184,8 @@ export class LoginReportsComponent implements OnInit {
185184 Object . keys ( data ) . forEach ( date => {
186185
187186 Object . keys ( data [ date ] ) . forEach ( email => {
188- if ( ! userAccumulator [ email ] ) {
189- userAccumulator [ email ] = { email : email , totalLogins : 0 , sevenDays : 0 , thirtyDays : 0 , lastLogin : date } ;
187+ if ( ! userAccumulator [ email ] ) {
188+ userAccumulator [ email ] = { email : email , totalLogins : 0 , sevenDays : 0 , thirtyDays : 0 , lastLogin : date } ;
190189 }
191190 userAccumulator [ email ] . totalLogins += data [ date ] [ email ] ;
192191 totals . totalLogins += data [ date ] [ email ] ;
@@ -212,7 +211,7 @@ export class LoginReportsComponent implements OnInit {
212211 } ) ;
213212 } ) ;
214213
215- Object . keys ( userAccumulator ) . forEach ( email => {
214+ Object . keys ( userAccumulator ) . forEach ( email => {
216215 this . userData . push ( userAccumulator [ email ] ) ;
217216 } ) ;
218217 this . userData . push ( totals ) ;
@@ -226,17 +225,20 @@ export class LoginReportsComponent implements OnInit {
226225 downloadLoginData ( data : any ) {
227226
228227 const flatData = [ ] ;
229- Object . keys ( data ) . forEach ( day => {
230- Object . keys ( data [ day ] ) . forEach ( email => {
228+ Object . keys ( data ) . forEach ( day => {
229+ Object . keys ( data [ day ] ) . forEach ( email => {
231230 flatData . push (
232- { date : day , email : email , 'number of logins' : data [ day ] [ email ] }
231+ { date : day , email : email , 'number of logins' : data [ day ] [ email ] }
233232 ) ;
234233 } ) ;
235234
236235 } ) ;
237236
238- const csv = parse ( flatData , [ 'email' , 'date' , 'number of logins' ] ) ;
239- saveAs ( new Blob ( [ csv ] , { type : 'text/csv; charset=utf-8' } ) , 'srt-login-report.csv' ) ;
237+ const fields = [ 'email' , 'date' , 'number of logins' ] ;
238+ const header = fields . join ( ',' ) ;
239+ const rows = flatData . map ( row => fields . map ( f => '"' + String ( row [ f ] ?? '' ) . replace ( / " / g, '""' ) + '"' ) . join ( ',' ) ) ;
240+ const csv = [ header , ...rows ] . join ( '\n' ) ;
241+ saveAs ( new Blob ( [ csv ] , { type : 'text/csv; charset=utf-8' } ) , 'srt-login-report.csv' ) ;
240242 }
241243
242244 ngOnInit ( ) {
0 commit comments