import { ActionGroup, Button, Dropdown, DropdownToggle, Form, FormGroup, Modal, ModalVariant, Select, SelectVariant, TextInput, Tooltip, ToolbarItem, } from "@patternfly/react-core"; import { cellWidth, Table, TableBody, TableHeader, TableVariant, } from "@patternfly/react-table"; import type AdminEventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/adminEventRepresentation"; import moment from "moment"; import React, { FunctionComponent, useState } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; import { useAdminClient } from "../context/auth/AdminClient"; import { useRealm } from "../context/realm-context/RealmContext"; import "./events.css"; type DisplayDialogProps = { titleKey: string; onClose: () => void; }; type AdminEventSearchForm = { operationType: string[]; resourceType: string[]; resourcePath: string; dateFrom: string; dateTo: string; client: string; user: string; realm: string[]; ipAddress: string; }; const defaultValues: AdminEventSearchForm = { operationType: [], resourceType: [], resourcePath: "", dateFrom: "", dateTo: "", client: "", user: "", realm: [], ipAddress: "", }; const DisplayDialog: FunctionComponent = ({ titleKey, onClose, children, }) => { const { t } = useTranslation("events"); return ( {children} ); }; const MAX_TEXT_LENGTH = 38; const Truncate = ({ text, children, }: { text?: string; children: (text: string) => any; }) => { const definedText = text || ""; const needsTruncation = definedText.length > MAX_TEXT_LENGTH; const truncatedText = definedText.substr(0, MAX_TEXT_LENGTH); return ( <> {needsTruncation && ( {children(truncatedText + "...")} )} {!needsTruncation && <>{children(definedText)}} ); }; export const AdminEvents = () => { const { t } = useTranslation("events"); const adminClient = useAdminClient(); const { realm } = useRealm(); const [key, setKey] = useState(0); const [searchDropdownOpen, setSearchDropdownOpen] = useState(false); const [selectOpen, setSelectOpen] = useState(false); const refresh = () => setKey(new Date().getTime()); const [authEvent, setAuthEvent] = useState(); const [representationEvent, setRepresentationEvent] = useState(); const { register, formState: { isDirty }, } = useForm({ shouldUnregister: false, mode: "onChange", defaultValues, }); const loader = async (first?: number, max?: number, search?: string) => { const params = { first: first!, max: max!, realm, }; if (search) { console.log("how to search?", search); } return await adminClient.realms.findAdminEvents({ ...params }); }; const LinkResource = (row: AdminEventRepresentation) => ( <> {(text) => ( <> {row.resourceType !== "COMPONENT" && ( {text} )} {row.resourceType === "COMPONENT" && {text}} )} ); const adminEventSearchFormDisplay = () => { return ( <> setSearchDropdownOpen(isOpen)} className="keycloak__events_search_selector_dropdown__toggle" > {t("searchForAdminEvent")} } isOpen={searchDropdownOpen} >
); }; return ( <> {authEvent && ( setAuthEvent(undefined)}>
)} {representationEvent && ( setRepresentationEvent(undefined)} > some json from the changed values )} setAuthEvent(event), }, { title: t("representation"), onRowClick: (event) => setRepresentationEvent(event), }, ]} columns={[ { name: "time", displayKey: "events:time", cellRenderer: (row) => moment(row.time).format("LLL"), }, { name: "resourcePath", displayKey: "events:resourcePath", cellRenderer: LinkResource, }, { name: "resourceType", displayKey: "events:resourceType", }, { name: "operationType", displayKey: "events:operationType", transforms: [cellWidth(10)], }, { name: "", displayKey: "events:user", cellRenderer: (event) => event.authDetails?.userId, }, ]} emptyState={ } /> ); };