Changed to use one confirm dialog (#2722)

This commit is contained in:
Erik Jan de Wit 2022-06-01 11:12:30 +02:00 committed by GitHub
parent 152a62b72a
commit 219b60ff77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 127 deletions

View file

@ -12,7 +12,7 @@ export default class SessionsPage {
clearNotBeforeButton = "clear-not-before-button"; clearNotBeforeButton = "clear-not-before-button";
notBeforeInput = "not-before-input"; notBeforeInput = "not-before-input";
logoutAll = "logout-all"; logoutAll = "logout-all";
logoutAllConfirm = "logout-all-confirm-button"; logoutAllConfirm = "confirm";
setToNow() { setToNow() {
cy.findByTestId(this.actionDropdown).should("exist").click(); cy.findByTestId(this.actionDropdown).should("exist").click();

View file

@ -1,74 +0,0 @@
import React from "react";
import {
AlertVariant,
Button,
ButtonVariant,
Modal,
ModalVariant,
TextContent,
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import { useAlerts } from "../components/alert/Alerts";
type RevocationModalProps = {
handleModalToggle: () => void;
};
export const LogoutAllSessionsModal = ({
handleModalToggle,
}: RevocationModalProps) => {
const { t } = useTranslation("sessions");
const { addAlert } = useAlerts();
const { realm: realmName } = useRealm();
const adminClient = useAdminClient();
const logoutAllSessions = async () => {
try {
await adminClient.realms.logoutAll({ realm: realmName });
adminClient.keycloak?.logout({ redirectUri: "" });
} catch (error) {
addAlert(t("logoutAllSessionsError", { error }), AlertVariant.danger);
}
};
return (
<Modal
variant={ModalVariant.small}
title={t("signOutAllActiveSessionsQuestion")}
isOpen={true}
onClose={handleModalToggle}
actions={[
<Button
data-testid="logout-all-confirm-button"
key="set-to-now"
variant="primary"
onClick={() => {
logoutAllSessions();
handleModalToggle();
}}
form="revocation-modal-form"
>
{t("realm-settings:confirm")}
</Button>,
<Button
id="modal-cancel"
data-testid="cancel"
key="cancel"
variant={ButtonVariant.link}
onClick={() => {
handleModalToggle();
}}
>
{t("common:cancel")}
</Button>,
]}
>
<TextContent className="kc-logout-all-description-text">
{t("logoutAllDescription")}
</TextContent>
</Modal>
);
};

View file

@ -6,18 +6,22 @@ import { useTranslation } from "react-i18next";
import { ViewHeader } from "../components/view-header/ViewHeader"; import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAdminClient } from "../context/auth/AdminClient"; import { useAdminClient } from "../context/auth/AdminClient";
import helpUrls from "../help-urls"; import helpUrls from "../help-urls";
import { LogoutAllSessionsModal } from "./LogoutAllSessionsModal";
import { RevocationModal } from "./RevocationModal"; import { RevocationModal } from "./RevocationModal";
import SessionsTable from "./SessionsTable"; import SessionsTable from "./SessionsTable";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { useAlerts } from "../components/alert/Alerts";
import { useRealm } from "../context/realm-context/RealmContext";
import "./SessionsSection.css"; import "./SessionsSection.css";
export default function SessionsSection() { export default function SessionsSection() {
const adminClient = useAdminClient();
const { t } = useTranslation("sessions"); const { t } = useTranslation("sessions");
const adminClient = useAdminClient();
const { addError } = useAlerts();
const { realm } = useRealm();
const [revocationModalOpen, setRevocationModalOpen] = useState(false); const [revocationModalOpen, setRevocationModalOpen] = useState(false);
const [logoutAllSessionsModalOpen, setLogoutAllSessionsModalOpen] =
useState(false);
const [activeClientDetails, setActiveClientDetails] = useState< const [activeClientDetails, setActiveClientDetails] = useState<
ClientRepresentation[] ClientRepresentation[]
>([]); >([]);
@ -27,10 +31,6 @@ export default function SessionsSection() {
setRevocationModalOpen(!revocationModalOpen); setRevocationModalOpen(!revocationModalOpen);
}; };
const handleLogoutAllSessionsModalToggle = () => {
setLogoutAllSessionsModalOpen(!logoutAllSessionsModalOpen);
};
const loader = async () => { const loader = async () => {
const activeClients = await adminClient.sessions.find(); const activeClients = await adminClient.sessions.find();
const clientSessions = ( const clientSessions = (
@ -63,6 +63,20 @@ export default function SessionsSection() {
return userSessions; return userSessions;
}; };
const [toggleLogoutDialog, LogoutConfirm] = useConfirmDialog({
titleKey: "sessions:logoutAllSessions",
messageKey: "sessions:logoutAllDescription",
continueButtonLabel: "common:confirm",
onConfirm: async () => {
try {
await adminClient.realms.logoutAll({ realm });
adminClient.keycloak?.logout({ redirectUri: "" });
} catch (error) {
addError("sessions:logoutAllSessionsError", error);
}
},
});
const dropdownItems = [ const dropdownItems = [
<DropdownItem <DropdownItem
key="toggle-modal" key="toggle-modal"
@ -77,7 +91,7 @@ export default function SessionsSection() {
data-testid="logout-all" data-testid="logout-all"
component="button" component="button"
isDisabled={noSessions} isDisabled={noSessions}
onClick={() => handleLogoutAllSessionsModalToggle()} onClick={toggleLogoutDialog}
> >
{t("signOutAllActiveSessions")} {t("signOutAllActiveSessions")}
</DropdownItem>, </DropdownItem>,
@ -85,6 +99,7 @@ export default function SessionsSection() {
return ( return (
<> <>
<LogoutConfirm />
<ViewHeader <ViewHeader
dropdownItems={dropdownItems} dropdownItems={dropdownItems}
titleKey="sessions:title" titleKey="sessions:title"
@ -101,11 +116,6 @@ export default function SessionsSection() {
}} }}
/> />
)} )}
{logoutAllSessionsModalOpen && (
<LogoutAllSessionsModal
handleModalToggle={handleLogoutAllSessionsModalToggle}
/>
)}
<SessionsTable loader={loader} /> <SessionsTable loader={loader} />
</PageSection> </PageSection>
</> </>

View file

@ -12,6 +12,8 @@ import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { toClient } from "../clients/routes/Client"; import { toClient } from "../clients/routes/Client";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
import { import {
Field, Field,
@ -43,8 +45,9 @@ export default function SessionsTable({
const { whoAmI } = useWhoAmI(); const { whoAmI } = useWhoAmI();
const { t } = useTranslation("sessions"); const { t } = useTranslation("sessions");
const adminClient = useAdminClient(); const adminClient = useAdminClient();
const [key, setKey] = useState(0); const { addError } = useAlerts();
const locale = whoAmI.getLocale(); const locale = whoAmI.getLocale();
const [key, setKey] = useState(0);
const refresh = () => setKey((value) => value + 1); const refresh = () => setKey((value) => value + 1);
const columns = useMemo(() => { const columns = useMemo(() => {
@ -98,6 +101,20 @@ export default function SessionsTable({
); );
}, [realm, locale, hiddenColumns]); }, [realm, locale, hiddenColumns]);
const [toggleLogoutDialog, LogoutConfirm] = useConfirmDialog({
titleKey: "sessions:logoutAllSessions",
messageKey: "sessions:logoutAllDescription",
continueButtonLabel: "common:confirm",
onConfirm: async () => {
try {
await adminClient.users.logout({ id: logoutUser! });
refresh();
} catch (error) {
addError("sessions:logoutAllSessionsError", error);
}
},
});
async function onClickSignOut(session: UserSessionRepresentation) { async function onClickSignOut(session: UserSessionRepresentation) {
await adminClient.realms.deleteSession({ realm, session: session.id! }); await adminClient.realms.deleteSession({ realm, session: session.id! });
@ -109,42 +126,40 @@ export default function SessionsTable({
} }
return ( return (
<KeycloakDataTable <>
key={key} <LogoutConfirm />
loader={loader} <KeycloakDataTable
ariaLabelKey="sessions:title" key={key}
searchPlaceholderKey="sessions:searchForSession" loader={loader}
toolbarItem={ ariaLabelKey="sessions:title"
logoutUser && ( searchPlaceholderKey="sessions:searchForSession"
<ToolbarItem> toolbarItem={
<Button logoutUser && (
onClick={async () => { <ToolbarItem>
await adminClient.users.logout({ id: logoutUser }); <Button onClick={toggleLogoutDialog}>
refresh(); {t("logoutAllSessions")}
}} </Button>
> </ToolbarItem>
{t("logoutAllSessions")} )
</Button> }
</ToolbarItem> columns={columns}
) actions={[
} {
columns={columns} title: t("common:signOut"),
actions={[ onRowClick: onClickSignOut,
{ },
title: t("common:signOut"), ]}
onRowClick: onClickSignOut, emptyState={
}, <ListEmptyState
]} hasIcon
emptyState={ icon={CubesIcon}
<ListEmptyState message={t("noSessions")}
hasIcon instructions={
icon={CubesIcon} emptyInstructions ? emptyInstructions : t("noSessionsDescription")
message={t("noSessions")} }
instructions={ />
emptyInstructions ? emptyInstructions : t("noSessionsDescription") }
} />
/> </>
}
/>
); );
} }