Changed to use one confirm dialog (#2722)
This commit is contained in:
parent
152a62b72a
commit
219b60ff77
4 changed files with 78 additions and 127 deletions
|
@ -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();
|
||||||
|
|
|
@ -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>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -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>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -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")
|
}
|
||||||
}
|
/>
|
||||||
/>
|
</>
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue