import React, { useState } from "react"; import { Link } from "react-router-dom"; import { useTranslation } from "react-i18next"; import moment from "moment"; import { DropdownItem, PageSection, Select, SelectOption, SelectVariant, } from "@patternfly/react-core"; import { FilterIcon } from "@patternfly/react-icons"; import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { ViewHeader } from "../components/view-header/ViewHeader"; import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; import { useAdminClient } from "../context/auth/AdminClient"; import { CubesIcon } from "@patternfly/react-icons"; import "./SessionsSection.css"; import { RevocationModal } from "./RevocationModal"; import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation"; import { LogoutAllSessionsModal } from "./LogoutAllSessionsModal"; const Clients = (row: UserSessionRepresentation) => { return ( <> {Object.values(row.clients!).map((client) => ( {client} ))} ); }; export default function SessionsSection() { const { t } = useTranslation("sessions"); const adminClient = useAdminClient(); const [filterDropdownOpen, setFilterDropdownOpen] = useState(false); const [revocationModalOpen, setRevocationModalOpen] = useState(false); const [logoutAllSessionsModalOpen, setLogoutAllSessionsModalOpen] = useState(false); const [activeClientDetails, setActiveClientDetails] = useState< ClientRepresentation[] >([]); const [filterType, setFilterType] = useState( t("sessionsType.allSessions").toString() ); const [key, setKey] = useState(0); const [noSessions, setNoSessions] = useState(false); const refresh = () => { setKey(new Date().getTime()); }; const handleRevocationModalToggle = () => { setRevocationModalOpen(!revocationModalOpen); }; const handleLogoutAllSessionsModalToggle = () => { setLogoutAllSessionsModalOpen(!logoutAllSessionsModalOpen); }; const loader = async () => { const activeClients = await adminClient.sessions.find(); const clientSessions = ( await Promise.all( activeClients.map((client) => adminClient.clients.listSessions({ id: client.id }) ) ) ).flat(); setNoSessions(clientSessions.length === 0); const allClients = await adminClient.clients.find(); const getActiveClientDetails = allClients.filter((x) => activeClients.map((y) => y.id).includes(x.id) ); setActiveClientDetails(getActiveClientDetails); const userIds = Array.from( new Set(clientSessions.map((session) => session.userId)) ); const userSessions = ( await Promise.all( userIds.map((userId) => adminClient.users.listSessions({ id: userId! })) ) ).flat(); return userSessions; }; const dropdownItems = [ handleRevocationModalToggle()} > {t("revocation")} , handleLogoutAllSessionsModalToggle()} > {t("signOutAllActiveSessions")} , ]; return ( <> {revocationModalOpen && ( { handleRevocationModalToggle(); }} /> )} {logoutAllSessionsModalOpen && ( )} setFilterDropdownOpen(isExpanded)} toggleIcon={} onSelect={(_, value) => { setFilterType(value.toString()); refresh(); setFilterDropdownOpen(false); }} selections={filterType} > } columns={[ { name: "username", displayKey: "sessions:subject", }, { name: "lastAccess", displayKey: "sessions:lastAccess", cellRenderer: (row) => moment(row.lastAccess).fromNow(), }, { name: "start", displayKey: "sessions:startDate", cellRenderer: (row) => moment(row.lastAccess).format("LLL"), }, { name: "clients", displayKey: "sessions:accessedClients", cellRenderer: Clients, }, ]} emptyState={ } /> ); }