keycloak-developers

KEYCLAOK-7170 device activity component (#5169) * KEYCLOAK-7170:

4/25/2018 4:04:56 PM

Details

diff --git a/themes/src/main/resources/theme/base/account/messages/messages_en.properties b/themes/src/main/resources/theme/base/account/messages/messages_en.properties
index ec7852f..43c4a69 100755
--- a/themes/src/main/resources/theme/base/account/messages/messages_en.properties
+++ b/themes/src/main/resources/theme/base/account/messages/messages_en.properties
@@ -98,6 +98,7 @@ applications=Applications
 account=Account
 federatedIdentity=Federated Identity
 authenticator=Authenticator
+device-activity=Device Activity
 sessions=Sessions
 log=Log
 
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
index 02dc9df..2755da1 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
+++ b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
@@ -189,7 +189,7 @@
                             <hr/>
                             <h3><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
                             <hr/>
-                            <h3><a href="${baseUrl}/#/sessions">${msg("deviceActivityHtmlTitle")}</a></h3>
+                            <h3><a href="${baseUrl}/#/device-activity">${msg("deviceActivityHtmlTitle")}</a></h3>
                             <hr/>
                             <h3><a href="${baseUrl}/#/account">${msg("federatedIdentity")}</a></h3>
                         </div>
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts
index f11cdaf..792c48a 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts
@@ -28,6 +28,7 @@ export const routes: Routes = [
             { path: 'account', loadChildren: resourceUrl + '/app/content/account-page/account.module.js#AccountModule' },
             { path: 'password', loadChildren: resourceUrl + '/app/content/password-page/password.module.js#PasswordModule' },
             { path: 'authenticator', loadChildren: resourceUrl + '/app/content/authenticator-page/authenticator.module.js#AuthenticatorModule' },
+            { path: 'device-activity', loadChildren: resourceUrl + '/app/content/device-activity-page/device-activity.module.js#DeviceActivityModule' },
             { path: 'sessions', loadChildren: resourceUrl + '/app/content/sessions-page/sessions.module.js#SessionsModule' },
             { path: 'applications', loadChildren: resourceUrl + '/app/content/applications-page/applications.module.js#ApplicationsModule' },
             { path: ':**', loadChildren: resourceUrl + '/app/content/page-not-found/page-not-found.module.js#PageNotFoundModule' },
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity.module.ts
new file mode 100644
index 0000000..8c2f463
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity.module.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import { DeviceActivityPageComponent } from './device-activity-page.component';
+import { DeviceActivityRoutingModule } from './device-activity-routing.module';
+
+@NgModule({
+  imports:      [ CommonModule, FormsModule, TranslateModule, DeviceActivityRoutingModule ],
+  declarations: [ DeviceActivityPageComponent ],
+  providers:    [ ]
+})
+export class DeviceActivityModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.css b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.css
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.html b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.html
new file mode 100644
index 0000000..026c471
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.html
@@ -0,0 +1,219 @@
+<div class="page-header">
+  <h1>{{'deviceActivityHtmlTitle' | translate}}</h1>
+</div>
+
+<div class="row row-cards-pf">
+  <div class="col-md-12">
+    <div class="card-pf card-pf-utilization" style="">
+      <div>
+        <button class="btn btn-default pull-right" type="button" data-toggle="modal" data-target="#myModal">Log Out All Devices</button>
+        <h2 class="card-pf-title" style="">
+          Signed In Devices
+        </h2>
+        <p class="detail-description">You can find devices that have logged into your account from the list. Log out any of them if the device is unfamiliar or logged in wrong place and time.</p>
+
+      </div>
+      <div class="card-pf-body" style="">
+        <div class="row">
+         <div class="container-fluid">
+          <div id="pf-list-simple-expansion" class="list-group list-view-pf list-view-pf-view">
+            <div class="list-group-item">
+              <div class="list-group-item-header">
+                <div class="list-view-pf-expand">
+                  <span class="fa fa-angle-right"></span>
+                </div>
+
+                <div class="list-view-pf-main-info">
+                  <div class="list-view-pf-left">
+                    <span class="fa fa-desktop list-view-pf-icon-sm"></span>
+                  </div>
+                  <div class="list-view-pf-body">
+                    <div class="list-view-pf-description">
+                      <div class="list-group-item-heading">
+                        Asus A3G
+                      </div>
+                      <div class="list-group-item-text current-color">
+                        Current device
+                      </div>
+                    </div>
+
+                  </div>
+                </div>
+              </div>
+              <div class="list-group-item-container container-fluid hidden">
+                <div class="close">
+                  <span class="pficon pficon-close"></span>
+                </div>
+
+                <div id="utilizationDonutChart11" class="example-donut-chart-utilization"></div>
+                <div class="activity-item">
+                  <ul>
+                    <li><h3><i class="fa fa-firefox"></i> Firefox on OS X 10.11</h3></li>
+                    <li><b>Last accessed in</b> Dalian, China (219.147.95.224) <b>on</b> January 8, 17:33:52</li>
+                    <li><b>Clients</b> security-admin-console, account</li>
+                    <li><span><b>Started at</b> January 8, 3:25:38</span> <span class="m-l"><b>Expires at</b> January 9, 3:25:37</span></li>
+                  </ul>
+
+                  <!-- Button trigger modal -->
+                  <button type="button" class="btn btn-default btn-logout" data-toggle="modal" data-target="#myModal">Log Out</button>
+                  <!-- End Button trigger modal -->
+                </div>
+
+                <div class="activity-item">
+                  <ul>
+                    <li><h3><i class="fa fa-chrome"></i> Chrome on OS X 10.11.6</h3></li>
+                    <li><b>Last accessed in</b> Dalian, China (219.147.95.224) <b>on</b> January 8, 17:33:52</li>
+                    <li><b>Clients</b> security-admin-console, account</li>
+                    <li><span><b>Started at</b> January 8, 3:25:38</span> <span class="m-l"><b>Expires at</b> January 9, 3:25:37</span></li>
+                  </ul>
+                  <button class="btn btn-default btn-logout">Log Out</button>
+                </div>
+              </div>
+            </div>
+            <div class="list-group-item">
+              <div class="list-group-item-header">
+                <div class="list-view-pf-expand">
+                  <span class="fa fa-angle-right"></span>
+                </div>
+
+                <div class="list-view-pf-main-info">
+                  <div class="list-view-pf-left">
+                    <span class="fa fa-mobile list-view-pf-icon-sm"></span>
+                  </div>
+                  <div class="list-view-pf-body">
+                    <div class="list-view-pf-description">
+                      <div class="list-group-item-heading">
+                        Asus A3G
+                      </div>
+                      <div class="list-group-item-text">
+                        <b>Last Access</b>
+                        <span>Raleigh, US - January 8, 17:33:52</span>
+                      </div>
+                    </div>
+
+                  </div>
+                </div>
+              </div>
+              <div class="list-group-item-container container-fluid hidden">
+                <div class="close">
+                  <span class="pficon pficon-close"></span>
+                </div>
+                <div class="activity-item">
+                  <ul>
+                    <li><h3><i class="fa fa-firefox"></i> Firefox on OS X 10.11</h3></li>
+                    <li><b>Last accessed in</b> Dalian, China (219.147.95.224) <b>on</b> January 8, 17:33:52</li>
+                    <li><b>Clients</b> security-admin-console, account</li>
+                    <li><span><b>Started at</b> January 8, 3:25:38</span> <span class="m-l"><b>Expires at</b> January 9, 3:25:37</span></li>
+                  </ul>
+                  <button class="btn btn-default btn-logout">Log Out</button>
+                </div>
+              </div>
+            </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="card-pf card-pf-utilization" style="">
+      <div>
+        <h2 class="card-pf-title" style="">
+          Recently Used Devices
+        </h2>
+        <p class="detail-description">You can find devices that you used in the last month, but they have not logged into your account anymore.</p>
+
+      </div>
+      <div class="card-pf-body" style="">
+        <div class="row">
+         <div class="container-fluid">
+
+           <div id="pf-list-simple-expansion" class="list-group list-view-pf list-view-pf-view">
+
+            <div class="list-group-item">
+              <div class="list-group-item-header">
+                <div class="list-view-pf-expand">
+                  <span class="fa fa-angle-right"></span>
+                </div>
+
+                <div class="list-view-pf-main-info">
+                  <div class="list-view-pf-left">
+                    <span class="fa fa-mobile list-view-pf-icon-sm"></span>
+                  </div>
+                  <div class="list-view-pf-body">
+                    <div class="list-view-pf-description">
+                      <div class="list-group-item-heading">
+                        Asus A3G
+                      </div>
+                      <div class="list-group-item-text">
+                        <b>Last Access</b>
+                        <span>Raleigh, US - January 8, 17:33:52</span>
+                      </div>
+                    </div>
+
+                  </div>
+                </div>
+              </div>
+              <div class="list-group-item-container container-fluid hidden">
+                <div class="close">
+                  <span class="pficon pficon-close"></span>
+                </div>
+                <div class="activity-item">
+                  <ul>
+                    <li><h3><i class="fa fa-firefox"></i> Firefox on OS X 10.11</h3></li>
+                    <li><b>Last accessed in</b> Dalian, China (219.147.95.224) <b>on</b> January 8, 17:33:52</li>
+                  </ul>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        </div>
+
+      </div>
+    </div>
+
+  </div>
+</div>
+
+<!-- Modal -->
+    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+      <div class="modal-dialog" role="document">
+        <div class="modal-content">
+          <div class="modal-header">
+            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+            <h4 class="modal-title" id="myModalLabel">Log Out All Devices</h4>
+          </div>
+          <div class="modal-body">
+            Logging Out All Devices will log out all the devices that have signed in to your account, including the current device you are using.
+          </div>
+          <div class="modal-footer">
+            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+            <button type="button" class="btn btn-primary">Log Out</button>
+          </div>
+        </div>
+      </div>
+    </div>
+<!-- End Modal -->
+
+
+<script>
+$(document).ready(function () {
+  // click the list-view heading then expand a row
+  $("#pf-list-simple-expansion .list-group-item-header").click(function(event){
+    if(!$(event.target).is("button, a, input, .fa-ellipsis-v")){
+      $(this).find(".fa-angle-right").toggleClass("fa-angle-down")
+      .end().parent().toggleClass("list-view-pf-expand-active")
+      .find(".list-group-item-container").toggleClass("hidden");
+    } else {
+    }
+  })
+
+  // click the close button, hide the expand row and remove the active status
+  $("#pf-list-simple-expansion .list-group-item-container .close").on("click", function (){
+    $(this).parent().addClass("hidden")
+    .parent().removeClass("list-view-pf-expand-active")
+    .find(".fa-angle-right").removeClass("fa-angle-down");
+  })
+
+});
+</script>
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.ts
new file mode 100644
index 0000000..0ecf6f1
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-page.component.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {Response} from '@angular/http';
+import {FormGroup} from '@angular/forms';
+
+import {AccountServiceClient} from '../../account-service/account.service';
+
+@Component({
+    selector: 'app-device-activity-page',
+    templateUrl: './device-activity-page.component.html',
+    styleUrls: ['./device-activity-page.component.css']
+})
+export class DeviceActivityPageComponent implements OnInit {
+
+    @ViewChild('formGroup') private formGroup: FormGroup;
+    
+    constructor(private accountSvc: AccountServiceClient) {
+    }
+    
+    public deviceActivity() {
+        console.log("posting: " + JSON.stringify(this.formGroup.value));
+        this.accountSvc.doPostRequest("/device-activity", (res: Response) => this.handlePostResponse(res), this.formGroup.value);
+    }
+    
+    protected handlePostResponse(res: Response) {
+      console.log('**** response from account POST ***');
+      console.log(JSON.stringify(res));
+      console.log('***************************************');
+    }
+
+    ngOnInit() {
+    }
+}
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-routing.module.ts
new file mode 100644
index 0000000..24a689b
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/device-activity-page/device-activity-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { DeviceActivityPageComponent } from './device-activity-page.component';
+
+const routes: Routes = [
+    { path: '**', component: DeviceActivityPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class DeviceActivityRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/side-nav/side-nav.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/side-nav/side-nav.component.ts
index 60d2548..df0577c 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/side-nav/side-nav.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/side-nav/side-nav.component.ts
@@ -47,6 +47,7 @@ export class SideNavComponent implements OnInit, MenuClickListener {
             this.makeSideNavItem("account", new Icon("pficon", "user"), "active"),
             this.makeSideNavItem("password", new Icon("pficon", "key")),
             this.makeSideNavItem("authenticator", new Icon("pficon", "cloud-security")),
+            this.makeSideNavItem("device-activity", new Icon("fa", "desktop")),
             this.makeSideNavItem("sessions", new Icon("fa", "clock-o")),
             this.makeSideNavItem("applications", new Icon("fa", "th"))
         ];
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css b/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
index 0c85b5f..2f212bd 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
@@ -1,52 +1,86 @@
-/* Welcome Page */
-
-body {
-  background: #f5f5f5;
-}
-
-p.description {
-  font-size: 14px;
-  margin: 10px auto 20px;
-  max-width: 60%;
-  padding: 0 10px;
-  text-align: center;
-}
-
-.btn-sign {
-  margin-top: 10px;
-}
-
-.layout-pf-alt.layout-pf-alt-fixed .container-pf-alt-nav-pf-vertical-alt {
-    margin-left: 210px;
-}
-
-.nav .nav-item-iconic {
-  color: #d1d1d1;
-}
-
-.content-area {
-  padding: 30px 30px 20px;
-  background: #ffffff;
-  font-size: 13px;
-  margin-bottom: 10px;
-}
-
-/* personal Info Style */
-.subtitle {
-  color: #4d5258;
-  font-size: 12px;
-}
-
-.content-area .required{
-  color: #cc0000;
-}
-
-.page-header {
-  border-bottom: 0;
-}
-
-
-/* Introduction Message on the left */
-.introMessage {
-    margin: 10px 20px 20px 0;
-}
+/* Welcome Page */
+
+body {
+  background: #f5f5f5;
+}
+
+p.description {
+  font-size: 14px;
+  margin: 10px auto 20px;
+  max-width: 60%;
+  padding: 0 10px;
+  text-align: center;
+}
+
+.btn-sign {
+  margin-top: 10px;
+}
+
+.layout-pf-alt.layout-pf-alt-fixed .container-pf-alt-nav-pf-vertical-alt {
+    margin-left: 210px;
+}
+
+.nav .nav-item-iconic {
+  color: #d1d1d1;
+}
+
+.content-area {
+  padding: 30px 30px 20px;
+  background: #ffffff;
+  font-size: 13px;
+  margin-bottom: 10px;
+}
+
+/* personal Info Style */
+.subtitle {
+  color: #4d5258;
+  font-size: 12px;
+}
+
+.content-area .required{
+  color: #cc0000;
+}
+
+.page-header {
+  border-bottom: 0;
+}
+
+
+/* Introduction Message on the left */
+.introMessage {
+    margin: 10px 20px 20px 0;
+    
+/* Device Activity */
+.card-title{
+	margin-left: 20px;
+	margin-bottom: 30px;
+}
+.detail-description{
+	margin-top:-10px;
+}
+.list-view-pf-view {
+	margin-top: 0;
+}
+.m-l{
+	margin-left: 20px;
+}
+.activity-item {
+	padding-left: 60px;
+}
+.activity-item ul{
+	list-style: none;
+}
+.activity-item h3 .fa{
+	margin-left: -30px;
+	margin-right: 5px;
+	font-size: 20px;
+}
+.btn-logout{
+	margin-left: 40px;
+	margin-bottom: 20px;
+	margin-top: 5px;
+}
+.list-view-pf .current-color{
+	font-weight: bold;
+	color: #4F9207!important;
+}