import { Button, DataList, DataListContent, DataListItem, DataListItemRow, DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, Grid, GridItem, Label, Spinner, Split, SplitItem, Title, Tooltip, } from "@patternfly/react-core"; import { SyncAltIcon, MobileAltIcon, DesktopIcon, } from "@patternfly/react-icons"; import { TFuncKey } from "i18next"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { deleteSession, getDevices } from "../api/methods"; import { DeviceRepresentation, SessionRepresentation, ClientRepresentation, } from "../api/representations"; import { useAlerts, ContinueCancelModal } from "ui-shared"; import useFormatter from "../components/formatter/format-date"; import { Page } from "../components/page/Page"; import { keycloak } from "../keycloak"; import { usePromise } from "../utils/usePromise"; const DeviceActivity = () => { const { t } = useTranslation(); const { addAlert, addError } = useAlerts(); const { formatTime } = useFormatter(); const [devices, setDevices] = useState(); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const moveCurrentToTop = (devices: DeviceRepresentation[]) => { let currentDevice = devices[0]; const index = devices.findIndex((d) => d.current); currentDevice = devices.splice(index, 1)[0]; devices.unshift(currentDevice); const sessionIndex = currentDevice.sessions.findIndex((s) => s.current); const currentSession = currentDevice.sessions.splice(sessionIndex, 1)[0]; currentDevice.sessions.unshift(currentSession); setDevices(devices); }; usePromise((signal) => getDevices({ signal }), moveCurrentToTop, [key]); const signOutAll = async () => { await deleteSession(); keycloak.logout(); }; const signOutSession = async ( session: SessionRepresentation, device: DeviceRepresentation ) => { try { await deleteSession(session.id); addAlert(t("signedOutSession", [session.browser, device.os])); refresh(); } catch (error) { addError("errorSignOutMessage", error); } }; const makeClientsString = (clients: ClientRepresentation[]): string => { let clientsString = ""; clients.forEach((client, index) => { let clientName: string; if (client.clientName !== "") { clientName = t(client.clientName as TFuncKey); } else { clientName = client.clientId; } clientsString += clientName; if (clients.length > index + 1) clientsString += ", "; }); return clientsString; }; if (!devices) { return ; } return ( {t("signedInDevices")} {(devices.length > 1 || devices[0].sessions.length > 1) && ( signOutAll()} /> )} {devices.map((device) => device.sessions.map((session) => ( {device.mobile ? : } {device.os.toLowerCase().includes("unknown") ? t("unknownOperatingSystem") : device.os}{" "} {!device.osVersion.toLowerCase().includes("unknown") && device.osVersion}{" "} / {session.browser} {session.current && ( )} {!session.current && ( signOutSession(session, device)} /> )} {t("ipAddress")} {session.ipAddress} {t("lastAccessedOn")} {formatTime(session.lastAccess)} {t("clients")} {makeClientsString(session.clients)} {t("started")} {formatTime(session.started)} {t("expires")} {formatTime(session.expires)} )) )} ); }; export default DeviceActivity;