Added status for when user and admin events saving is turned off (#35673)

Signed-off-by: Agnieszka Gancarczyk <agagancarczyk@gmail.com>
This commit is contained in:
Agnieszka Gancarczyk
2025-01-07 14:28:42 +00:00
committed by GitHub
parent 1c4dd66f52
commit fd1d40a83a
5 changed files with 41 additions and 9 deletions

View File

@@ -3333,4 +3333,6 @@ downloadThemeJar=Download theme JAR
themeColorInfo=Here you can set the patternfly color variables and create a "theme jar" file that you can download and put in your providers folder to apply the theme to your realm.
permissionsSubTitle=Fine-grained admin permissions allow assigning detailed, specific access rights, controlling which resources and actions can be managed.
connectionTrace=Connection trace
connectionTraceHelp=If enabled, incoming and outgoing LDAP ASN.1 BER packets will be dumped to the error output stream. Be careful when enabling this option in production as it will expose all data sent to and from the LDAP server.
connectionTraceHelp=If enabled, incoming and outgoing LDAP ASN.1 BER packets will be dumped to the error output stream. Be careful when enabling this option in production as it will expose all data sent to and from the LDAP server.
savingUserEventsOff=Saving user events turned off
savingAdminEventsOff=Saving admin events turned off

View File

@@ -5,13 +5,21 @@ import { useTranslation } from "react-i18next";
type WarnBannerProps = {
msg: string;
className?: string;
};
const WarnBanner = ({ msg }: WarnBannerProps) => {
type EventsBannerType = "userEvents" | "adminEvents";
const WarnBanner = ({ msg, className }: WarnBannerProps) => {
const { t } = useTranslation();
return (
<Banner screenReaderText={t(msg)} variant="gold" isSticky>
<Banner
screenReaderText={t(msg)}
variant="gold"
className={className}
isSticky
>
<Flex
spaceItems={{ default: "spaceItemsSm" }}
flexWrap={{ default: "wrap" }}
@@ -30,3 +38,10 @@ export const Banners = () => {
if (whoAmI.isTemporary()) return <WarnBanner msg="loggedInAsTempAdminUser" />;
};
export const EventsBanners = ({ type }: { type: EventsBannerType }) => {
const msg =
type === "userEvents" ? "savingUserEventsOff" : "savingAdminEventsOff";
return <WarnBanner msg={msg} className="pf-v5-u-mt-md pf-v5-u-mx-md" />;
};

View File

@@ -6,6 +6,7 @@ import {
ListEmptyState,
SelectVariant,
TextControl,
useFetch,
} from "@keycloak/keycloak-ui-shared";
import {
ActionGroup,
@@ -47,6 +48,7 @@ import { useServerInfo } from "../context/server-info/ServerInfoProvider";
import { prettyPrintJSON } from "../util";
import useFormatDate, { FORMAT_DATE_AND_TIME } from "../utils/useFormatDate";
import { CellResourceLinkRenderer } from "./ResourceLinks";
import { EventsBanners } from "../Banners";
import "./events.css";
@@ -135,6 +137,7 @@ export const AdminEvents = () => {
>({});
const [authEvent, setAuthEvent] = useState<AdminEventRepresentation>();
const [adminEventsEnabled, setAdminEventsEnabled] = useState<boolean>();
const [representationEvent, setRepresentationEvent] =
useState<AdminEventRepresentation>();
@@ -161,6 +164,14 @@ export const AdminEvents = () => {
control,
} = form;
useFetch(
() => adminClient.realms.getConfigEvents({ realm }),
(events) => {
setAdminEventsEnabled(events?.adminEventsEnabled!);
},
[],
);
function loader(first?: number, max?: number) {
return adminClient.realms.findAdminEvents({
// The admin client wants 'dateFrom' and 'dateTo' to be Date objects, however it cannot actually handle them so we need to cast to any.
@@ -271,8 +282,8 @@ export const AdminEvents = () => {
/>
</DisplayDialog>
)}
{!adminEventsEnabled && <EventsBanners type="adminEvents" />}
<KeycloakDataTable
className="keycloak__events_table"
key={key}
loader={loader}
detailColumns={[

View File

@@ -39,6 +39,7 @@ import { useRealm } from "../context/realm-context/RealmContext";
import { toUser } from "../user/routes/User";
import useFormatDate, { FORMAT_DATE_AND_TIME } from "../utils/useFormatDate";
import useLocaleSort from "../utils/useLocaleSort";
import { EventsBanners } from "../Banners";
import "./events.css";
@@ -127,6 +128,7 @@ export const UserEvents = ({ user, client }: UserEventsProps) => {
const [searchDropdownOpen, setSearchDropdownOpen] = useState(false);
const [selectOpen, setSelectOpen] = useState(false);
const [events, setEvents] = useState<string[]>();
const [userEventsEnabled, setUserEventsEnabled] = useState<boolean>();
const [activeFilters, setActiveFilters] = useState<
Partial<UserEventSearchForm>
>({});
@@ -164,8 +166,10 @@ export const UserEvents = ({ user, client }: UserEventsProps) => {
useFetch(
() => adminClient.realms.getConfigEvents({ realm }),
(events) =>
setEvents(localeSort(events?.enabledEventTypes || [], (e) => e)),
(events) => {
setUserEventsEnabled(events?.eventsEnabled!);
setEvents(localeSort(events?.enabledEventTypes || [], (e) => e));
},
[],
);
@@ -429,7 +433,8 @@ export const UserEvents = ({ user, client }: UserEventsProps) => {
};
return (
<div className="keycloak__events_table">
<>
{!userEventsEnabled && <EventsBanners type="userEvents" />}
<KeycloakDataTable
key={key}
loader={loader}
@@ -485,6 +490,6 @@ export const UserEvents = ({ user, client }: UserEventsProps) => {
}
isSearching={Object.keys(activeFilters).length > 0}
/>
</div>
</>
);
};

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type {
UserProfileAttribute,
UserProfileConfig,