KEYCLAOK-7170 device activity component (#5169)
* KEYCLOAK-7170: Create Device Activity Page * KEYCLOAK-7170: Create Device Activity Page * Fixes KEYCLOAK-7205 - Device activity - update HTML
This commit is contained in:
parent
35154db50f
commit
5a56a822b0
10 changed files with 422 additions and 53 deletions
|
@ -98,6 +98,7 @@ applications=Applications
|
||||||
account=Account
|
account=Account
|
||||||
federatedIdentity=Federated Identity
|
federatedIdentity=Federated Identity
|
||||||
authenticator=Authenticator
|
authenticator=Authenticator
|
||||||
|
device-activity=Device Activity
|
||||||
sessions=Sessions
|
sessions=Sessions
|
||||||
log=Log
|
log=Log
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
<h3><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
|
<h3><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
|
||||||
<hr/>
|
<hr/>
|
||||||
<h3><a href="${baseUrl}/#/sessions">${msg("deviceActivityHtmlTitle")}</a></h3>
|
<h3><a href="${baseUrl}/#/device-activity">${msg("deviceActivityHtmlTitle")}</a></h3>
|
||||||
<hr/>
|
<hr/>
|
||||||
<h3><a href="${baseUrl}/#/account">${msg("federatedIdentity")}</a></h3>
|
<h3><a href="${baseUrl}/#/account">${msg("federatedIdentity")}</a></h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,6 +28,7 @@ export const routes: Routes = [
|
||||||
{ path: 'account', loadChildren: resourceUrl + '/app/content/account-page/account.module.js#AccountModule' },
|
{ 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: 'password', loadChildren: resourceUrl + '/app/content/password-page/password.module.js#PasswordModule' },
|
||||||
{ path: 'authenticator', loadChildren: resourceUrl + '/app/content/authenticator-page/authenticator.module.js#AuthenticatorModule' },
|
{ 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: 'sessions', loadChildren: resourceUrl + '/app/content/sessions-page/sessions.module.js#SessionsModule' },
|
||||||
{ path: 'applications', loadChildren: resourceUrl + '/app/content/applications-page/applications.module.js#ApplicationsModule' },
|
{ 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' },
|
{ path: ':**', loadChildren: resourceUrl + '/app/content/page-not-found/page-not-found.module.js#PageNotFoundModule' },
|
||||||
|
|
|
@ -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">×</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>
|
|
@ -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() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {}
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ export class SideNavComponent implements OnInit, MenuClickListener {
|
||||||
this.makeSideNavItem("account", new Icon("pficon", "user"), "active"),
|
this.makeSideNavItem("account", new Icon("pficon", "user"), "active"),
|
||||||
this.makeSideNavItem("password", new Icon("pficon", "key")),
|
this.makeSideNavItem("password", new Icon("pficon", "key")),
|
||||||
this.makeSideNavItem("authenticator", new Icon("pficon", "cloud-security")),
|
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("sessions", new Icon("fa", "clock-o")),
|
||||||
this.makeSideNavItem("applications", new Icon("fa", "th"))
|
this.makeSideNavItem("applications", new Icon("fa", "th"))
|
||||||
];
|
];
|
||||||
|
|
|
@ -49,4 +49,38 @@ p.description {
|
||||||
/* Introduction Message on the left */
|
/* Introduction Message on the left */
|
||||||
.introMessage {
|
.introMessage {
|
||||||
margin: 10px 20px 20px 0;
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue