add action menu to current user (#1094)
* add action menu to delete current user * added impersonate user to action manu * fixed spelling
This commit is contained in:
parent
6e8ec947b5
commit
f87463d036
9 changed files with 81 additions and 22 deletions
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -8,7 +8,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "Apache",
|
"license": "Apache",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keycloak/keycloak-admin-client": "^16.0.0-dev.0",
|
"@keycloak/keycloak-admin-client": "^16.0.0-dev.2",
|
||||||
"@patternfly/patternfly": "^4.132.2",
|
"@patternfly/patternfly": "^4.132.2",
|
||||||
"@patternfly/react-core": "4.152.4",
|
"@patternfly/react-core": "4.152.4",
|
||||||
"@patternfly/react-icons": "4.11.14",
|
"@patternfly/react-icons": "4.11.14",
|
||||||
|
@ -2541,9 +2541,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@keycloak/keycloak-admin-client": {
|
"node_modules/@keycloak/keycloak-admin-client": {
|
||||||
"version": "16.0.0-dev.0",
|
"version": "16.0.0-dev.2",
|
||||||
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.0.tgz",
|
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.2.tgz",
|
||||||
"integrity": "sha512-o1gUKPn6Zeqe//1v2TF5VVvwDeeXktUFf/L70rQ8KJC/PudGPnV6luDu6Pyj/G32Yoc5iigSMWFly5Qlsd0bgw==",
|
"integrity": "sha512-eLeN4/O5OWjU0fIIvndv0oLSRQN3q0bdMep19E+09/qL4jeNeBR4ltxLKd0mnW1FY53cZJ+QWLaq/lfgRXFfzA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"camelize": "^1.0.0",
|
"camelize": "^1.0.0",
|
||||||
|
@ -19352,9 +19352,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@keycloak/keycloak-admin-client": {
|
"@keycloak/keycloak-admin-client": {
|
||||||
"version": "16.0.0-dev.0",
|
"version": "16.0.0-dev.2",
|
||||||
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.0.tgz",
|
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.2.tgz",
|
||||||
"integrity": "sha512-o1gUKPn6Zeqe//1v2TF5VVvwDeeXktUFf/L70rQ8KJC/PudGPnV6luDu6Pyj/G32Yoc5iigSMWFly5Qlsd0bgw==",
|
"integrity": "sha512-eLeN4/O5OWjU0fIIvndv0oLSRQN3q0bdMep19E+09/qL4jeNeBR4ltxLKd0mnW1FY53cZJ+QWLaq/lfgRXFfzA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"camelize": "^1.0.0",
|
"camelize": "^1.0.0",
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keycloak/keycloak-admin-client": "^16.0.0-dev.0",
|
"@keycloak/keycloak-admin-client": "^16.0.0-dev.2",
|
||||||
"@patternfly/patternfly": "^4.132.2",
|
"@patternfly/patternfly": "^4.132.2",
|
||||||
"@patternfly/react-core": "4.152.4",
|
"@patternfly/react-core": "4.152.4",
|
||||||
"@patternfly/react-icons": "4.11.14",
|
"@patternfly/react-icons": "4.11.14",
|
||||||
|
|
|
@ -59,7 +59,6 @@ export default {
|
||||||
searchForRole: "Search role",
|
searchForRole: "Search role",
|
||||||
origin: "Origin",
|
origin: "Origin",
|
||||||
user: "User",
|
user: "User",
|
||||||
details: "Details",
|
|
||||||
noGeneratedAccessToken: "No generated access token",
|
noGeneratedAccessToken: "No generated access token",
|
||||||
generatedAccessTokenIsDisabled:
|
generatedAccessTokenIsDisabled:
|
||||||
"Generated access token is disabled when no user is selected",
|
"Generated access token is disabled when no user is selected",
|
||||||
|
|
|
@ -84,6 +84,7 @@ export default {
|
||||||
userFederation: "User federation",
|
userFederation: "User federation",
|
||||||
|
|
||||||
settings: "Settings",
|
settings: "Settings",
|
||||||
|
details: "Details",
|
||||||
|
|
||||||
required: "Required field",
|
required: "Required field",
|
||||||
maxLength: "Max length {{length}}",
|
maxLength: "Max length {{length}}",
|
||||||
|
|
|
@ -144,11 +144,11 @@ export const DownloadDialog = ({
|
||||||
<StackItem isFilled>
|
<StackItem isFilled>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
fieldId="details"
|
fieldId="details"
|
||||||
label={t("clients:details")}
|
label={t("details")}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<HelpItem
|
<HelpItem
|
||||||
helpText={t("clients-help:details")}
|
helpText={t("clients-help:details")}
|
||||||
forLabel={t("clients:details")}
|
forLabel={t("details")}
|
||||||
forID="details"
|
forID="details"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,7 +331,7 @@ export const RealmRoleTabs = () => {
|
||||||
<KeycloakTabs isBox>
|
<KeycloakTabs isBox>
|
||||||
<Tab
|
<Tab
|
||||||
eventKey="details"
|
eventKey="details"
|
||||||
title={<TabTitleText>{t("details")}</TabTitleText>}
|
title={<TabTitleText>{t("common:details")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<RealmRoleForm
|
<RealmRoleForm
|
||||||
|
|
|
@ -22,7 +22,6 @@ export default {
|
||||||
roleDetails: "Role details",
|
roleDetails: "Role details",
|
||||||
composite: "Composite",
|
composite: "Composite",
|
||||||
deleteRole: "Delete this role",
|
deleteRole: "Delete this role",
|
||||||
details: "Details",
|
|
||||||
inheritedFrom: "Inherited from",
|
inheritedFrom: "Inherited from",
|
||||||
roleList: "Role list",
|
roleList: "Role list",
|
||||||
searchFor: "Search role by name",
|
searchFor: "Search role by name",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
ButtonVariant,
|
||||||
|
DropdownItem,
|
||||||
PageSection,
|
PageSection,
|
||||||
Tab,
|
Tab,
|
||||||
TabTitleText,
|
TabTitleText,
|
||||||
|
@ -20,10 +22,12 @@ import { UserGroups } from "./UserGroups";
|
||||||
import { UserConsents } from "./UserConsents";
|
import { UserConsents } from "./UserConsents";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { UserIdentityProviderLinks } from "./UserIdentityProviderLinks";
|
import { UserIdentityProviderLinks } from "./UserIdentityProviderLinks";
|
||||||
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { toUser } from "./routes/User";
|
import { toUser } from "./routes/User";
|
||||||
|
import { toUsers } from "./routes/Users";
|
||||||
|
|
||||||
export const UsersTabs = () => {
|
export const UsersTabs = () => {
|
||||||
const { t } = useTranslation("roles");
|
const { t } = useTranslation("users");
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
@ -70,7 +74,7 @@ export const UsersTabs = () => {
|
||||||
try {
|
try {
|
||||||
if (id) {
|
if (id) {
|
||||||
await adminClient.users.update({ id }, user);
|
await adminClient.users.update({ id }, user);
|
||||||
addAlert(t("users:userSaved"), AlertVariant.success);
|
addAlert(t("userSaved"), AlertVariant.success);
|
||||||
} else {
|
} else {
|
||||||
const createdUser = await adminClient.users.create(user);
|
const createdUser = await adminClient.users.create(user);
|
||||||
|
|
||||||
|
@ -81,7 +85,7 @@ export const UsersTabs = () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
addAlert(t("users:userCreated"), AlertVariant.success);
|
addAlert(t("userCreated"), AlertVariant.success);
|
||||||
history.push(toUser({ id: createdUser.id, realm, tab: "settings" }));
|
history.push(toUser({ id: createdUser.id, realm, tab: "settings" }));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -89,11 +93,61 @@ export const UsersTabs = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
||||||
|
titleKey: "users:deleteConfirm",
|
||||||
|
messageKey: "users:deleteConfirmCurrentUser",
|
||||||
|
continueButtonLabel: "common:delete",
|
||||||
|
continueButtonVariant: ButtonVariant.danger,
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
await adminClient.users.del({ id });
|
||||||
|
addAlert(t("userDeletedSuccess"), AlertVariant.success);
|
||||||
|
history.push(toUsers({ realm }));
|
||||||
|
} catch (error) {
|
||||||
|
addError("users:userDeletedError", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const [toggleImpersonateDialog, ImpersonateConfirm] = useConfirmDialog({
|
||||||
|
titleKey: "users:impersonateConfirm",
|
||||||
|
messageKey: "users:impersonateConfirmDialog",
|
||||||
|
continueButtonLabel: "users:impersonate",
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
const data = await adminClient.users.impersonation(
|
||||||
|
{ id },
|
||||||
|
{ user: id, realm }
|
||||||
|
);
|
||||||
|
if (data.sameRealm) {
|
||||||
|
window.location = data.redirect;
|
||||||
|
} else {
|
||||||
|
window.open(data.redirect, "_blank");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addError("users:impersonateError", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<ImpersonateConfirm />
|
||||||
|
<DeleteConfirm />
|
||||||
<ViewHeader
|
<ViewHeader
|
||||||
titleKey={user?.username || t("users:createUser")}
|
titleKey={user?.username || t("users:createUser")}
|
||||||
divider={!id}
|
divider={!id}
|
||||||
|
dropdownItems={[
|
||||||
|
<DropdownItem
|
||||||
|
key="impersonate"
|
||||||
|
onClick={() => toggleImpersonateDialog()}
|
||||||
|
>
|
||||||
|
{t("impersonate")}
|
||||||
|
</DropdownItem>,
|
||||||
|
<DropdownItem key="delete" onClick={() => toggleDeleteDialog()}>
|
||||||
|
{t("common:delete")}
|
||||||
|
</DropdownItem>,
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
<PageSection variant="light" className="pf-u-p-0">
|
<PageSection variant="light" className="pf-u-p-0">
|
||||||
<FormProvider {...userForm}>
|
<FormProvider {...userForm}>
|
||||||
|
@ -102,7 +156,7 @@ export const UsersTabs = () => {
|
||||||
<Tab
|
<Tab
|
||||||
eventKey="settings"
|
eventKey="settings"
|
||||||
data-testid="user-details-tab"
|
data-testid="user-details-tab"
|
||||||
title={<TabTitleText>{t("details")}</TabTitleText>}
|
title={<TabTitleText>{t("common:details")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
{bruteForced && (
|
{bruteForced && (
|
||||||
|
@ -118,14 +172,14 @@ export const UsersTabs = () => {
|
||||||
<Tab
|
<Tab
|
||||||
eventKey="groups"
|
eventKey="groups"
|
||||||
data-testid="user-groups-tab"
|
data-testid="user-groups-tab"
|
||||||
title={<TabTitleText>{t("groups")}</TabTitleText>}
|
title={<TabTitleText>{t("common:groups")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<UserGroups user={user} />
|
<UserGroups user={user} />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
eventKey="consents"
|
eventKey="consents"
|
||||||
data-testid="user-consents-tab"
|
data-testid="user-consents-tab"
|
||||||
title={<TabTitleText>{t("users:consents")}</TabTitleText>}
|
title={<TabTitleText>{t("consents")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<UserConsents />
|
<UserConsents />
|
||||||
</Tab>
|
</Tab>
|
||||||
|
@ -133,9 +187,7 @@ export const UsersTabs = () => {
|
||||||
eventKey="identity-provider-links"
|
eventKey="identity-provider-links"
|
||||||
data-testid="identity-provider-links-tab"
|
data-testid="identity-provider-links-tab"
|
||||||
title={
|
title={
|
||||||
<TabTitleText>
|
<TabTitleText>{t("identityProviderLinks")}</TabTitleText>
|
||||||
{t("users:identityProviderLinks")}
|
|
||||||
</TabTitleText>
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<UserIdentityProviderLinks />
|
<UserIdentityProviderLinks />
|
||||||
|
|
|
@ -46,8 +46,16 @@ export default {
|
||||||
notVerified: "Not verified",
|
notVerified: "Not verified",
|
||||||
requiredUserActions: "Required user actions",
|
requiredUserActions: "Required user actions",
|
||||||
addUser: "Add user",
|
addUser: "Add user",
|
||||||
|
impersonate: "Impersonate",
|
||||||
|
impersonateConfirm: "Impersonate user?",
|
||||||
|
impersonateConfirmDialog:
|
||||||
|
"Are you sure you want to log in as this user? If this user is in the same realm with you, your current login session will be logged out before you log in as this user.",
|
||||||
|
impersonateError: "Could not impersonate the user: {{error}}",
|
||||||
|
|
||||||
deleteUser: "Delete user",
|
deleteUser: "Delete user",
|
||||||
deleteConfirm: "Delete user?",
|
deleteConfirm: "Delete user?",
|
||||||
|
deleteConfirmCurrentUser:
|
||||||
|
"Are you sure you want to permanently delete this user",
|
||||||
deleteConfirmDialog:
|
deleteConfirmDialog:
|
||||||
"Are you sure you want to permanently delete {{count}} selected user",
|
"Are you sure you want to permanently delete {{count}} selected user",
|
||||||
deleteConfirmDialog_plural:
|
deleteConfirmDialog_plural:
|
||||||
|
|
Loading…
Reference in a new issue