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:
agagancarczyk 2021-11-30 16:18:47 +00:00 committed by GitHub
parent 61b2689864
commit 93ee81b6af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 139 additions and 3 deletions

View file

@ -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"

View file

@ -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}}",
},
};

View file

@ -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;
}