KEYCLOAK-11539: Rewrite Device Activity page
This commit is contained in:
parent
9a93e5028c
commit
787386fc21
2 changed files with 20 additions and 116 deletions
|
@ -26,8 +26,6 @@ import {
|
|||
DataListItem,
|
||||
DataListItemRow,
|
||||
DataListCell,
|
||||
DataListToggle,
|
||||
DataListContent,
|
||||
DataListItemCells,
|
||||
Grid,
|
||||
GridItem,
|
||||
|
@ -44,11 +42,8 @@ import {
|
|||
FirefoxIcon,
|
||||
GlobeIcon,
|
||||
InternetExplorerIcon,
|
||||
LaptopIcon,
|
||||
MobileAltIcon,
|
||||
OperaIcon,
|
||||
SafariIcon,
|
||||
TabletAltIcon,
|
||||
YandexInternationalIcon,
|
||||
} from '@patternfly/react-icons';
|
||||
|
||||
|
@ -64,7 +59,6 @@ export interface DeviceActivityPageProps {
|
|||
}
|
||||
|
||||
export interface DeviceActivityPageState {
|
||||
isRowOpen: boolean[];
|
||||
devices: Device[];
|
||||
}
|
||||
|
||||
|
@ -98,7 +92,6 @@ interface Client {
|
|||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2019 Red Hat Inc.
|
||||
*
|
||||
*/
|
||||
export class DeviceActivityPage extends React.Component<DeviceActivityPageProps, DeviceActivityPageState> {
|
||||
|
||||
|
@ -106,19 +99,12 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
isRowOpen: [],
|
||||
devices: []
|
||||
};
|
||||
|
||||
this.fetchDevices();
|
||||
}
|
||||
|
||||
private onToggle = (row: number): void => {
|
||||
const newIsRowOpen: boolean[] = this.state.isRowOpen;
|
||||
newIsRowOpen[row] = !newIsRowOpen[row];
|
||||
this.setState({isRowOpen: newIsRowOpen});
|
||||
};
|
||||
|
||||
private signOutAll = () => {
|
||||
AccountServiceClient.Instance.doDelete("/sessions")
|
||||
.then( (response: AxiosResponse<Object>) => {
|
||||
|
@ -135,8 +121,6 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
}
|
||||
|
||||
private fetchDevices(): void {
|
||||
const sessionsOnOpenRow: string[] = this.findSessionsOnOpenRow();
|
||||
|
||||
AccountServiceClient.Instance.doGet("/sessions/devices")
|
||||
.then((response: AxiosResponse<Object>) => {
|
||||
console.log({response});
|
||||
|
@ -145,43 +129,12 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
devices = this.moveCurrentToTop(devices);
|
||||
|
||||
this.setState({
|
||||
isRowOpen: this.openRows(devices, sessionsOnOpenRow),
|
||||
devices: devices
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// calculating open rows this way assures that when a session is signed out
|
||||
// or on refresh, the open rows stay open
|
||||
private findSessionsOnOpenRow() : string[] {
|
||||
let sessionsOnOpenRow: string[] = [];
|
||||
|
||||
this.state.devices.forEach( (device: Device, index: number) => {
|
||||
if (this.state.isRowOpen[index]) {
|
||||
device.sessions.forEach( (session: Session) => {
|
||||
sessionsOnOpenRow.push(session.id);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
return sessionsOnOpenRow;
|
||||
}
|
||||
|
||||
private openRows(devices: Device[], sessionsOnOpenRow: string[]): boolean[] {
|
||||
const openRows: boolean[] = new Array<boolean>().fill(false);
|
||||
|
||||
devices.forEach((device: Device, deviceIndex: number) => {
|
||||
device.sessions.forEach( (session: Session) => {
|
||||
if (sessionsOnOpenRow.includes(session.id)) {
|
||||
openRows[deviceIndex] = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return openRows;
|
||||
}
|
||||
|
||||
// current device and session should display at the top of their respective lists
|
||||
private moveCurrentToTop(devices: Device[]): Device[] {
|
||||
let currentDevice: Device = devices[0];
|
||||
|
@ -208,32 +161,6 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
return moment(time * 1000).format('LLLL');
|
||||
}
|
||||
|
||||
private findDeviceName(device: Device): string {
|
||||
let deviceName: string = device.device;
|
||||
|
||||
const deviceNameLower = deviceName.toLowerCase();
|
||||
if (deviceNameLower.includes('other') || deviceNameLower.includes('generic') ) {
|
||||
deviceName = this.findOS(device) + ' ' + this.findOSVersion(device);
|
||||
}
|
||||
|
||||
if (deviceName.trim() === 'Other') {
|
||||
deviceName = this.makeClientsString(device.sessions[0].clients);
|
||||
}
|
||||
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
private findDeviceIcon(device: Device): React.ReactNode {
|
||||
const deviceName = device.device.toLowerCase();
|
||||
if (deviceName.includes('kindle') || deviceName.includes('ipad')) {
|
||||
return (<TabletAltIcon size='lg' />);
|
||||
}
|
||||
|
||||
if (device.mobile) return (<MobileAltIcon size='lg' />);
|
||||
|
||||
return (<LaptopIcon size='lg'/>);
|
||||
}
|
||||
|
||||
private findBrowserIcon(session: Session): React.ReactNode {
|
||||
const browserName: string = session.browser.toLowerCase();
|
||||
if (browserName.includes("chrom")) return (<ChromeIcon size='lg'/>); // chrome or chromium
|
||||
|
@ -319,40 +246,16 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
</DataListItemRow>
|
||||
</DataListItem>
|
||||
|
||||
<DataListItem aria-labelledby='sessions'>
|
||||
<Grid gutter='sm'>
|
||||
<GridItem span={12}/> {/* <-- top spacing */}
|
||||
{this.state.devices.map((device: Device, deviceIndex: number) => {
|
||||
return (
|
||||
<DataListItem key={'device-' + deviceIndex} aria-labelledby="ex-item1" isExpanded={this.state.isRowOpen[deviceIndex]}>
|
||||
<DataListItemRow onClick={() => this.onToggle(deviceIndex)}>
|
||||
<DataListToggle
|
||||
isExpanded={this.state.isRowOpen[deviceIndex]}
|
||||
id={'deviceToggle-' + deviceIndex}
|
||||
aria-controls="ex-expand1"
|
||||
/>
|
||||
<DataListItemCells
|
||||
dataListCells={[
|
||||
<DataListCell isIcon key={"icon-" + deviceIndex} width={1}>
|
||||
{this.findDeviceIcon(device)}
|
||||
</DataListCell>,
|
||||
<DataListCell key={"os-" + deviceIndex} width={1}>
|
||||
<strong>{this.findDeviceName(device)}</strong>
|
||||
</DataListCell>,
|
||||
<DataListCell key={"lastAccess-" + deviceIndex} width={5}>
|
||||
{device.current && <p><span className='pf-c-badge pf-m-read'><strong><Msg msgKey="currentDevice"/></strong></span></p>}
|
||||
{!device.current && <p><strong><Msg msgKey="lastAccess"/>: </strong><span>{this.time(device.lastAccess)}</span></p>}
|
||||
</DataListCell>
|
||||
]}
|
||||
/>
|
||||
</DataListItemRow>
|
||||
<DataListContent
|
||||
noPadding={false}
|
||||
aria-label="Session Details"
|
||||
id="ex-expand1"
|
||||
isHidden={!this.state.isRowOpen[deviceIndex]}
|
||||
>
|
||||
<Grid gutter='sm'>
|
||||
<React.Fragment>
|
||||
{device.sessions.map((session: Session, sessionIndex: number) => {
|
||||
return (
|
||||
<React.Fragment key={'device-' + deviceIndex + '-session-' + sessionIndex}>
|
||||
|
||||
<GridItem span={3}>
|
||||
<Stack>
|
||||
<StackItem isFilled={false}>
|
||||
|
@ -392,14 +295,15 @@ export class DeviceActivityPage extends React.Component<DeviceActivityPageProps,
|
|||
|
||||
</GridItem>
|
||||
</React.Fragment>
|
||||
)})
|
||||
}
|
||||
);
|
||||
|
||||
})}
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
<GridItem span={12}/> {/* <-- bottom spacing */}
|
||||
</Grid>
|
||||
</DataListContent>
|
||||
</DataListItem>
|
||||
)})}
|
||||
|
||||
</DataList>
|
||||
</StackItem>
|
||||
|
||||
|
|
|
@ -949,7 +949,7 @@
|
|||
'./icons/landmark-icon.js': '@empty',
|
||||
'./icons/language-icon.js': '@empty',
|
||||
'./icons/laptop-code-icon.js': '@empty',
|
||||
//'./icons/laptop-icon.js': '@empty',
|
||||
'./icons/laptop-icon.js': '@empty',
|
||||
'./icons/laptop-medical-icon.js': '@empty',
|
||||
'./icons/laravel-icon.js': '@empty',
|
||||
'./icons/lastfm-icon.js': '@empty',
|
||||
|
@ -1050,7 +1050,7 @@
|
|||
'./icons/mix-icon.js': '@empty',
|
||||
'./icons/mixcloud-icon.js': '@empty',
|
||||
'./icons/mizuni-icon.js': '@empty',
|
||||
//'./icons/mobile-alt-icon.js': '@empty',
|
||||
'./icons/mobile-alt-icon.js': '@empty',
|
||||
'./icons/mobile-icon.js': '@empty',
|
||||
'./icons/modx-icon.js': '@empty',
|
||||
'./icons/monero-icon.js': '@empty',
|
||||
|
@ -1603,7 +1603,7 @@
|
|||
'./icons/syringe-icon.js': '@empty',
|
||||
'./icons/table-icon.js': '@empty',
|
||||
'./icons/table-tennis-icon.js': '@empty',
|
||||
//'./icons/tablet-alt-icon.js': '@empty',
|
||||
'./icons/tablet-alt-icon.js': '@empty',
|
||||
'./icons/tablet-icon.js': '@empty',
|
||||
'./icons/tablets-icon.js': '@empty',
|
||||
'./icons/tachometer-alt-icon.js': '@empty',
|
||||
|
|
Loading…
Reference in a new issue