diff --git a/src/events/AdminEvents.tsx b/src/events/AdminEvents.tsx new file mode 100644 index 0000000000..457d90dd06 --- /dev/null +++ b/src/events/AdminEvents.tsx @@ -0,0 +1,147 @@ +import React, { ReactNode, useContext, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { + Button, + Modal, + ModalVariant, + ToolbarItem, +} from "@patternfly/react-core"; +import moment from "moment"; + +import { useAdminClient } from "../context/auth/AdminClient"; +import { DataList } from "../components/table-toolbar/DataList"; +import { RealmContext } from "../context/realm-context/RealmContext"; +import { + Table, + TableBody, + TableHeader, + TableVariant, +} from "@patternfly/react-table"; +import AdminEventRepresentation from "keycloak-admin/lib/defs/adminEventRepresentation"; +import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; + +type DisplayDialogProps = { + titleKey: string; + onClose: () => void; + children: ReactNode; +}; + +const DisplayDialog = ({ titleKey, onClose, children }: DisplayDialogProps) => { + const { t } = useTranslation("events"); + return ( + + {children} + + ); +}; + +export const AdminEvents = () => { + const { t } = useTranslation("events"); + const adminClient = useAdminClient(); + const { realm } = useContext(RealmContext); + + const [key, setKey] = useState(""); + const refresh = () => setKey(`${new Date().getTime()}`); + + const [authEvent, setAuthEvent] = useState(); + const [representationEvent, setRepresentationEvent] = useState< + AdminEventRepresentation + >(); + + 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 }); + }; + + return ( + <> + {authEvent && ( + setAuthEvent(undefined)}> + + + +
+
+ )} + {representationEvent && ( + setRepresentationEvent(undefined)} + > + some json from the changed values + + )} + + + + + + } + actions={[ + { + title: t("auth"), + onRowClick: (event) => setAuthEvent(event), + }, + { + title: t("representation"), + onRowClick: (event) => setRepresentationEvent(event), + }, + ]} + columns={[ + { + name: "time", + displayKey: "events:time", + cellRenderer: (row) => moment(row.time).fromNow(), + }, + { + name: "resourcePath", + displayKey: "events:resourcePath", + }, + { + name: "resourceType", + displayKey: "events:resourceType", + }, + { + name: "operationType", + displayKey: "events:operationType", + }, + { + name: "", + displayKey: "events:user", + cellRenderer: (event) => event.authDetails?.userId, + }, + ]} + emptyState={ + + } + /> + + ); +}; diff --git a/src/events/EventsSection.tsx b/src/events/EventsSection.tsx index ef95f536e9..972a4ffcd5 100644 --- a/src/events/EventsSection.tsx +++ b/src/events/EventsSection.tsx @@ -4,6 +4,9 @@ import { Button, Label, PageSection, + Tab, + Tabs, + TabTitleText, ToolbarItem, } from "@patternfly/react-core"; import moment from "moment"; @@ -14,11 +17,15 @@ import { ViewHeader } from "../components/view-header/ViewHeader"; import { DataList } from "../components/table-toolbar/DataList"; import { RealmContext } from "../context/realm-context/RealmContext"; import { InfoCircleIcon } from "@patternfly/react-icons"; +import { AdminEvents } from "./AdminEvents"; +import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; export const EventsSection = () => { const { t } = useTranslation("events"); const adminClient = useAdminClient(); const { realm } = useContext(RealmContext); + + const [activeTab, setActiveTab] = useState(0); const [key, setKey] = useState(""); const refresh = () => setKey(`${new Date().getTime()}`); @@ -48,44 +55,67 @@ export const EventsSection = () => { <> - - - - - - } - columns={[ - { - name: "time", - displayKey: "events:time", - cellRenderer: (row) => moment(row.time).fromNow(), - }, - { - name: "userId", - displayKey: "events:user", - }, - { - name: "type", - displayKey: "events:eventType", - cellRenderer: StatusRow, - }, - { - name: "ipAddress", - displayKey: "events:ipAddress", - }, - { - name: "clientId", - displayKey: "events:client", - }, - ]} - /> + setActiveTab(key as number)} + isBox + > + {t("userEvents")}} + > + + + + + + } + columns={[ + { + name: "time", + displayKey: "events:time", + cellRenderer: (row) => moment(row.time).fromNow(), + }, + { + name: "userId", + displayKey: "events:user", + }, + { + name: "type", + displayKey: "events:eventType", + cellRenderer: StatusRow, + }, + { + name: "ipAddress", + displayKey: "events:ipAddress", + }, + { + name: "clientId", + displayKey: "events:client", + }, + ]} + emptyState={ + + } + /> + + {t("adminEvents")}} + > + + + ); diff --git a/src/events/messages.json b/src/events/messages.json index 3e551f0238..6e2d3ae11b 100644 --- a/src/events/messages.json +++ b/src/events/messages.json @@ -2,12 +2,23 @@ "events": { "title": "Events", "eventExplain": "If you want to configure user events, Admin events or Event listeners, please enter Event configs page realm settings to configure.", + "userEvents": "User events", + "adminEvents": "Admin events", "searchForEvent": "Search user event", "refresh": "Refresh", + "emptyEvents": "No events logged", + "emptyEventsInstructions": "Configure event logging in the realm settings", "time": "Time", "user": "User", "eventType": "Event type", "ipAddress": "IP address", - "client": "Client" + "client": "Client", + "resourcePath": "Resource path", + "resourceType": "Resource type", + "operationType": "Operation type", + "auth": "Auth", + "attribute": "Attribute", + "value": "Value", + "representation": "Representation" } } \ No newline at end of file