User label cred edit (#1624)
* user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * user credentials - wip * added deleting credentials * replaced DataList with Table * added reset password - wip * added reset password * added show data dialog - wip * added show data dialog - wip * added password data dialog * added few translations * added sorting to password data * tidied up * clean up rows code * feedback fixes * editanle user label - wip * editanle user label - wip * editable user label - wip * editable user label - wip * editable user label - wip * editable user label - final * added extra check for credentialId Co-authored-by: Agnieszka Gancarczyk <agancarc@redhat.com> Co-authored-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
parent
61b2689864
commit
93ee81b6af
3 changed files with 139 additions and 3 deletions
|
@ -13,6 +13,7 @@ import {
|
|||
ModalVariant,
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
TextVariants,
|
||||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
|
@ -28,6 +29,7 @@ import {
|
|||
Thead,
|
||||
Tr,
|
||||
} from "@patternfly/react-table";
|
||||
import { PencilAltIcon, CheckIcon, TimesIcon } from "@patternfly/react-icons";
|
||||
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
@ -40,6 +42,7 @@ import { HelpItem } from "../components/help-enabler/HelpItem";
|
|||
import "./user-section.css";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import type CredentialRepresentation from "@keycloak/keycloak-admin-client/lib/defs/credentialRepresentation";
|
||||
import { FormAccess } from "../components/form-access/FormAccess";
|
||||
|
||||
type UserCredentialsProps = {
|
||||
user: UserRepresentation;
|
||||
|
@ -51,7 +54,7 @@ type CredentialsForm = {
|
|||
temporaryPassword: boolean;
|
||||
};
|
||||
|
||||
const defaultValues: CredentialsForm = {
|
||||
const credFormDefaultValues: CredentialsForm = {
|
||||
password: "",
|
||||
passwordConfirmation: "",
|
||||
temporaryPassword: true,
|
||||
|
@ -62,6 +65,14 @@ type DisplayDialogProps = {
|
|||
onClose: () => void;
|
||||
};
|
||||
|
||||
type UserLabelForm = {
|
||||
userLabel: string;
|
||||
};
|
||||
|
||||
const userLabelDefaultValues: UserLabelForm = {
|
||||
userLabel: "",
|
||||
};
|
||||
|
||||
const DisplayDialog: FunctionComponent<DisplayDialogProps> = ({
|
||||
titleKey,
|
||||
onClose,
|
||||
|
@ -90,8 +101,18 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
const [openSaveConfirm, setOpenSaveConfirm] = useState(false);
|
||||
const [kebabOpen, setKebabOpen] = useState(false);
|
||||
const adminClient = useAdminClient();
|
||||
const form = useForm<CredentialsForm>({ defaultValues });
|
||||
const form = useForm<CredentialsForm>({
|
||||
defaultValues: credFormDefaultValues,
|
||||
});
|
||||
const userLabelForm = useForm<UserLabelForm>({
|
||||
defaultValues: userLabelDefaultValues,
|
||||
});
|
||||
const { control, errors, handleSubmit, register } = form;
|
||||
const {
|
||||
getValues: getValues1,
|
||||
handleSubmit: handleSubmit1,
|
||||
register: register1,
|
||||
} = userLabelForm;
|
||||
const [credentials, setCredentials] = useState<CredentialsForm>();
|
||||
const [userCredentials, setUserCredentials] = useState<
|
||||
CredentialRepresentation[]
|
||||
|
@ -100,6 +121,9 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
useState<CredentialRepresentation>({});
|
||||
const [isResetPassword, setIsResetPassword] = useState(false);
|
||||
const [showData, setShowData] = useState(false);
|
||||
const [isUserLabelEdit, setIsUserLabelEdit] = useState(false);
|
||||
const [editedUserCredential, setEditedUserCredential] =
|
||||
useState<CredentialRepresentation>({});
|
||||
|
||||
useFetch(
|
||||
() => adminClient.users.getCredentials({ id: user.id! }),
|
||||
|
@ -218,6 +242,30 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
});
|
||||
}, [selectedCredential.credentialData]);
|
||||
|
||||
const saveUserLabel = async () => {
|
||||
const userLabelFormValue = getValues1();
|
||||
|
||||
if (Object.keys(editedUserCredential).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await adminClient.users.updateCredentialLabel(
|
||||
{
|
||||
id: user.id!,
|
||||
credentialId: editedUserCredential.id!,
|
||||
},
|
||||
userLabelFormValue.userLabel || ""
|
||||
);
|
||||
refresh();
|
||||
addAlert(t("updateCredentialUserLabelSuccess"), AlertVariant.success);
|
||||
setIsUserLabelEdit(false);
|
||||
} catch (error) {
|
||||
addError(t("updateCredentialUserLabelError"), error);
|
||||
setIsUserLabelEdit(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{open && (
|
||||
|
@ -439,7 +487,63 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
{credential.type?.charAt(0).toUpperCase()! +
|
||||
credential.type?.slice(1)}
|
||||
</Td>
|
||||
<Td>My Password</Td>
|
||||
<Td>
|
||||
<FormAccess isHorizontal role="view-users">
|
||||
<FormGroup
|
||||
fieldId="kc-userLabel"
|
||||
className="kc-userLabel-row"
|
||||
>
|
||||
<div className="kc-form-group-userLabel">
|
||||
{isUserLabelEdit ? (
|
||||
<>
|
||||
<TextInput
|
||||
name="userLabel"
|
||||
ref={register1()}
|
||||
type="text"
|
||||
className="kc-userLabel"
|
||||
aria-label={t("userLabel")}
|
||||
data-testid="user-label-fld"
|
||||
/>
|
||||
<div className="kc-userLabel-actionBtns">
|
||||
<Button
|
||||
key={"key-acceptBtn"}
|
||||
variant="link"
|
||||
className="kc-editUserLabel-acceptBtn"
|
||||
onClick={() => {
|
||||
setEditedUserCredential(credential);
|
||||
handleSubmit1(saveUserLabel)();
|
||||
setIsUserLabelEdit(false);
|
||||
}}
|
||||
data-testid="editUserLabel-acceptBtn"
|
||||
icon={<CheckIcon />}
|
||||
/>
|
||||
<Button
|
||||
key={"key-cancelBtn"}
|
||||
variant="link"
|
||||
className="kc-editUserLabel-cancelBtn"
|
||||
onClick={() => setIsUserLabelEdit(false)}
|
||||
data-testid="editUserLabel-cancelBtn"
|
||||
icon={<TimesIcon />}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{credential.userLabel ?? ""}
|
||||
<Button
|
||||
key={"key"}
|
||||
variant="link"
|
||||
className="kc-editUserLabel-btn"
|
||||
onClick={() => setIsUserLabelEdit(true)}
|
||||
data-testid="editUserLabelBtn"
|
||||
icon={<PencilAltIcon />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</FormAccess>
|
||||
</Td>
|
||||
<Td>
|
||||
<Button
|
||||
className="kc-showData-btn"
|
||||
|
|
|
@ -166,5 +166,8 @@ export default {
|
|||
userLabel: "User label",
|
||||
data: "Data",
|
||||
passwordDataTitle: "Password data",
|
||||
updateCredentialUserLabelSuccess:
|
||||
"The user label has been changed successfully.",
|
||||
updateCredentialUserLabelError: "Error changing user label: {{error}}",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -145,3 +145,32 @@ article.pf-c-card.pf-m-flat.kc-available-idps > div > div > h1 {
|
|||
.kc-showData-btn {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.kc-userLabel-row {
|
||||
display: inline-block !important;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.kc-form-group-userLabel, .kc-userLabel-actionBtns {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.kc-editUserLabel-btn, .kc-editUserLabel-cancelBtn {
|
||||
color: var(--pf-global--Color--200) !important;
|
||||
}
|
||||
|
||||
.kc-editUserLabel-btn {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.kc-editUserLabel-btn:hover {
|
||||
filter: brightness(55%);
|
||||
}
|
||||
|
||||
.kc-editUserLabel-acceptBtn {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.kc-editUserLabel-cancelBtn {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue