@@ -36,6 +36,15 @@ <h3 data-i18n="admin.view_manage" class="card-title section-title">View and mana
3636 < i class ="ki-solid ki-magnifier fs-1 position-absolute ms-6 "> </ i >
3737 < input name ="search " data-i18n ="[placeholder]general.search " type ="text " data-table-filter ="search "
3838 class ="form-control rounded-1 w-250px ps-15 me-5 " placeholder ="Search " />
39+ < button id ="export_button " type ="button " class ="btn btn-light-primary ms-3 " data-table-filter ="export ">
40+ < span data-i18n ="general.export " class ="indicator-label ">
41+ Export
42+ </ span >
43+ < span data-i18n ="general.wait " class ="indicator-progress ">
44+ Please wait...
45+ < span class ="spinner-border spinner-border-sm align-middle ms-2 "> </ span >
46+ </ span >
47+ </ button >
3948 </ div >
4049
4150 < div class ="d-flex justify-content-end my-2 " data-table-toolbar ="base ">
@@ -112,6 +121,8 @@ <h3 data-i18n="admin.view_manage" class="card-title section-title">View and mana
112121{{- end}}
113122{{- define "extra_js"}}
114123< script {{- if .CSPNonce}} nonce ="{{.CSPNonce}} "{{- end}} src ="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js "> </ script >
124+ < script {{- if .CSPNonce}} nonce ="{{.CSPNonce}} "{{- end}} src ="{{.StaticURL}}/vendor/papaparse/papaparse.min.js "> </ script >
125+ < script {{- if .CSPNonce}} nonce ="{{.CSPNonce}} "{{- end}} src ="{{.StaticURL}}/vendor/file-saver/FileSaver.min.js "> </ script >
115126< script type ="text/javascript " {{- if .CSPNonce}} nonce ="{{.CSPNonce}} "{{- end}} >
116127 function deleteAction ( username ) {
117128 ModalAlert . fire ( {
@@ -453,6 +464,104 @@ <h3 data-i18n="admin.view_manage" class="card-title section-title">View and mana
453464 handleColVisibilityCheckbox ( $ ( '#checkColRole' ) , 4 ) ;
454465 handleColVisibilityCheckbox ( $ ( '#checkCol2FA' ) , 5 ) ;
455466 handleColVisibilityCheckbox ( $ ( '#checkColDesc' ) , 6 ) ;
467+
468+ const exportButton = $ ( document . querySelector ( '[data-table-filter="export"]' ) ) ;
469+ exportButton . on ( 'click' , function ( e ) {
470+ e . preventDefault ( ) ;
471+ this . blur ( ) ;
472+ this . setAttribute ( 'data-kt-indicator' , 'on' ) ;
473+ this . disabled = true ;
474+
475+ let data = [ ] ;
476+ dt . rows ( { search : 'applied' } ) . every ( function ( rowIdx , tableLoop , rowLoop ) {
477+ let line = { } ;
478+ let rowData = dt . row ( rowIdx ) . data ( ) ;
479+ let filters = rowData [ "filters" ] ;
480+
481+ line [ "Username" ] = rowData [ "username" ] ;
482+ let status = "Inactive" ;
483+ if ( rowData [ "status" ] == 1 ) {
484+ status = "Active" ;
485+ }
486+ line [ "Status" ] = status ;
487+ line [ "Permissions" ] = rowData [ "permissions" ] . join ( ", " ) ;
488+
489+ if ( rowData [ "created_at" ] ) {
490+ line [ "Created At" ] = moment ( rowData [ "created_at" ] ) . format ( "YYYY-MM-DD HH:mm" ) ;
491+ } else {
492+ line [ "Created At" ] = "" ;
493+ }
494+ if ( rowData [ "updated_at" ] ) {
495+ line [ "Updated At" ] = moment ( rowData [ "updated_at" ] ) . format ( "YYYY-MM-DD HH:mm" ) ;
496+ } else {
497+ line [ "Updated At" ] = "" ;
498+ }
499+ if ( rowData [ "last_login" ] ) {
500+ line [ "Last Login" ] = moment ( rowData [ "last_login" ] ) . format ( "YYYY-MM-DD HH:mm" ) ;
501+ } else {
502+ line [ "Last Login" ] = "" ;
503+ }
504+ if ( rowData [ "email" ] ) {
505+ line [ "Email" ] = rowData [ "email" ] ;
506+ } else {
507+ line [ "Email" ] = "" ;
508+ }
509+ let totpConfig = filters [ "totp_config" ] ;
510+ if ( totpConfig && totpConfig [ "enabled" ] ) {
511+ line [ "Two-factor auth" ] = "Enabled" ;
512+ } else {
513+ line [ "Two-factor auth" ] = "Disabled" ;
514+ }
515+ if ( filters [ "allow_list" ] ) {
516+ line [ "Allow List" ] = filters [ "allow_list" ] . join ( ", " ) ;
517+ } else {
518+ line [ "Allow List" ] = "" ;
519+ }
520+ let groups = [ ] ;
521+ let rowGroups = rowData [ "groups" ] ;
522+ if ( rowGroups ) {
523+ for ( i = 0 ; i < rowGroups . length ; i ++ ) {
524+ groups . push ( rowGroups [ i ] . name ) ;
525+ }
526+ }
527+ line [ "Groups" ] = groups . join ( ", " ) ;
528+ if ( rowData [ "role" ] ) {
529+ line [ "Role" ] = rowData [ "role" ] ;
530+ } else {
531+ line [ "Role" ] = "" ;
532+ }
533+ if ( rowData [ "description" ] ) {
534+ line [ "Description" ] = rowData [ "description" ] ;
535+ } else {
536+ line [ "Description" ] = "" ;
537+ }
538+ if ( rowData [ "additional_info" ] ) {
539+ line [ "Additional info" ] = rowData [ "additional_info" ] ;
540+ } else {
541+ line [ "Additional info" ] = "" ;
542+ }
543+
544+ data . push ( line ) ;
545+ } ) ;
546+
547+ let csv = Papa . unparse ( data , {
548+ quotes : false ,
549+ quoteChar : '"' ,
550+ escapeChar : '"' ,
551+ delimiter : "," ,
552+ header : true ,
553+ newline : "\r\n" ,
554+ skipEmptyLines : false ,
555+ columns : null ,
556+ escapeFormulae : true
557+ } ) ;
558+ let blob = new Blob ( [ csv ] , { type : "text/csv" } ) ;
559+ let ts = moment ( ) . format ( "YYYY_MM_DD_HH_mm_ss" ) ;
560+ saveAs ( blob , `admins_${ ts } .csv` ) ;
561+
562+ this . removeAttribute ( 'data-kt-indicator' ) ;
563+ this . disabled = false ;
564+ } ) ;
456565 }
457566
458567 function handleRowActions ( ) {
0 commit comments