Restore the Cache tab in Realm Settings (#34311)
closes keycloak#17727 Signed-off-by: Christian Janker <christian.janker@gmx.at>
This commit is contained in:
parent
6482e41cd8
commit
9851452be1
5 changed files with 159 additions and 5 deletions
|
@ -3286,3 +3286,13 @@ somethingWentWrong=Something went wrong
|
|||
somethingWentWrongDescription=Sorry, an unexpected error has occurred.
|
||||
tryAgain=Try again
|
||||
errorSavingTranslations=Error saving translations\: '{{error}}'
|
||||
clearCachesTitle=Clear Caches
|
||||
realmCache=Realm Cache
|
||||
userCache=User Cache
|
||||
keysCache=Keys Cache
|
||||
clearButtonTitle=Clear
|
||||
clearRealmCacheHelp=This will clear entries for all realms.
|
||||
clearUserCacheHelp=This will clear entries for all realms.
|
||||
clearKeysCacheHelp=Clears all entries from the cache of external public keys. These are keys of external clients or identity providers. This will clear all entries for all realms.
|
||||
clearCacheSuccess=Cache cleared successfully
|
||||
clearCacheError=Could not clear cache\: {{error}}
|
||||
|
|
|
@ -23,6 +23,9 @@ import { HelpHeader } from "./components/help-enabler/HelpHeader";
|
|||
import { useRealm } from "./context/realm-context/RealmContext";
|
||||
import { useWhoAmI } from "./context/whoami/WhoAmI";
|
||||
import { toDashboard } from "./dashboard/routes/Dashboard";
|
||||
import useToggle from "./utils/useToggle";
|
||||
import { PageHeaderClearCachesModal } from "./PageHeaderClearCachesModal";
|
||||
import { useAccess } from "./context/access/Access";
|
||||
|
||||
const ManageAccountDropdownItem = () => {
|
||||
const { keycloak } = useEnvironment();
|
||||
|
@ -67,6 +70,20 @@ const ServerInfoDropdownItem = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const ClearCachesDropdownItem = () => {
|
||||
const { t } = useTranslation();
|
||||
const [open, toggleModal] = useToggle();
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownItem key="clear caches" onClick={() => toggleModal()}>
|
||||
{t("clearCachesTitle")}
|
||||
</DropdownItem>
|
||||
{open && <PageHeaderClearCachesModal onClose={() => toggleModal()} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const HelpDropdownItem = () => {
|
||||
const { t } = useTranslation();
|
||||
const { enabled, toggleHelp } = useHelp();
|
||||
|
@ -81,23 +98,34 @@ const HelpDropdownItem = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const kebabDropdownItems = [
|
||||
const kebabDropdownItems = (isMasterRealm: boolean, isManager: boolean) => [
|
||||
<ManageAccountDropdownItem key="kebab Manage Account" />,
|
||||
<ServerInfoDropdownItem key="kebab Server Info" />,
|
||||
...(isMasterRealm && isManager
|
||||
? [<ClearCachesDropdownItem key="Clear Caches" />]
|
||||
: []),
|
||||
<HelpDropdownItem key="kebab Help" />,
|
||||
<Divider component="li" key="kebab sign out separator" />,
|
||||
<SignOutDropdownItem key="kebab Sign out" />,
|
||||
];
|
||||
|
||||
const userDropdownItems = [
|
||||
const userDropdownItems = (isMasterRealm: boolean, isManager: boolean) => [
|
||||
<ManageAccountDropdownItem key="Manage Account" />,
|
||||
<ServerInfoDropdownItem key="Server info" />,
|
||||
...(isMasterRealm && isManager
|
||||
? [<ClearCachesDropdownItem key="Clear Caches" />]
|
||||
: []),
|
||||
<Divider component="li" key="sign out separator" />,
|
||||
<SignOutDropdownItem key="Sign out" />,
|
||||
];
|
||||
|
||||
const KebabDropdown = () => {
|
||||
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
||||
const { realm } = useRealm();
|
||||
const { hasAccess } = useAccess();
|
||||
|
||||
const isMasterRealm = realm === "master";
|
||||
const isManager = hasAccess("manage-realm");
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
|
@ -116,7 +144,9 @@ const KebabDropdown = () => {
|
|||
)}
|
||||
isOpen={isDropdownOpen}
|
||||
>
|
||||
<DropdownList>{kebabDropdownItems}</DropdownList>
|
||||
<DropdownList>
|
||||
{kebabDropdownItems(isMasterRealm, isManager)}
|
||||
</DropdownList>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
@ -124,6 +154,11 @@ const KebabDropdown = () => {
|
|||
const UserDropdown = () => {
|
||||
const { whoAmI } = useWhoAmI();
|
||||
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
||||
const { realm } = useRealm();
|
||||
const { hasAccess } = useAccess();
|
||||
|
||||
const isMasterRealm = realm === "master";
|
||||
const isManager = hasAccess("manage-realm");
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
|
@ -140,7 +175,7 @@ const UserDropdown = () => {
|
|||
</MenuToggle>
|
||||
)}
|
||||
>
|
||||
<DropdownList>{userDropdownItems}</DropdownList>
|
||||
<DropdownList>{userDropdownItems(isMasterRealm, isManager)}</DropdownList>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
|
101
js/apps/admin-ui/src/PageHeaderClearCachesModal.tsx
Normal file
101
js/apps/admin-ui/src/PageHeaderClearCachesModal.tsx
Normal file
|
@ -0,0 +1,101 @@
|
|||
import {
|
||||
AlertVariant,
|
||||
Button,
|
||||
Flex,
|
||||
FlexItem,
|
||||
List,
|
||||
ListItem,
|
||||
Modal,
|
||||
ModalVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useRealm } from "./context/realm-context/RealmContext";
|
||||
import { useAdminClient } from "./admin-client";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem, useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
export type ClearCachesModalProps = {
|
||||
onClose: () => void;
|
||||
};
|
||||
export const PageHeaderClearCachesModal = ({
|
||||
onClose,
|
||||
}: ClearCachesModalProps) => {
|
||||
const { realm: realmName } = useRealm();
|
||||
const { t } = useTranslation();
|
||||
const { adminClient } = useAdminClient();
|
||||
const { addError, addAlert } = useAlerts();
|
||||
|
||||
const clearCache =
|
||||
(clearCacheFn: typeof adminClient.cache.clearRealmCache) =>
|
||||
async (realm: string) => {
|
||||
try {
|
||||
await clearCacheFn({ realm });
|
||||
addAlert(t("clearCacheSuccess"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
addError("clearCacheError", error);
|
||||
}
|
||||
};
|
||||
const clearRealmCache = clearCache(adminClient.cache.clearRealmCache);
|
||||
const clearUserCache = clearCache(adminClient.cache.clearUserCache);
|
||||
const clearKeysCache = clearCache(adminClient.cache.clearKeysCache);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t("clearCachesTitle")}
|
||||
variant={ModalVariant.small}
|
||||
isOpen
|
||||
onClose={onClose}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<List isPlain isBordered>
|
||||
<ListItem>
|
||||
<Flex justifyContent={{ default: "justifyContentSpaceBetween" }}>
|
||||
<FlexItem>
|
||||
{t("realmCache")}{" "}
|
||||
<HelpItem
|
||||
helpText={t("clearRealmCacheHelp")}
|
||||
fieldLabelId="clearRealmCacheHelp"
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Button onClick={() => clearRealmCache(realmName)}>
|
||||
{t("clearButtonTitle")}
|
||||
</Button>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Flex justifyContent={{ default: "justifyContentSpaceBetween" }}>
|
||||
<FlexItem>
|
||||
{t("userCache")}{" "}
|
||||
<HelpItem
|
||||
helpText={t("clearUserCacheHelp")}
|
||||
fieldLabelId="clearUserCacheHelp"
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Button onClick={() => clearUserCache(realmName)}>
|
||||
{t("clearButtonTitle")}
|
||||
</Button>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Flex justifyContent={{ default: "justifyContentSpaceBetween" }}>
|
||||
<FlexItem>
|
||||
{t("keysCache")}{" "}
|
||||
<HelpItem
|
||||
helpText={t("clearKeysCacheHelp")}
|
||||
fieldLabelId="clearKeysCacheHelp"
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Button onClick={() => clearKeysCache(realmName)}>
|
||||
{t("clearButtonTitle")}
|
||||
</Button>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Modal>
|
||||
);
|
||||
};
|
|
@ -6,6 +6,14 @@ export class Cache extends Resource<{ realm?: string }> {
|
|||
method: "POST",
|
||||
path: "/clear-user-cache",
|
||||
});
|
||||
public clearKeysCache = this.makeRequest<{}, void>({
|
||||
method: "POST",
|
||||
path: "/clear-keys-cache",
|
||||
});
|
||||
public clearRealmCache = this.makeRequest<{}, void>({
|
||||
method: "POST",
|
||||
path: "/clear-realm-cache",
|
||||
});
|
||||
|
||||
constructor(client: KeycloakAdminClient) {
|
||||
super(client, {
|
||||
|
|
Loading…
Reference in a new issue