فهرست منبع

update admin-activty jsp with new tabs

Jason Rivard 7 سال پیش
والد
کامیت
a3c8138755

+ 23 - 28
server/src/main/java/password/pwm/http/servlet/admin/AdminServlet.java

@@ -48,10 +48,8 @@ import password.pwm.http.servlet.ControlledPwmServlet;
 import password.pwm.http.servlet.PwmServletDefinition;
 import password.pwm.http.servlet.PwmServletDefinition;
 import password.pwm.i18n.Message;
 import password.pwm.i18n.Message;
 import password.pwm.ldap.search.UserSearchEngine;
 import password.pwm.ldap.search.UserSearchEngine;
+import password.pwm.svc.event.AuditEvent;
 import password.pwm.svc.event.AuditRecord;
 import password.pwm.svc.event.AuditRecord;
-import password.pwm.svc.event.HelpdeskAuditRecord;
-import password.pwm.svc.event.SystemAuditRecord;
-import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.svc.intruder.RecordType;
 import password.pwm.svc.intruder.RecordType;
 import password.pwm.svc.report.ReportColumnFilter;
 import password.pwm.svc.report.ReportColumnFilter;
 import password.pwm.svc.report.ReportCsvUtility;
 import password.pwm.svc.report.ReportCsvUtility;
@@ -62,6 +60,7 @@ import password.pwm.util.java.ClosableIterator;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.StringUtil;
+import password.pwm.util.java.TimeDuration;
 import password.pwm.util.localdb.LocalDBException;
 import password.pwm.util.localdb.LocalDBException;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.reports.ReportUtils;
 import password.pwm.util.reports.ReportUtils;
@@ -75,6 +74,7 @@ import java.io.OutputStream;
 import java.io.Writer;
 import java.io.Writer;
 import java.lang.management.ManagementFactory;
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadInfo;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
@@ -84,6 +84,7 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
 import java.util.TreeMap;
 import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
 
 
 @WebServlet(
 @WebServlet(
         name = "AdminServlet",
         name = "AdminServlet",
@@ -437,38 +438,32 @@ public class AdminServlet extends ControlledPwmServlet
 
 
     @ActionHandler( action = "auditData" )
     @ActionHandler( action = "auditData" )
     private ProcessStatus restAuditDataHandler( final PwmRequest pwmRequest )
     private ProcessStatus restAuditDataHandler( final PwmRequest pwmRequest )
-            throws ChaiUnavailableException, PwmUnrecoverableException, IOException
+            throws PwmUnrecoverableException, IOException
     {
     {
-        final int max = readMaxParameter( pwmRequest, 1000, 10 * 1000 );
-        final ArrayList<UserAuditRecord> userRecords = new ArrayList<>();
-        final ArrayList<HelpdeskAuditRecord> helpdeskRecords = new ArrayList<>();
-        final ArrayList<SystemAuditRecord> systemRecords = new ArrayList<>();
+        final Instant startTime = Instant.now();
+        final TimeDuration maxSearchTime = new TimeDuration( 10, TimeUnit.SECONDS );
+        final int max = readMaxParameter( pwmRequest, 100, 10 * 1000 );
+        final AuditEvent.Type auditDataType = AuditEvent.Type.valueOf( pwmRequest.readParameterAsString( "type", AuditEvent.Type.USER.name() ) );
+        final ArrayList<AuditRecord> records = new ArrayList<>();
         final Iterator<AuditRecord> iterator = pwmRequest.getPwmApplication().getAuditManager().readVault();
         final Iterator<AuditRecord> iterator = pwmRequest.getPwmApplication().getAuditManager().readVault();
-        int counter = 0;
-        while ( iterator.hasNext() && counter <= max )
+
+        while (
+                iterator.hasNext()
+                        && records.size() < max
+                        && TimeDuration.fromCurrent( startTime ).isShorterThan( maxSearchTime )
+                )
         {
         {
             final AuditRecord loopRecord = iterator.next();
             final AuditRecord loopRecord = iterator.next();
-            counter++;
-            if ( loopRecord instanceof SystemAuditRecord )
+            if ( auditDataType == loopRecord.getType() )
             {
             {
-                systemRecords.add( ( SystemAuditRecord ) loopRecord );
-            }
-            else if ( loopRecord instanceof HelpdeskAuditRecord )
-            {
-                helpdeskRecords.add( ( HelpdeskAuditRecord ) loopRecord );
-            }
-            else if ( loopRecord instanceof UserAuditRecord )
-            {
-                userRecords.add( ( UserAuditRecord ) loopRecord );
+                records.add( loopRecord );
             }
             }
         }
         }
-        final HashMap<String, List> outputMap = new HashMap<>();
-        outputMap.put( "user", userRecords );
-        outputMap.put( "helpdesk", helpdeskRecords );
-        outputMap.put( "system", systemRecords );
 
 
-        final RestResultBean restResultBean = RestResultBean.withData( outputMap );
-        LOGGER.debug( pwmRequest.getPwmSession(), "output " + counter + " audit records." );
+        final HashMap<String, Object> resultData = new HashMap<>( Collections.singletonMap( "records", records ) );
+
+        final RestResultBean restResultBean = RestResultBean.withData( resultData );
+        LOGGER.debug( pwmRequest.getPwmSession(), "output " + records.size() + " audit records." );
         pwmRequest.outputJsonResult( restResultBean );
         pwmRequest.outputJsonResult( restResultBean );
         return ProcessStatus.Halt;
         return ProcessStatus.Halt;
     }
     }
@@ -640,7 +635,7 @@ public class AdminServlet extends ControlledPwmServlet
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
         final String stringMax = pwmRequest.readParameterAsString( "maximum", String.valueOf( defaultValue ) );
         final String stringMax = pwmRequest.readParameterAsString( "maximum", String.valueOf( defaultValue ) );
-        return Math.max( Integer.parseInt( stringMax ), maxValue );
+        return Math.min( Integer.parseInt( stringMax ), maxValue );
     }
     }
 
 
     public enum Page
     public enum Page

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/admin/AppDashboardData.java

@@ -480,7 +480,7 @@ public class AppDashboardData implements Serializable
             javaInfo.add( new DisplayElement(
             javaInfo.add( new DisplayElement(
                     "sessionAverageSize",
                     "sessionAverageSize",
                     DisplayElement.Type.string,
                     DisplayElement.Type.string,
-                    "Estimated Session Total Size",
+                    "Estimated Session Average Size",
                     debugInfoMap.get( SessionTrackService.DebugKey.HttpSessionAvgSize )
                     debugInfoMap.get( SessionTrackService.DebugKey.HttpSessionAvgSize )
             ) );
             ) );
         }
         }

+ 2 - 12
server/src/main/webapp/WEB-INF/jsp/accountinformation.jsp

@@ -42,7 +42,7 @@
     </jsp:include>
     </jsp:include>
     <div id="centerbody">
     <div id="centerbody">
         <div id="page-content-title" style="display: none;"><pwm:display key="Title_UserInformation" displayIfMissing="true"/></div>
         <div id="page-content-title" style="display: none;"><pwm:display key="Title_UserInformation" displayIfMissing="true"/></div>
-        <div class="tab-container" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false">
+        <div class="tab-container" style="width: 100%; height: 100%;">
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <label for="tab-1" class="label"><pwm:display key="Title_UserInformation"/></label>
             <label for="tab-1" class="label"><pwm:display key="Title_UserInformation"/></label>
             <div class="tab-content-pane" id="UserInformation" title="<pwm:display key="Title_UserInformation"/>" class="tabContent">
             <div class="tab-content-pane" id="UserInformation" title="<pwm:display key="Title_UserInformation"/>" class="tabContent">
@@ -55,7 +55,7 @@
             </div>
             </div>
             <% if (!JavaHelper.isEmpty(accountInformationBean.getFormData())) { %>
             <% if (!JavaHelper.isEmpty(accountInformationBean.getFormData())) { %>
             <input name="tabs" type="radio" id="tab-2" class="input"/>
             <input name="tabs" type="radio" id="tab-2" class="input"/>
-            <label for="tab-2" class="label"><%=Display.Title_UserData.toString()%></label>
+            <label for="tab-2" class="label"><pwm:display key="Title_UserData"/></label>
             <div class="tab-content-pane" id="UserData" title="<pwm:display key="<%=Display.Title_UserData.toString()%>"/>" class="tabContent">
             <div class="tab-content-pane" id="UserData" title="<pwm:display key="<%=Display.Title_UserData.toString()%>"/>" class="tabContent">
                 <div style="max-height: 400px; overflow: auto;">
                 <div style="max-height: 400px; overflow: auto;">
                     <table class="nomargin">
                     <table class="nomargin">
@@ -126,16 +126,6 @@
     </div>
     </div>
     <div class="push"></div>
     <div class="push"></div>
 </div>
 </div>
-<pwm:script>
-    <script type="text/javascript">
-        PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo/parser","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojoParser){
-                dojoParser.parse();
-            });
-        });
-    </script>
-</pwm:script>
-<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/tab-container.css' addContext="true"/>"/>
 <jsp:include page="/WEB-INF/jsp/fragment/footer.jsp"/>
 <jsp:include page="/WEB-INF/jsp/fragment/footer.jsp"/>
 </body>
 </body>
 </html>                   
 </html>                   

+ 114 - 109
server/src/main/webapp/WEB-INF/jsp/admin-activity.jsp

@@ -49,20 +49,22 @@
     }
     }
 </style>
 </style>
 <div id="wrapper">
 <div id="wrapper">
-    <% final String PageName = JspUtility.localizedString(pageContext,"Title_UserActivity",Admin.class);%>
+        <% final String PageName = JspUtility.localizedString(pageContext,"Title_UserActivity",Admin.class);%>
     <jsp:include page="/WEB-INF/jsp/fragment/header-body.jsp" flush="true" >
     <jsp:include page="/WEB-INF/jsp/fragment/header-body.jsp" flush="true" >
         <jsp:param name="pwm.PageName" value="<%=PageName%>"/>
         <jsp:param name="pwm.PageName" value="<%=PageName%>"/>
     </jsp:include>
     </jsp:include>
     <div id="centerbody" class="wide">
     <div id="centerbody" class="wide">
         <div id="page-content-title"><pwm:display key="Title_UserActivity" bundle="Admin"/></div>
         <div id="page-content-title"><pwm:display key="Title_UserActivity" bundle="Admin"/></div>
         <%@ include file="fragment/admin-nav.jsp" %>
         <%@ include file="fragment/admin-nav.jsp" %>
-        <div data-dojo-type="dijit/layout/TabContainer" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true">
-            <div id="ActiveWebSessions" data-dojo-type="dijit/layout/ContentPane" title="<pwm:display key="Title_Sessions" bundle="Admin"/>" class="tabContent">
+        <div id="ActivityTabContainer" class="tab-container" style="width: 100%; height: 100%;">
+            <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
+            <label for="tab-1" class="label"><pwm:display key="Title_Sessions" bundle="Admin"/></label>
+            <div id="SessionsTab" class="tab-content-pane" title="<pwm:display key="Title_Sessions" bundle="Admin"/>" >
+
                 <div id="activeSessionGrid" class="analysisGrid">
                 <div id="activeSessionGrid" class="analysisGrid">
                 </div>
                 </div>
                 <div style="text-align: center">
                 <div style="text-align: center">
-                    <input name="maxResults" id="maxActiveSessionResults" value="1000" data-dojo-type="dijit/form/NumberSpinner" style="width: 70px"
-                           data-dojo-props="constraints:{min:10,max:10000000,pattern:'#'},smallDelta:100"/>
+                    <input name="maxResults" id="maxActiveSessionResults" value="1000" type="number" min="10" max="10000000" style="width: 70px"/>
                     Rows
                     Rows
                     <button class="btn" type="button" id="button-activeSessionRefresh">
                     <button class="btn" type="button" id="button-activeSessionRefresh">
                         <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
                         <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
@@ -77,126 +79,129 @@
                             });
                             });
                         </script>
                         </script>
                     </pwm:script>
                     </pwm:script>
-
                 </div>
                 </div>
             </div>
             </div>
+            <input name="tabs" type="radio" id="tab-2" class="input"/>
+            <label for="tab-2" class="label"><pwm:display key="Title_Intruders" bundle="Admin"/></label>
+            <div id="IntrudersTab" class="tab-content-pane" title="<pwm:display key="Title_Intruders" bundle="Admin"/>">
+                <div class="tab-container" style="width: 100%; height: 100%;">
+                    <% boolean checked = true; %>
+                    <% for (final RecordType recordType : RecordType.values()) { %>
+                    <% final String titleName = LocaleHelper.getLocalizedMessage(activity_pwmRequest.getLocale(),"IntruderRecordType_" + recordType.toString(), activity_pwmRequest.getConfig(), Admin.class); %>
+                    <input name="intruder_tabs" type="radio" id="tab-2.<%=recordType%>" <%=checked?"checked=\"checked\"":""%> class="input"/>
+                    <label for="tab-2.<%=recordType%>" class="label"><%=titleName%></label>
+                    <div class="tab-content-pane" title="<%=titleName%>">
 
 
-
-            <div data-dojo-type="dijit/layout/TabContainer" title="<pwm:display key="Title_Intruders" bundle="Admin"/>" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true">
-            <% for (final RecordType recordType : RecordType.values()) { %>
-            <% final String titleName = LocaleHelper.getLocalizedMessage(activity_pwmRequest.getLocale(),"IntruderRecordType_" + recordType.toString(), activity_pwmRequest.getConfig(), Admin.class); %>
-            <div id="Intruders<%=titleName%>" data-dojo-type="dijit/layout/ContentPane" title="<%=titleName%>" class="tabContent">
-                <div id="<%=recordType%>_Grid" class="analysisGrid">
+                            <div id="<%=recordType%>_Grid" class="analysisGrid">
+                            </div>
+                    </div>
+                    <% checked = false; %>
+                    <% } %>
+                    <div class="tab-end"></div>
                 </div>
                 </div>
             </div>
             </div>
-            <% } %>
-            </div>
+            <input name="tabs" type="radio" id="tab-3" class="input"/>
+            <label for="tab-3" class="label" id="audit_tab_label"><pwm:display key="Title_Audit" bundle="Admin"/></label>
+            <div id="AuditTab" class="tab-content-pane" title="<pwm:display key="Title_Audit" bundle="Admin"/>">
+                <div class="tab-container" style="width: 100%; height: 100%;">
 
 
-            <div data-dojo-type="dijit/layout/TabContainer" title="<pwm:display key="Title_Audit" bundle="Admin"/>" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true">
-            <div id="AuditUser" data-dojo-type="dijit/layout/ContentPane" title="<pwm:display key="Title_AuditUsers" bundle="Admin"/>" class="tabContent">
-                <div id="auditUserGrid" class="analysisGrid">
-                </div>
-                <div style="text-align: center">
-                    <input name="maxAuditUserResults" id="maxAuditUserResults" value="1000" data-dojo-type="dijit/form/NumberSpinner" style="width: 70px"
-                           data-dojo-props="constraints:{min:10,max:10000000,pattern:'#'},smallDelta:100"/>
-                    Rows
-                    <button class="btn" type="button" id="button-refreshAuditUser">
-                        <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
-                        <pwm:display key="Button_Refresh" bundle="Admin"/>
-                    </button>
-                    <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
-                        <button type="submit" class="btn">
-                            <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
-                            <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
-                        </button>
-                        <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
-                        <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
-                    </form>
-                </div>
-            </div>
-            <div id="AuditHelpdesk" data-dojo-type="dijit/layout/ContentPane" title="<pwm:display key="Title_AuditHelpdesk" bundle="Admin"/>" class="tabContent">
-                <div id="auditHelpdeskGrid" class="analysisGrid">
-                </div>
-                <div style="text-align: center">
-                    <input name="maxAuditHelpdeskResults" id="maxAuditHelpdeskResults" value="1000" data-dojo-type="dijit/form/NumberSpinner" style="width: 70px"
-                           data-dojo-props="constraints:{min:10,max:10000000,pattern:'#'},smallDelta:100"/>
-                    Rows
-                    <button class="btn" type="button" id="button-refreshHelpdeskUser">
-                        <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
-                        <pwm:display key="Button_Refresh" bundle="Admin"/>
-                    </button>
-                    <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
-                        <button type="submit" class="btn">
-                            <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
-                            <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
-                        </button>
-                        <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
-                        <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
-                    </form>
-                </div>
-            </div>
-            <div id="AuditSystem" data-dojo-type="dijit/layout/ContentPane" title="<pwm:display key="Title_AuditSystem" bundle="Admin"/>" class="tabContent">
-                <div id="auditSystemGrid" class="analysisGrid">
-                </div>
-                <div style="text-align: center">
-                    <input name="maxAuditSystemResults" id="maxAuditSystemResults" value="1000" data-dojo-type="dijit/form/NumberSpinner" style="width: 70px"
-                           data-dojo-props="constraints:{min:10,max:10000000,pattern:'#'},smallDelta:100"/>
-                    Rows
-                    <button class="btn" type="button" id="button-refreshSystemAudit">
-                        <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
-                        <pwm:display key="Button_Refresh" bundle="Admin"/>
-                    </button>
-                    <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
-                        <button type="submit" class="btn">
-                            <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
-                            <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
-                        </button>
-                        <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
-                        <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
-                    </form>
+                    <input name="audit_tabs" type="radio" id="tab-3.1" checked="checked" class="input"/>
+                    <label for="tab-3.1" class="label"><pwm:display key="Title_AuditUsers" bundle="Admin"/></label>
+                    <div class="tab-content-pane" title="<pwm:display key="Title_AuditUsers" bundle="Admin"/>" class="tabContent">
+
+                        <div id="auditUserGrid" class="analysisGrid">
+                        </div>
+
+                        <div style="text-align: center">
+                            <input name="maxAuditUserResults" id="maxAuditUserResults" value="100" type="number" min="10" max="10000000" style="width: 70px"/>
+                            Rows
+                            <button class="btn" type="button" id="button-refreshAuditUser">
+                                <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
+                                <pwm:display key="Button_Refresh" bundle="Admin"/>
+                            </button>
+                            <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
+                                <button type="submit" class="btn">
+                                    <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
+                                    <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
+                                </button>
+                                <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
+                                <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
+                            </form>
+                        </div>
+                    </div>
+                    <input name="audit_tabs" type="radio" id="tab-3.2" class="input"/>
+                    <label for="tab-3.2" class="label"><pwm:display key="Title_AuditHelpdesk" bundle="Admin"/></label>
+                    <div class="tab-content-pane" title="<pwm:display key="Title_AuditHelpdesk" bundle="Admin"/>" class="tabContent">
+                        <div id="auditHelpdeskGrid" class="analysisGrid">
+                        </div>
+                        <div style="text-align: center">
+                            <input name="maxAuditHelpdeskResults" id="maxAuditHelpdeskResults" value="100" type="number" min="10" max="10000000" style="width: 70px"/>
+                            Rows
+                            <button class="btn" type="button" id="button-refreshHelpdeskUser">
+                                <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
+                                <pwm:display key="Button_Refresh" bundle="Admin"/>
+                            </button>
+                            <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
+                                <button type="submit" class="btn">
+                                    <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
+                                    <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
+                                </button>
+                                <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
+                                <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
+                            </form>
+                        </div>
+                    </div>
+                    <input name="audit_tabs" type="radio" id="tab-3.3" class="input"/>
+                    <label for="tab-3.3" class="label"><pwm:display key="Title_AuditSystem" bundle="Admin"/></label>
+                    <div class="tab-content-pane" title="<pwm:display key="Title_AuditSystem" bundle="Admin"/>" class="tabContent">
+                        <div id="auditSystemGrid" class="analysisGrid">
+                        </div>
+                        <div style="text-align: center">
+                            <input name="maxAuditSystemResults" id="maxAuditSystemResults" value="100" type="number" min="10" max="10000000" style="width: 70px"/>
+                            Rows
+                            <button class="btn" type="button" id="button-refreshSystemAudit">
+                                <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
+                                <pwm:display key="Button_Refresh" bundle="Admin"/>
+                            </button>
+                            <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded">
+                                <button type="submit" class="btn">
+                                    <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-download"></span></pwm:if>
+                                    <pwm:display key="Button_DownloadCSV" bundle="Admin"/>
+                                </button>
+                                <input type="hidden" name="processAction" value="downloadAuditLogCsv"/>
+                                <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
+                            </form>
+                        </div>
+                    </div>
+                    <div class="tab-end"></div>
                 </div>
                 </div>
             </div>
             </div>
-            </div>
-        </div>
-        <br/>
-        <%--
-        <div style="text-align: center">
-            <input name="maxResults" id="maxIntruderGridResults" value="1000" data-dojo-type="dijit/form/NumberSpinner" style="width: 70px"
-                   data-dojo-props="constraints:{min:10,max:10000000,pattern:'#'},smallDelta:100"/>
-            Rows
-            <button class="btn" type="button" onclick="PWM_ADMIN.refreshIntruderGrid()">
-                <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-refresh">&nbsp;</span></pwm:if>
-                <pwm:display key="Button_Refresh" bundle="Admin"/>
-            </button>
+            <div class="tab-end"></div>
         </div>
         </div>
-        --%>
+        <div class="push"></div>
     </div>
     </div>
-    <div class="push"></div>
-</div>
-<pwm:script>
+    <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         PWM_GLOBAL['startupFunctions'].push(function(){
         PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo/parser","dojo/ready","dijit/layout/TabContainer","dijit/layout/ContentPane","dijit/Dialog","dijit/form/NumberSpinner"],function(dojoParser,ready){
-                dojoParser.parse(PWM_MAIN.getObject('centerbody'));
-                PWM_ADMIN.initIntrudersGrid();
-                PWM_ADMIN.initActiveSessionGrid();
-                PWM_ADMIN.initAuditGrid();
-
+            PWM_MAIN.addEventHandler('audit_tab_label','click',function(){
+            });
 
 
+            PWM_ADMIN.initAuditGrid();
+            PWM_ADMIN.initActiveSessionGrid();
+            PWM_ADMIN.initIntrudersGrid();
 
 
-                PWM_MAIN.addEventHandler('button-refreshAuditUser','click',function(){
-                    PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditUserResults').value);
-                });
-                PWM_MAIN.addEventHandler('button-refreshHelpdeskUser','click',function(){
-                    PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditHelpdeskResults').value);
-                });
-                PWM_MAIN.addEventHandler('button-refreshSystemAudit','click',function(){
-                    PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditSystemResults').value);
-                });
+            PWM_MAIN.addEventHandler('button-refreshAuditUser','click',function(){
+                PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditUserResults').value,'USER');
+            });
+            PWM_MAIN.addEventHandler('button-refreshHelpdeskUser','click',function(){
+                PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditHelpdeskResults').value,'HELPDESK');
+            });
+            PWM_MAIN.addEventHandler('button-refreshSystemAudit','click',function(){
+                PWM_ADMIN.refreshAuditGridData(PWM_MAIN.getObject('maxAuditSystemResults').value,'SYSTEM');
             });
             });
         });
         });
     </script>
     </script>
-</pwm:script>
-<%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
+    </pwm:script>
+    <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 </body>
 </body>
 </html>
 </html>

+ 5 - 8
server/src/main/webapp/WEB-INF/jsp/admin-analysis.jsp

@@ -63,10 +63,10 @@
     <div id="centerbody" class="wide">
     <div id="centerbody" class="wide">
         <div id="page-content-title"><pwm:display key="Title_DataAnalysis" bundle="Admin"/></div>
         <div id="page-content-title"><pwm:display key="Title_DataAnalysis" bundle="Admin"/></div>
         <%@ include file="fragment/admin-nav.jsp" %>
         <%@ include file="fragment/admin-nav.jsp" %>
-        <div class="tab-container" style="width: 100%; height: 100%;"  data-dojo-props="doLayout: false, persist: true" id="analysis-topLevelTab">
+        <div class="tab-container" style="width: 100%; height: 100%;" id="analysis-topLevelTab">
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <label for="tab-1" class="label"><pwm:display key="Title_DirectoryReporting" bundle="Admin"/></label>
             <label for="tab-1" class="label"><pwm:display key="Title_DirectoryReporting" bundle="Admin"/></label>
-            <div class="tab-content-pane" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_DirectoryReporting" bundle="Admin"/>">
+            <div class="tab-content-pane" style="width: 100%; height: 100%;" title="<pwm:display key="Title_DirectoryReporting" bundle="Admin"/>">
                 <div class="tab-container" style="width: 100%; height: 100%;">
                 <div class="tab-container" style="width: 100%; height: 100%;">
                     <input name="dr_tabs" type="radio" id="tab-1.1" checked="checked" class="input"/>
                     <input name="dr_tabs" type="radio" id="tab-1.1" checked="checked" class="input"/>
                     <label for="tab-1.1" class="label"><pwm:display key="Title_ReportEngineStatus" bundle="Admin"/></label>
                     <label for="tab-1.1" class="label"><pwm:display key="Title_ReportEngineStatus" bundle="Admin"/></label>
@@ -169,7 +169,7 @@
 
 
             <input name="tabs" type="radio" id="tab-2" class="input"/>
             <input name="tabs" type="radio" id="tab-2" class="input"/>
             <label for="tab-2" class="label"><pwm:display key="Title_EventStatistics" bundle="Admin"/></label>
             <label for="tab-2" class="label"><pwm:display key="Title_EventStatistics" bundle="Admin"/></label>
-            <div class="tab-content-pane" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_EventStatistics" bundle="Admin"/>">
+            <div class="tab-content-pane" style="width: 100%; height: 100%;" title="<pwm:display key="Title_EventStatistics" bundle="Admin"/>">
                 <div class="tab-container" style="width: 100%; height: 100%;">
                 <div class="tab-container" style="width: 100%; height: 100%;">
                     <input name="es_tabs" type="radio" id="tab-2.1" checked="checked" class="input"/>
                     <input name="es_tabs" type="radio" id="tab-2.1" checked="checked" class="input"/>
                     <label for="tab-2.1" class="label"><pwm:display key="Title_RawStatistics" bundle="Admin"/></label>
                     <label for="tab-2.1" class="label"><pwm:display key="Title_RawStatistics" bundle="Admin"/></label>
@@ -181,7 +181,7 @@
                                         <form action="<pwm:current-url/>" method="GET" enctype="application/x-www-form-urlencoded"
                                         <form action="<pwm:current-url/>" method="GET" enctype="application/x-www-form-urlencoded"
                                               name="statsUpdateForm" id="statsUpdateForm">
                                               name="statsUpdateForm" id="statsUpdateForm">
                                             <select name="statsPeriodSelect"
                                             <select name="statsPeriodSelect"
-                                                    style="width: 350px;" data-dojo-props="maxHeight: -1">
+                                                    style="width: 350px;">
                                                 <option value="<%=StatisticsManager.KEY_CUMULATIVE%>" <%= StatisticsManager.KEY_CUMULATIVE.equals(statsPeriodSelect) ? "selected=\"selected\"" : "" %>>
                                                 <option value="<%=StatisticsManager.KEY_CUMULATIVE%>" <%= StatisticsManager.KEY_CUMULATIVE.equals(statsPeriodSelect) ? "selected=\"selected\"" : "" %>>
                                                     since installation - <%= JavaHelper.toIsoDate(analysis_pwmRequest.getPwmApplication().getInstallTime()) %>
                                                     since installation - <%= JavaHelper.toIsoDate(analysis_pwmRequest.getPwmApplication().getInstallTime()) %>
                                                 </option>
                                                 </option>
@@ -253,7 +253,6 @@
                 </div>
                 </div>
             </div>
             </div>
 
 
-            <div class="tab-end"></div>
         </div>
         </div>
     </div>
     </div>
     <div class="push"></div>
     <div class="push"></div>
@@ -269,8 +268,7 @@
 
 
 
 
         PWM_GLOBAL['startupFunctions'].push(function(){
         PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo","dojo/query","dojo/parser","dijit/registry","dojo/ready","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojo,query,dojoParser,registry,ready){
-                dojoParser.parse('centerbody');
+            require(["dojo","dojo/query"],function(dojo,query){
                 PWM_MAIN.JSLibrary.setValueOfSelectElement('statsChartSelect','<%=Statistic.PASSWORD_CHANGES%>');
                 PWM_MAIN.JSLibrary.setValueOfSelectElement('statsChartSelect','<%=Statistic.PASSWORD_CHANGES%>');
 
 
                 setTimeout(function(){
                 setTimeout(function(){
@@ -308,7 +306,6 @@
     </script>
     </script>
 </pwm:script>
 </pwm:script>
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.HIDE_LOCALE); %>
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.HIDE_LOCALE); %>
-<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/tab-container.css' addContext="true"/>"/>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 </body>
 </body>
 </html>
 </html>

+ 37 - 39
server/src/main/webapp/WEB-INF/jsp/admin-dashboard.jsp

@@ -55,7 +55,7 @@
     <div id="centerbody">
     <div id="centerbody">
         <div id="page-content-title"><pwm:display key="Title_Dashboard" bundle="Admin"/></div>
         <div id="page-content-title"><pwm:display key="Title_Dashboard" bundle="Admin"/></div>
         <%@ include file="fragment/admin-nav.jsp" %>
         <%@ include file="fragment/admin-nav.jsp" %>
-        <div id="DashboardTabContainer" class="tab-container" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true">
+        <div id="DashboardTabContainer" class="tab-container" style="width: 100%; height: 100%;">
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <label for="tab-1" class="label">Status</label>
             <label for="tab-1" class="label">Status</label>
             <div id="StatusTab" class="tab-content-pane" title="Status" >
             <div id="StatusTab" class="tab-content-pane" title="Status" >
@@ -109,7 +109,7 @@
                     <% } %>
                     <% } %>
                     <% } %>
                     <% } %>
                 </table>
                 </table>
-                <div class="tab-container" style="margin-top: 15px;" data-dojo-props="doLayout: false, persist: true">
+                <div class="tab-container" style="margin-top: 15px;">
                     <input name="status_tabs" type="radio" id="tab-1.1" checked="checked" class="input"/>
                     <input name="status_tabs" type="radio" id="tab-1.1" checked="checked" class="input"/>
                     <label for="tab-1.1" class="label">Last Minute</label>
                     <label for="tab-1.1" class="label">Last Minute</label>
                     <div class="tab-content-pane" title="Last Minute" class="tabContent">
                     <div class="tab-content-pane" title="Last Minute" class="tabContent">
@@ -242,6 +242,7 @@
             <input name="tabs" type="radio" id="tab-4" class="input"/>
             <input name="tabs" type="radio" id="tab-4" class="input"/>
             <label for="tab-4" class="label">Services</label>
             <label for="tab-4" class="label">Services</label>
             <div id="ServicesTab" class="tab-content-pane" title="Services">
             <div id="ServicesTab" class="tab-content-pane" title="Services">
+                <div style="max-height: 600px; overflow: auto;">
                 <table class="nomargin">
                 <table class="nomargin">
                     <tr>
                     <tr>
                         <th style="font-weight:bold;">
                         <th style="font-weight:bold;">
@@ -289,6 +290,7 @@
                     </tr>
                     </tr>
                     <% } %>
                     <% } %>
                 </table>
                 </table>
+                </div>
             </div>
             </div>
 
 
             <input name="tabs" type="radio" id="tab-5" class="input"/>
             <input name="tabs" type="radio" id="tab-5" class="input"/>
@@ -304,32 +306,32 @@
                 </div>
                 </div>
                 <br/>
                 <br/>
                 <div style="max-height: 400px; overflow: auto;">
                 <div style="max-height: 400px; overflow: auto;">
-                <% if (!JavaHelper.isEmpty(appDashboardData.getLocalDbSizes())) { %>
-                <table class="nomargin">
-                    <tr>
-                        <td class="key">
-                            Name
-                        </td>
-                        <td class="key" style="text-align: left">
-                            Record Count
-                        </td>
-                    </tr>
-                    <% for (final Map.Entry<LocalDB.DB,String> entry : appDashboardData.getLocalDbSizes().entrySet()) { %>
-                    <tr>
-                        <td style="text-align: right">
-                            <%= entry.getKey() %>
-                        </td>
-                        <td>
-                            <%= entry.getValue() %>
-                        </td>
-                    </tr>
+                    <% if (!JavaHelper.isEmpty(appDashboardData.getLocalDbSizes())) { %>
+                    <table class="nomargin">
+                        <tr>
+                            <td class="key">
+                                Name
+                            </td>
+                            <td class="key" style="text-align: left">
+                                Record Count
+                            </td>
+                        </tr>
+                        <% for (final Map.Entry<LocalDB.DB,String> entry : appDashboardData.getLocalDbSizes().entrySet()) { %>
+                        <tr>
+                            <td style="text-align: right">
+                                <%= entry.getKey() %>
+                            </td>
+                            <td>
+                                <%= entry.getValue() %>
+                            </td>
+                        </tr>
+                        <% } %>
+                    </table>
+                    <% } else { %>
+                    <div class="noborder" style="text-align:center; width:100%;">
+                        <a style="cursor: pointer" id="button-showLocalDBCounts">Show LocalDB record counts</a> (may be slow to load)
+                    </div>
                     <% } %>
                     <% } %>
-                </table>
-                <% } else { %>
-                <div class="noborder" style="text-align:center; width:100%;">
-                    <a style="cursor: pointer" id="button-showLocalDBCounts">Show LocalDB record counts</a> (may be slow to load)
-                </div>
-                <% } %>
                 </div>
                 </div>
             </div>
             </div>
 
 
@@ -449,21 +451,18 @@
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         PWM_GLOBAL['startupFunctions'].push(function(){
         PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo/parser","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojoParser){
-                dojoParser.parse();
-                PWM_ADMIN.showStatChart('PASSWORD_CHANGES',14,'statsChart',{refreshTime:11*1000});
-                PWM_ADMIN.showAppHealth('healthBody', {showRefresh:true,showTimestamp:true});
+            PWM_ADMIN.showStatChart('PASSWORD_CHANGES',14,'statsChart',{refreshTime:11*1000});
+            PWM_ADMIN.showAppHealth('healthBody', {showRefresh:true,showTimestamp:true});
 
 
-                PWM_MAIN.addEventHandler('button-showLocalDBCounts','click',function(){
-                    PWM_MAIN.showWaitDialog({loadFunction:function(){
+            PWM_MAIN.addEventHandler('button-showLocalDBCounts','click',function(){
+                PWM_MAIN.showWaitDialog({loadFunction:function(){
                         PWM_MAIN.goto('dashboard?showLocalDBCounts=true');
                         PWM_MAIN.goto('dashboard?showLocalDBCounts=true');
                     }})
                     }})
-                });
-                PWM_MAIN.addEventHandler('button-showThreadDetails','click',function(){
-                    PWM_MAIN.showWaitDialog({loadFunction:function(){
+            });
+            PWM_MAIN.addEventHandler('button-showThreadDetails','click',function(){
+                PWM_MAIN.showWaitDialog({loadFunction:function(){
                         PWM_MAIN.goto('dashboard?showThreadDetails=true');
                         PWM_MAIN.goto('dashboard?showThreadDetails=true');
                     }})
                     }})
-                });
             });
             });
             <% for (final AppDashboardData.ServiceData loopService : appDashboardData.getServices()) { %>
             <% for (final AppDashboardData.ServiceData loopService : appDashboardData.getServices()) { %>
             <% if (!JavaHelper.isEmpty(loopService.getDebugData())) { %>
             <% if (!JavaHelper.isEmpty(loopService.getDebugData())) { %>
@@ -471,7 +470,7 @@
                 var tableText = '<table>';
                 var tableText = '<table>';
                 <% for (final Map.Entry<String,String> entry : loopService.getDebugData().entrySet()) { %>
                 <% for (final Map.Entry<String,String> entry : loopService.getDebugData().entrySet()) { %>
                 tableText += '<tr><td><%=StringUtil.escapeJS(entry.getKey())%></td>'
                 tableText += '<tr><td><%=StringUtil.escapeJS(entry.getKey())%></td>'
-                + '<td><%=StringUtil.escapeJS(entry.getValue())%></td></tr>';
+                    + '<td><%=StringUtil.escapeJS(entry.getValue())%></td></tr>';
                 <% } %>
                 <% } %>
                 tableText += '</table>';
                 tableText += '</table>';
                 PWM_MAIN.showDialog({title:'Debug Properties',text:tableText});
                 PWM_MAIN.showDialog({title:'Debug Properties',text:tableText});
@@ -482,7 +481,6 @@
     </script>
     </script>
 </pwm:script>
 </pwm:script>
 
 
-<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/tab-container.css' addContext="true"/>"/>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 <pwm:script-ref url="/public/resources/js/admin.js"/>
 <pwm:script-ref url="/public/resources/js/admin.js"/>
 </body>
 </body>

+ 1 - 13
server/src/main/webapp/WEB-INF/jsp/setupotpsecret.jsp

@@ -55,7 +55,7 @@
         <div id="page-content-title"><pwm:display key="Title_SetupOtpSecret" displayIfMissing="true"/></div>
         <div id="page-content-title"><pwm:display key="Title_SetupOtpSecret" displayIfMissing="true"/></div>
         <p><pwm:display key="Display_SetupOtpSecret"/></p>
         <p><pwm:display key="Display_SetupOtpSecret"/></p>
         <%@ include file="fragment/message.jsp" %>
         <%@ include file="fragment/message.jsp" %>
-        <div class="tab-container" data-dojo-props="doLayout: false, persist: true">
+        <div class="tab-container">
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <input name="tabs" type="radio" id="tab-1" checked="checked" class="input"/>
             <label for="tab-1" class="label"><pwm:display key="Display_SetupOtp_Android_Title"/></label>
             <label for="tab-1" class="label"><pwm:display key="Display_SetupOtp_Android_Title"/></label>
             <div class="tab-content-pane" title="<pwm:display key="Display_SetupOtp_Android_Title"/>">
             <div class="tab-content-pane" title="<pwm:display key="Display_SetupOtp_Android_Title"/>">
@@ -126,20 +126,8 @@
     </div>
     </div>
     <div class="push"></div>
     <div class="push"></div>
 </div>
 </div>
-<pwm:script>
-    <script type="text/javascript">
-        PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo/parser","dojo/ready","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojoParser,ready){
-                ready(function(){
-                    dojoParser.parse();
-                });
-            });
-        });
-    </script>
-</pwm:script>
 <pwm:script-ref url="/public/resources/js/responses.js"/>
 <pwm:script-ref url="/public/resources/js/responses.js"/>
 <pwm:script-ref url="/public/resources/js/otpsecret.js"/>
 <pwm:script-ref url="/public/resources/js/otpsecret.js"/>
-<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/tab-container.css' addContext="true"/>"/>
 <%@ include file="fragment/footer.jsp" %>
 <%@ include file="fragment/footer.jsp" %>
 </body>
 </body>
 </html>
 </html>

+ 131 - 158
server/src/main/webapp/public/resources/js/admin.js

@@ -114,30 +114,30 @@ PWM_ADMIN.initAdminNavMenu = function() {
 };
 };
 
 
 PWM_ADMIN.reportDataHeaders = function() {
 PWM_ADMIN.reportDataHeaders = function() {
-    return {
-        "username":PWM_ADMIN.showString("Field_Report_Username"),
-        "userDN":PWM_ADMIN.showString("Field_Report_UserDN"),
-        "ldapProfile":PWM_ADMIN.showString("Field_Report_LDAP_Profile"),
-        "email":PWM_ADMIN.showString("Field_Report_Email"),
-        "userGUID":PWM_ADMIN.showString("Field_Report_UserGuid"),
-        "accountExpirationTime":PWM_ADMIN.showString("Field_Report_AccountExpireTime"),
-        "passwordExpirationTime":PWM_ADMIN.showString("Field_Report_PwdExpireTime"),
-        "passwordChangeTime":PWM_ADMIN.showString("Field_Report_PwdChangeTime"),
-        "responseSetTime":PWM_ADMIN.showString("Field_Report_ResponseSaveTime"),
-        "lastLoginTime":PWM_ADMIN.showString("Field_Report_LastLogin"),
-        "hasResponses":PWM_ADMIN.showString("Field_Report_HasResponses"),
-        "hasHelpdeskResponses":PWM_ADMIN.showString("Field_Report_HasHelpdeskResponses"),
-        "responseStorageMethod":PWM_ADMIN.showString("Field_Report_ResponseStorageMethod"),
-        "responseFormatType":PWM_ADMIN.showString("Field_Report_ResponseFormatType"),
-        "passwordStatusExpired":PWM_ADMIN.showString("Field_Report_PwdExpired"),
-        "passwordStatusPreExpired":PWM_ADMIN.showString("Field_Report_PwdPreExpired"),
-        "passwordStatusViolatesPolicy":PWM_ADMIN.showString("Field_Report_PwdViolatesPolicy"),
-        "passwordStatusWarnPeriod":PWM_ADMIN.showString("Field_Report_PwdWarnPeriod"),
-        "requiresPasswordUpdate":PWM_ADMIN.showString("Field_Report_RequiresPasswordUpdate"),
-        "requiresResponseUpdate":PWM_ADMIN.showString("Field_Report_RequiresResponseUpdate"),
-        "requiresProfileUpdate":PWM_ADMIN.showString("Field_Report_RequiresProfileUpdate"),
-        "cacheTimestamp":PWM_ADMIN.showString("Field_Report_RecordCacheTime")
-    };
+    return [
+        {field:"username",label:PWM_ADMIN.showString("Field_Report_Username")},
+        {field:"userDN",label:PWM_ADMIN.showString("Field_Report_UserDN"),hidden:true},
+        {field:"ldapProfile",label:PWM_ADMIN.showString("Field_Report_LDAP_Profile"),hidden:true},
+        {field:"email",label:PWM_ADMIN.showString("Field_Report_Email"),hidden:true},
+        {field:"userGUID",label:PWM_ADMIN.showString("Field_Report_UserGuid"),hidden:true},
+        {field:"accountExpirationTime",label:PWM_ADMIN.showString("Field_Report_AccountExpireTime")},
+        {field:"passwordExpirationTime",label:PWM_ADMIN.showString("Field_Report_PwdExpireTime")},
+        {field:"passwordChangeTime",label:PWM_ADMIN.showString("Field_Report_PwdChangeTime")},
+        {field:"responseSetTime",label:PWM_ADMIN.showString("Field_Report_ResponseSaveTime")},
+        {field:"lastLoginTime",label:PWM_ADMIN.showString("Field_Report_LastLogin")},
+        {field:"hasResponses",label:PWM_ADMIN.showString("Field_Report_HasResponses")},
+        {field:"hasHelpdeskResponses",label:PWM_ADMIN.showString("Field_Report_HasHelpdeskResponses"),hidden:true},
+        {field:"responseStorageMethod",label:PWM_ADMIN.showString("Field_Report_ResponseStorageMethod"),hidden:true},
+        {field:"responseFormatType",label:PWM_ADMIN.showString("Field_Report_ResponseFormatType"),hidden:true},
+        {field:"passwordStatusExpired",label:PWM_ADMIN.showString("Field_Report_PwdExpired"),hidden:true},
+        {field:"passwordStatusPreExpired",label:PWM_ADMIN.showString("Field_Report_PwdPreExpired"),hidden:true},
+        {field:"passwordStatusViolatesPolicy",label:PWM_ADMIN.showString("Field_Report_PwdViolatesPolicy"),hidden:true},
+        {field:"passwordStatusWarnPeriod",label:PWM_ADMIN.showString("Field_Report_PwdWarnPeriod"),hidden:true},
+        {field:"requiresPasswordUpdate",label:PWM_ADMIN.showString("Field_Report_RequiresPasswordUpdate")},
+        {field:"requiresResponseUpdate",label:PWM_ADMIN.showString("Field_Report_RequiresResponseUpdate")},
+        {field:"requiresProfileUpdate",label:PWM_ADMIN.showString("Field_Report_RequiresProfileUpdate")},
+        {field:"cacheTimestamp",label:PWM_ADMIN.showString("Field_Report_RecordCacheTime"),hidden:true}
+    ];
 };
 };
 
 
 PWM_ADMIN.initReportDataGrid=function() {
 PWM_ADMIN.initReportDataGrid=function() {
@@ -153,20 +153,6 @@ PWM_ADMIN.initReportDataGrid=function() {
             // Now, create an instance of our custom grid
             // Now, create an instance of our custom grid
             PWM_VAR['reportGrid'] = new CustomGrid({columns: columnHeaders}, "grid");
             PWM_VAR['reportGrid'] = new CustomGrid({columns: columnHeaders}, "grid");
 
 
-            // unclick superfluous fields
-            PWM_MAIN.getObject('grid-hider-menu-check-cacheTimestamp').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-ldapProfile').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-email').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-userGUID').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-responseStorageMethod').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-responseFormatType').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-userDN').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-hasHelpdeskResponses').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-passwordStatusExpired').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-passwordStatusPreExpired').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-passwordStatusViolatesPolicy').click();
-            PWM_MAIN.getObject('grid-hider-menu-check-passwordStatusWarnPeriod').click();
-
             PWM_VAR['reportGrid'].on(".dgrid-row:click", function(evt){
             PWM_VAR['reportGrid'].on(".dgrid-row:click", function(evt){
                 PWM_ADMIN.detailView(evt, PWM_ADMIN.reportDataHeaders(), PWM_VAR['reportGrid']);
                 PWM_ADMIN.detailView(evt, PWM_ADMIN.reportDataHeaders(), PWM_VAR['reportGrid']);
             });
             });
@@ -280,36 +266,36 @@ PWM_ADMIN.reportAction=function(action) {
     confirmText = PWM_ADMIN.showString('Confirm_Report_' + action);
     confirmText = PWM_ADMIN.showString('Confirm_Report_' + action);
     actionText = PWM_ADMIN.showString('Display_Report_Action_' + action);
     actionText = PWM_ADMIN.showString('Display_Report_Action_' + action);
     PWM_MAIN.showConfirmDialog({text:confirmText,okAction:function(){
     PWM_MAIN.showConfirmDialog({text:confirmText,okAction:function(){
-        PWM_MAIN.showWaitDialog({title:PWM_MAIN.showString('Display_PleaseWait'),text:actionText,loadFunction:function(){
-            var url = PWM_GLOBAL['url-context'] + "/private/admin";
-            url = PWM_MAIN.addParamToUrl(url, 'processAction','reportCommand');
-            url = PWM_MAIN.addParamToUrl(url, 'command',action);
-            PWM_MAIN.ajaxRequest(url,function(){
-                setTimeout(function(){
-                    PWM_ADMIN.refreshReportDataStatus();
-                    PWM_ADMIN.refreshReportDataSummary();
-                    PWM_MAIN.closeWaitDialog();
-                },7500);
-            });
+            PWM_MAIN.showWaitDialog({title:PWM_MAIN.showString('Display_PleaseWait'),text:actionText,loadFunction:function(){
+                    var url = PWM_GLOBAL['url-context'] + "/private/admin";
+                    url = PWM_MAIN.addParamToUrl(url, 'processAction','reportCommand');
+                    url = PWM_MAIN.addParamToUrl(url, 'command',action);
+                    PWM_MAIN.ajaxRequest(url,function(){
+                        setTimeout(function(){
+                            PWM_ADMIN.refreshReportDataStatus();
+                            PWM_ADMIN.refreshReportDataSummary();
+                            PWM_MAIN.closeWaitDialog();
+                        },7500);
+                    });
+                }});
         }});
         }});
-    }});
 };
 };
 
 
 PWM_ADMIN.webSessionHeaders = function() {
 PWM_ADMIN.webSessionHeaders = function() {
-    return {
-        "userID":PWM_ADMIN.showString('Field_Session_UserID'),
-        "ldapProfile":PWM_ADMIN.showString('Field_Session_LdapProfile'),
-        "userDN":PWM_ADMIN.showString('Field_Session_UserDN'),
-        "createTime":PWM_ADMIN.showString('Field_Session_CreateTime'),
-        "lastTime":PWM_ADMIN.showString('Field_Session_LastTime'),
-        "label":PWM_ADMIN.showString('Field_Session_Label'),
-        "idle":PWM_ADMIN.showString('Field_Session_Idle'),
-        "locale":PWM_ADMIN.showString('Field_Session_Locale'),
-        "srcAddress":PWM_ADMIN.showString('Field_Session_SrcAddress'),
-        "srcHost":PWM_ADMIN.showString('Field_Session_SrcHost'),
-        "lastUrl":PWM_ADMIN.showString('Field_Session_LastURL'),
-        "intruderAttempts":PWM_ADMIN.showString('Field_Session_IntruderAttempts')
-    };
+    return [
+        {field:"userID",label:PWM_ADMIN.showString('Field_Session_UserID')},
+        {field:"ldapProfile",label:PWM_ADMIN.showString('Field_Session_LdapProfile')},
+        {field:"userDN",label:PWM_ADMIN.showString('Field_Session_UserDN'),hidden:true},
+        {field:"createTime",label:PWM_ADMIN.showString('Field_Session_CreateTime')},
+        {field:"lastTime",label:PWM_ADMIN.showString('Field_Session_LastTime')},
+        {field:"label",label:PWM_ADMIN.showString('Field_Session_Label')},
+        {field:"idle",label:PWM_ADMIN.showString('Field_Session_Idle')},
+        {field:"locale",label:PWM_ADMIN.showString('Field_Session_Locale'),hidden:true},
+        {field:"srcAddress",label:PWM_ADMIN.showString('Field_Session_SrcAddress')},
+        {field:"srcHost",label:PWM_ADMIN.showString('Field_Session_SrcHost'),hidden:true},
+        {field:"lastUrl",label:PWM_ADMIN.showString('Field_Session_LastURL'),hidden:true},
+        {field:"intruderAttempts",label:PWM_ADMIN.showString('Field_Session_IntruderAttempts'),hidden:true}
+    ];
 };
 };
 
 
 PWM_ADMIN.initActiveSessionGrid=function() {
 PWM_ADMIN.initActiveSessionGrid=function() {
@@ -327,14 +313,6 @@ PWM_ADMIN.initActiveSessionGrid=function() {
                 columns: columnHeaders
                 columns: columnHeaders
             }, "activeSessionGrid");
             }, "activeSessionGrid");
 
 
-            // unclick superfluous fields
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-label').click();
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-userDN').click();
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-srcHost').click();
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-locale').click();
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-lastUrl').click();
-            PWM_MAIN.getObject('activeSessionGrid-hider-menu-check-intruderAttempts').click();
-
             PWM_ADMIN.refreshActiveSessionGrid();
             PWM_ADMIN.refreshActiveSessionGrid();
 
 
             PWM_VAR['activeSessionsGrid'].on(".dgrid-row:click", function(evt){
             PWM_VAR['activeSessionsGrid'].on(".dgrid-row:click", function(evt){
@@ -358,12 +336,12 @@ PWM_ADMIN.refreshActiveSessionGrid=function() {
 };
 };
 
 
 PWM_ADMIN.intruderHeaders = function(){
 PWM_ADMIN.intruderHeaders = function(){
-    return {
-        "subject":PWM_ADMIN.showString('Field_Intruder_Subject'),
-        "timestamp":PWM_ADMIN.showString('Field_Intruder_Timestamp'),
-        "count":PWM_ADMIN.showString('Field_Intruder_Count'),
-        "status":PWM_ADMIN.showString('Field_Intruder_Status')
-    };
+    return [
+        {field:"subject",label:PWM_ADMIN.showString('Field_Intruder_Subject')},
+        {field:"timestamp",label:PWM_ADMIN.showString('Field_Intruder_Timestamp')},
+        {field:"count",label:PWM_ADMIN.showString('Field_Intruder_Count')},
+        {field:"status",label:PWM_ADMIN.showString('Field_Intruder_Status')}
+    ];
 };
 };
 
 
 
 
@@ -417,47 +395,55 @@ PWM_ADMIN.refreshIntruderGrid=function() {
 };
 };
 
 
 PWM_ADMIN.auditUserHeaders = function() {
 PWM_ADMIN.auditUserHeaders = function() {
-    return {
-        "timestamp": PWM_ADMIN.showString('Field_Audit_Timestamp'),
-        "perpetratorID": PWM_ADMIN.showString('Field_Audit_PerpetratorID'),
-        "perpetratorDN": PWM_ADMIN.showString('Field_Audit_PerpetratorDN'),
-        "perpetratorLdapProfile": PWM_ADMIN.showString('Field_Audit_PerpetratorLdapProfile'),
-        "eventCode": PWM_ADMIN.showString('Field_Audit_EventCode'),
-        "message": PWM_ADMIN.showString('Field_Audit_Message'),
-        "sourceAddress": PWM_ADMIN.showString('Field_Audit_SourceAddress'),
-        "sourceHost": PWM_ADMIN.showString('Field_Audit_SourceHost'),
-        "guid": PWM_ADMIN.showString('Field_Audit_GUID'),
-        "narrative": PWM_ADMIN.showString('Field_Audit_Narrative')
-    };
+    return [
+        {field:"timestamp",label:PWM_ADMIN.showString('Field_Audit_Timestamp')},
+        {field:"perpetratorID",label:PWM_ADMIN.showString('Field_Audit_PerpetratorID')},
+        {field:"perpetratorDN",label:PWM_ADMIN.showString('Field_Audit_PerpetratorDN'),hidden:true},
+        {field:"perpetratorLdapProfile",label:PWM_ADMIN.showString('Field_Audit_PerpetratorLdapProfile'),hidden:true},
+        {field:"eventCode",label:PWM_ADMIN.showString('Field_Audit_EventCode')},
+        {field:"message",label:PWM_ADMIN.showString('Field_Audit_Message'),hidden:true},
+        {field:"sourceAddress",label:PWM_ADMIN.showString('Field_Audit_SourceAddress')},
+        {field:"sourceHost",label:PWM_ADMIN.showString('Field_Audit_SourceHost'),hidden:true},
+        {field:"guid",label:PWM_ADMIN.showString('Field_Audit_GUID'),hidden:true},
+        {field:"narrative",label:PWM_ADMIN.showString('Field_Audit_Narrative')}
+    ];
 };
 };
 
 
 PWM_ADMIN.auditHelpdeskHeaders = function() {
 PWM_ADMIN.auditHelpdeskHeaders = function() {
-    return {
-        "timestamp": PWM_ADMIN.showString('Field_Audit_Timestamp'),
-        "perpetratorID": PWM_ADMIN.showString('Field_Audit_PerpetratorID'),
-        "perpetratorDN": PWM_ADMIN.showString('Field_Audit_PerpetratorDN'),
-        "perpetratorLdapProfile": PWM_ADMIN.showString('Field_Audit_PerpetratorLdapProfile'),
-        "eventCode": PWM_ADMIN.showString('Field_Audit_EventCode'),
-        "message": PWM_ADMIN.showString('Field_Audit_Message'),
-        "targetID": PWM_ADMIN.showString('Field_Audit_TargetID'),
-        "targetDN": PWM_ADMIN.showString('Field_Audit_TargetDN'),
-        "targetLdapProfile": PWM_ADMIN.showString('Field_Audit_TargetLdapProfile'),
-        "sourceAddress": PWM_ADMIN.showString('Field_Audit_SourceAddress'),
-        "sourceHost": PWM_ADMIN.showString('Field_Audit_SourceHost'),
-        "guid": PWM_ADMIN.showString('Field_Audit_GUID'),
-        "narrative": PWM_ADMIN.showString('Field_Audit_Narrative')
-    };
+    return [
+        {field:"timestamp",label:PWM_ADMIN.showString('Field_Audit_Timestamp')},
+        {field:"perpetratorID",label:PWM_ADMIN.showString('Field_Audit_PerpetratorID')},
+        {field:"perpetratorDN",label:PWM_ADMIN.showString('Field_Audit_PerpetratorDN'),hidden:true},
+        {field:"perpetratorLdapProfile",label:PWM_ADMIN.showString('Field_Audit_PerpetratorLdapProfile'),hidden:true},
+        {field:"eventCode",label:PWM_ADMIN.showString('Field_Audit_EventCode')},
+        {field:"message",label:PWM_ADMIN.showString('Field_Audit_Message'),hidden:true},
+        {field:"targetID",label:PWM_ADMIN.showString('Field_Audit_TargetID')},
+        {field:"targetDN",label:PWM_ADMIN.showString('Field_Audit_TargetDN')},
+        {field:"targetLdapProfile",label:PWM_ADMIN.showString('Field_Audit_TargetLdapProfile')},
+        {field:"sourceAddress",label:PWM_ADMIN.showString('Field_Audit_SourceAddress')},
+        {field:"sourceHost",label:PWM_ADMIN.showString('Field_Audit_SourceHost'),hidden:true},
+        {field:"guid",label:PWM_ADMIN.showString('Field_Audit_GUID'),hidden:true},
+        {field:"narrative",label:PWM_ADMIN.showString('Field_Audit_Narrative'),hidden:true}
+    ];
 };
 };
 
 
 PWM_ADMIN.auditSystemHeaders = function() {
 PWM_ADMIN.auditSystemHeaders = function() {
-    return {
-        "timestamp":PWM_ADMIN.showString('Field_Audit_Timestamp'),
-        "eventCode":PWM_ADMIN.showString('Field_Audit_EventCode'),
-        "message":PWM_ADMIN.showString('Field_Audit_Message'),
-        "instance":PWM_ADMIN.showString('Field_Audit_Instance'),
-        "guid":PWM_ADMIN.showString('Field_Audit_GUID'),
-        "narrative":PWM_ADMIN.showString('Field_Audit_Narrative')
-    };
+    return [
+        {field:"timestamp",label:PWM_ADMIN.showString('Field_Audit_Timestamp')},
+        {field:"eventCode",label:PWM_ADMIN.showString('Field_Audit_EventCode')},
+        {field:"message",label:PWM_ADMIN.showString('Field_Audit_Message')},
+        {field:"instance",label:PWM_ADMIN.showString('Field_Audit_Instance'),hidden:true},
+        {field:"guid",label:PWM_ADMIN.showString('Field_Audit_GUID'),hidden:true},
+        {field:"narrative",label:PWM_ADMIN.showString('Field_Audit_Narrative'),hidden:true}
+    ];
+};
+
+PWM_ADMIN.makeGrid = function() {
+    require(["dojo","dojo/_base/declare", "dgrid/Grid", "dgrid/Keyboard", "dgrid/Selection", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnHider", "dgrid/extensions/DijitRegistry"],
+        function(dojo, declare, Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry){
+            return declare([ Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry ]);
+        }
+    );
 };
 };
 
 
 PWM_ADMIN.initAuditGrid=function() {
 PWM_ADMIN.initAuditGrid=function() {
@@ -471,27 +457,9 @@ PWM_ADMIN.initAuditGrid=function() {
             PWM_VAR['auditSystemGrid'] = new CustomGrid({columns: PWM_ADMIN.auditSystemHeaders()}, "auditSystemGrid");
             PWM_VAR['auditSystemGrid'] = new CustomGrid({columns: PWM_ADMIN.auditSystemHeaders()}, "auditSystemGrid");
             PWM_VAR['auditHelpdeskGrid'] = new CustomGrid({columns: PWM_ADMIN.auditHelpdeskHeaders()}, "auditHelpdeskGrid");
             PWM_VAR['auditHelpdeskGrid'] = new CustomGrid({columns: PWM_ADMIN.auditHelpdeskHeaders()}, "auditHelpdeskGrid");
 
 
-            // unclick superfluous fields
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-perpetratorDN').click();
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-perpetratorLdapProfile').click();
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-message').click();
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-sourceHost').click();
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-guid').click();
-            PWM_MAIN.getObject('auditUserGrid-hider-menu-check-narrative').click();
-
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-perpetratorDN').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-perpetratorLdapProfile').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-message').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-targetDN').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-targetLdapProfile').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-sourceHost').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-guid').click();
-            PWM_MAIN.getObject('auditHelpdeskGrid-hider-menu-check-narrative').click();
-
-            PWM_MAIN.getObject('auditSystemGrid-hider-menu-check-instance').click();
-            PWM_MAIN.getObject('auditSystemGrid-hider-menu-check-guid').click();
-            PWM_MAIN.getObject('auditSystemGrid-hider-menu-check-narrative').click();
-            PWM_ADMIN.refreshAuditGridData();
+            PWM_ADMIN.refreshAuditGridData(undefined,'USER');
+            PWM_ADMIN.refreshAuditGridData(undefined,'HELPDESK');
+            PWM_ADMIN.refreshAuditGridData(undefined,'SYSTEM');
 
 
             PWM_VAR['auditUserGrid'].on(".dgrid-row:click", function(evt){
             PWM_VAR['auditUserGrid'].on(".dgrid-row:click", function(evt){
                 PWM_ADMIN.detailView(evt, PWM_ADMIN.auditUserHeaders(), PWM_VAR['auditUserGrid']);
                 PWM_ADMIN.detailView(evt, PWM_ADMIN.auditUserHeaders(), PWM_VAR['auditUserGrid']);
@@ -505,28 +473,32 @@ PWM_ADMIN.initAuditGrid=function() {
         });
         });
 };
 };
 
 
-PWM_ADMIN.refreshAuditGridData=function(maximum) {
-    PWM_VAR['auditUserGrid'].refresh();
-    PWM_VAR['auditHelpdeskGrid'].refresh();
-    PWM_VAR['auditSystemGrid'].refresh();
-    if (!maximum) {
-        maximum = 1000;
+PWM_ADMIN.refreshAuditGridData=function(maximum,type) {
+    switch (type) {
+        case 'USER':
+            var grid = PWM_VAR['auditUserGrid'];
+            break;
+
+        case 'HELPDESK':
+            var grid = PWM_VAR['auditHelpdeskGrid'];
+            break;
+
+        case 'SYSTEM':
+            var grid = PWM_VAR['auditSystemGrid'];
+            break;
     }
     }
-    var url = PWM_MAIN.addParamToUrl(window.location.href,"processAction", "auditData");
-    url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
-    var loadFunction = function(data) {
-        PWM_VAR['auditUserGrid'].renderArray(data['data']['user']);
-        PWM_VAR['auditUserGrid'].set("sort", { attribute : 'timestamp', ascending: false, descending: true });
-        PWM_VAR['auditUserGrid'].resize();
 
 
-        PWM_VAR['auditHelpdeskGrid'].renderArray(data['data']['helpdesk']);
-        PWM_VAR['auditHelpdeskGrid'].set("sort", { attribute : 'timestamp', ascending: false, descending: true });
-        PWM_VAR['auditHelpdeskGrid'].resize();
+    grid.refresh();
 
 
-        PWM_VAR['auditSystemGrid'].renderArray(data['data']['system']);
-        PWM_VAR['auditSystemGrid'].set("sort", { attribute : 'timestamp', ascending: false, descending: true });
-        PWM_VAR['auditSystemGrid'].resize();
+    if (!maximum) {
+        maximum = 100;
+    }
 
 
+    var url = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "auditData");
+    url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
+    url = PWM_MAIN.addParamToUrl(url,'type',type);
+    var loadFunction = function(data) {
+        grid.renderArray(data['data']['records']);
     };
     };
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
 };
 };
@@ -768,8 +740,9 @@ PWM_ADMIN.detailView = function(evt, headers, grid){
     var postExecuteFunctions = [];
     var postExecuteFunctions = [];
     for (var item in headers) {
     for (var item in headers) {
         (function(key){
         (function(key){
-            var value = key in row.data ? row.data[key] : '';
-            var label = headers[key];
+            var field = headers[key]['field'];
+            var label = headers[key]['label'];
+            var value = field in row.data ? row.data[field] : '';
             var id = "record-detail-" + key;
             var id = "record-detail-" + key;
             text += '<tr><td class="key">' + label + '</td>';
             text += '<tr><td class="key">' + label + '</td>';
             text += '<td><span id="' + id + '" style="max-height: 200px; overflow: auto; max-width: 400px" class="timestamp">';
             text += '<td><span id="' + id + '" style="max-height: 200px; overflow: auto; max-width: 400px" class="timestamp">';
@@ -788,10 +761,10 @@ PWM_ADMIN.detailView = function(evt, headers, grid){
     }
     }
     text += '</table>';
     text += '</table>';
     PWM_MAIN.showDialog({title:"Record Detail",text:text,showClose:true,allowMove:true,loadFunction:function(){
     PWM_MAIN.showDialog({title:"Record Detail",text:text,showClose:true,allowMove:true,loadFunction:function(){
-        for (var i = 0; i < postExecuteFunctions.length; i++) {
-            postExecuteFunctions[i]();
-        }
-    }});
+            for (var i = 0; i < postExecuteFunctions.length; i++) {
+                postExecuteFunctions[i]();
+            }
+        }});
 };
 };
 
 
 PWM_ADMIN.showString=function (key, options) {
 PWM_ADMIN.showString=function (key, options) {

+ 97 - 0
server/src/main/webapp/public/resources/style.css

@@ -1525,6 +1525,9 @@ html[dir="rtl"] .message.message-error .errorDetail {
     white-space: nowrap;
     white-space: nowrap;
 }
 }
 
 
+/*** TABS ****/
+
+
 /*Change these values for the tab highlight color:*/
 /*Change these values for the tab highlight color:*/
 .tab-container > .label:hover {
 .tab-container > .label:hover {
     color: #2D2D2D;
     color: #2D2D2D;
@@ -1532,3 +1535,97 @@ html[dir="rtl"] .message.message-error .errorDetail {
     border-left-color: #2D2D2D;
     border-left-color: #2D2D2D;
     border-right-color: #2D2D2D;
     border-right-color: #2D2D2D;
 }
 }
+
+
+.tab-container * {
+    box-sizing: border-box;
+}
+
+.tab-container {
+    display: flex;
+    flex-wrap: wrap;
+    position: relative;
+}
+
+.input {
+    position: absolute;
+    opacity: 0;
+}
+
+.tab-container > .label {
+    background: #f6f9f8;
+    border: 1px solid #dae1e1;
+    border-bottom: transparent;
+    border-radius: 4px 4px 0 0;
+    color: #7f7f7f;
+    cursor: pointer;
+    font-size: 15px;
+    height: 31px;
+    margin-left: 5px;
+    padding: 6px 12px;
+    transition: background 0.1s, color 0.1s;
+    width: 100%;
+}
+
+.tab-container > .label:active {
+    /*background: #ccc;*/
+}
+
+.tab-container > .input:focus + .label {
+    z-index: 1;
+}
+
+.tab-container > .input:checked + .label {
+    background: #fff;
+    border: 1px solid #6a6f71;
+    border-bottom-color: transparent;
+    color: #000;
+    position: relative;
+    z-index: 100;
+}
+
+.tab-container > .input:checked + .label::after {
+    content: "";
+    background: #fff;
+    bottom: -3px;
+    height: 3px;
+    left: 0;
+    position: absolute;
+    right: 0;
+}
+
+@media (min-width: 600px) {
+    .tab-container > .label {
+        width: auto;
+    }
+}
+
+.tab-content-pane {
+    background: #fff;
+    display: none;
+    padding: 20px 30px 30px;
+    width: 100%;
+}
+
+@media (min-width: 600px) {
+    .tab-content-pane {
+        order: 99;
+    }
+}
+
+.input:checked + .label + .tab-content-pane {
+    display: block;
+}
+
+.tab-container > .tab-end {
+    border-bottom: 1px solid #6a6f71;
+    left: 0;
+    width: 100%;
+}
+
+/*This targets only IE*/
+@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
+    .tab-container > .tab-end {
+        height: 7px;
+    }
+}

+ 0 - 114
server/src/main/webapp/public/resources/tab-container.css

@@ -1,114 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2018 The PWM Project
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-.tab-container * {
-    box-sizing: border-box;
-}
-
-.tab-container {
-    display: flex;
-    flex-wrap: wrap;
-    position: relative;
-}
-
-.input {
-    position: absolute;
-    opacity: 0;
-}
-
-.tab-container > .label {
-    background: #f6f9f8;
-    border: 1px solid #dae1e1;
-    border-bottom: transparent;
-    border-radius: 4px 4px 0 0;
-    color: #7f7f7f;
-    cursor: pointer;
-    font-size: 15px;
-    height: 31px;
-    margin-left: 5px;
-    padding: 6px 12px;
-    transition: background 0.1s, color 0.1s;
-    width: 100%;
-}
-
-.tab-container > .label:active {
-    /*background: #ccc;*/
-}
-
-.tab-container > .input:focus + .label {
-    z-index: 1;
-}
-
-.tab-container > .input:checked + .label {
-    background: #fff;
-    border: 1px solid #6a6f71;
-    border-bottom-color: transparent;
-    color: #000;
-    position: relative;
-    z-index: 100;
-}
-
-.tab-container > .input:checked + .label::after {
-    content: "";
-    background: #fff;
-    bottom: -3px;
-    height: 3px;
-    left: 0;
-    position: absolute;
-    right: 0;
-}
-
-@media (min-width: 600px) {
-    .tab-container > .label {
-        width: auto;
-    }
-}
-
-.tab-content-pane {
-    background: #fff;
-    display: none;
-    padding: 20px 30px 30px;
-    width: 100%;
-}
-
-@media (min-width: 600px) {
-    .tab-content-pane {
-        order: 99;
-    }
-}
-
-.input:checked + .label + .tab-content-pane {
-    display: block;
-}
-
-.tab-container > .tab-end {
-    border-bottom: 1px solid #6a6f71;
-    left: 0;
-    width: 100%;
-}
-
-/*This targets only IE*/
-@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
-    .tab-container > .tab-end {
-        height: 7px;
-    }
-}

+ 23 - 0
server/src/main/webapp/public/resources/themes/pwm/style.css

@@ -164,3 +164,26 @@ h3 {
     border: 1px solid transparent;
     border: 1px solid transparent;
     box-shadow: 0 0 0 0 white, 0 0 0 0 white, 9px 0 12px -4px #B2B1B9, -9px 0 12px -4px #B2B1B9;
     box-shadow: 0 0 0 0 white, 0 0 0 0 white, 9px 0 12px -4px #B2B1B9, -9px 0 12px -4px #B2B1B9;
 }
 }
+
+.tab-container > .tab-end {
+    border-bottom: 1px solid #E8E1F6;
+}
+
+.tab-container > .input:checked + .label {
+    border: 1px solid #E8E1F6;
+    color: #808080;
+}
+
+.tab-container > .label {
+    font-size: 14px;
+    height: 25px;
+    padding-top: 3px;
+}
+
+.tab-container > .label:hover {
+    color: #808080;
+    border-top-color: #E8E1F6;
+    border-left-color: #E8E1F6;
+    border-right-color: #E8E1F6;
+}
+