Multiple credentials (#1642)

* fixed user label editing bug

* fixed user label editing bug

* feedback

* fixed table

* fixed opening edit input per row

* fixed opening dropdown per row

* fixed closing dropdown per row

* feedback fixes

* added set password btn into credentials table

Co-authored-by: Agnieszka Gancarczyk <agancarc@redhat.com>
This commit is contained in:
agagancarczyk 2021-12-06 09:52:05 +00:00 committed by GitHub
parent d7973a8008
commit 4d4dfe0308
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 28 deletions

View file

@ -3,6 +3,7 @@ import {
AlertVariant, AlertVariant,
Button, Button,
ButtonVariant, ButtonVariant,
Divider,
Dropdown, Dropdown,
DropdownItem, DropdownItem,
DropdownPosition, DropdownPosition,
@ -99,7 +100,10 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
const refresh = () => setKey(key + 1); const refresh = () => setKey(key + 1);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [openSaveConfirm, setOpenSaveConfirm] = useState(false); const [openSaveConfirm, setOpenSaveConfirm] = useState(false);
const [kebabOpen, setKebabOpen] = useState(false); const [kebabOpen, setKebabOpen] = useState({
status: false,
rowKey: "",
});
const adminClient = useAdminClient(); const adminClient = useAdminClient();
const form = useForm<CredentialsForm>({ const form = useForm<CredentialsForm>({
defaultValues: credFormDefaultValues, defaultValues: credFormDefaultValues,
@ -121,9 +125,12 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
useState<CredentialRepresentation>({}); useState<CredentialRepresentation>({});
const [isResetPassword, setIsResetPassword] = useState(false); const [isResetPassword, setIsResetPassword] = useState(false);
const [showData, setShowData] = useState(false); const [showData, setShowData] = useState(false);
const [isUserLabelEdit, setIsUserLabelEdit] = useState(false);
const [editedUserCredential, setEditedUserCredential] = const [editedUserCredential, setEditedUserCredential] =
useState<CredentialRepresentation>({}); useState<CredentialRepresentation>({});
const [isUserLabelEdit, setIsUserLabelEdit] = useState<{
status: boolean;
rowKey: string;
}>();
useFetch( useFetch(
() => adminClient.users.getCredentials({ id: user.id! }), () => adminClient.users.getCredentials({ id: user.id! }),
@ -133,6 +140,10 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
[key] [key]
); );
const passwordTypeFinder = userCredentials.find(
(credential) => credential.type === "password"
);
const passwordWatcher = useWatch<CredentialsForm["password"]>({ const passwordWatcher = useWatch<CredentialsForm["password"]>({
control, control,
name: "password", name: "password",
@ -192,7 +203,9 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
setOpenSaveConfirm(false); setOpenSaveConfirm(false);
} catch (error) { } catch (error) {
addError( addError(
isResetPassword ? t("resetPasswordError") : t("savePasswordError"), isResetPassword
? "users:resetPasswordError"
: "users:savePasswordError",
error error
); );
} }
@ -218,7 +231,7 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
addAlert(t("deleteCredentialsSuccess"), AlertVariant.success); addAlert(t("deleteCredentialsSuccess"), AlertVariant.success);
setKey((key) => key + 1); setKey((key) => key + 1);
} catch (error) { } catch (error) {
addError(t("deleteCredentialsError"), error); addError("users:deleteCredentialsError", error);
} }
}, },
}); });
@ -265,10 +278,13 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
addAlert(t("updateCredentialUserLabelSuccess"), AlertVariant.success); addAlert(t("updateCredentialUserLabelSuccess"), AlertVariant.success);
setEditedUserCredential({}); setEditedUserCredential({});
} catch (error) { } catch (error) {
addError(t("updateCredentialUserLabelError"), error); addError("users:updateCredentialUserLabelError", error);
} }
setIsUserLabelEdit(false); setIsUserLabelEdit({
status: false,
rowKey: credentialToEdit.id!,
});
}; };
return ( return (
@ -459,6 +475,23 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
</Table> </Table>
</DisplayDialog> </DisplayDialog>
)} )}
{userCredentials.length !== 0 && passwordTypeFinder === undefined && (
<>
<Button
key={`confirmSaveBtn-table-${user.id}`}
className="setPasswordBtn-table"
data-testid="setPasswordBtn-table"
variant="primary"
form="userCredentials-form"
onClick={() => {
setOpen(true);
}}
>
{t("savePassword")}
</Button>
<Divider />
</>
)}
{userCredentials.length !== 0 ? ( {userCredentials.length !== 0 ? (
<TableComposable aria-label="password-data-table" variant={"compact"}> <TableComposable aria-label="password-data-table" variant={"compact"}>
<Thead> <Thead>
@ -480,15 +513,18 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
<Tr> {userCredentials.map((credential) => (
{userCredentials.map((credential) => ( <Tr key={`table-${credential.id}`}>
<> <>
<Td <Td
draggableRow={{ draggableRow={{
id: `draggable-row-${credential.id}`, id: `draggable-row-${credential.id}`,
}} }}
/> />
<Td key={`${credential}`} dataLabel={`columns-${credential}`}> <Td
key={`table-item-${credential.id}`}
dataLabel={`columns-${credential.id}`}
>
{credential.type?.charAt(0).toUpperCase()! + {credential.type?.charAt(0).toUpperCase()! +
credential.type?.slice(1)} credential.type?.slice(1)}
</Td> </Td>
@ -499,7 +535,8 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
className="kc-userLabel-row" className="kc-userLabel-row"
> >
<div className="kc-form-group-userLabel"> <div className="kc-form-group-userLabel">
{isUserLabelEdit ? ( {isUserLabelEdit?.status &&
isUserLabelEdit.rowKey === credential.id ? (
<> <>
<TextInput <TextInput
name="userLabel" name="userLabel"
@ -511,19 +548,29 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
/> />
<div className="kc-userLabel-actionBtns"> <div className="kc-userLabel-actionBtns">
<Button <Button
key={`editUserLabel-accept-${credential.id}`}
variant="link" variant="link"
className="kc-editUserLabel-acceptBtn" className="kc-editUserLabel-acceptBtn"
onClick={() => { onClick={() => {
handleSubmit1(saveUserLabel)(); handleSubmit1(saveUserLabel)();
setIsUserLabelEdit(false); setIsUserLabelEdit({
status: false,
rowKey: credential.id!,
});
}} }}
data-testid="editUserLabel-acceptBtn" data-testid="editUserLabel-acceptBtn"
icon={<CheckIcon />} icon={<CheckIcon />}
/> />
<Button <Button
key={`editUserLabel-cancel-${credential.id}`}
variant="link" variant="link"
className="kc-editUserLabel-cancelBtn" className="kc-editUserLabel-cancelBtn"
onClick={() => setIsUserLabelEdit(false)} onClick={() =>
setIsUserLabelEdit({
status: false,
rowKey: credential.id!,
})
}
data-testid="editUserLabel-cancelBtn" data-testid="editUserLabel-cancelBtn"
icon={<TimesIcon />} icon={<TimesIcon />}
/> />
@ -533,11 +580,15 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
<> <>
{credential.userLabel ?? ""} {credential.userLabel ?? ""}
<Button <Button
key={`editUserLabel-${credential.id}`}
variant="link" variant="link"
className="kc-editUserLabel-btn" className="kc-editUserLabel-btn"
onClick={() => { onClick={() => {
setEditedUserCredential(credential); setEditedUserCredential(credential);
setIsUserLabelEdit(true); setIsUserLabelEdit({
status: true,
rowKey: credential.id!,
});
}} }}
data-testid="editUserLabelBtn" data-testid="editUserLabelBtn"
icon={<PencilAltIcon />} icon={<PencilAltIcon />}
@ -561,24 +612,39 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
{t("showDataBtn")} {t("showDataBtn")}
</Button> </Button>
</Td> </Td>
<Td> {credential.type === "password" ? (
<Button <Td>
variant="secondary" <Button
data-testid="resetPasswordBtn" variant="secondary"
onClick={resetPassword} data-testid="resetPasswordBtn"
> onClick={resetPassword}
{t("resetPasswordBtn")} >
</Button> {t("resetPasswordBtn")}
</Td> </Button>
</Td>
) : (
<Td />
)}
<Td> <Td>
<Dropdown <Dropdown
isPlain isPlain
position={DropdownPosition.right} position={DropdownPosition.right}
toggle={ toggle={
<KebabToggle onToggle={(open) => setKebabOpen(open)} /> <KebabToggle
onToggle={(status) =>
setKebabOpen({
status,
rowKey: credential.id!,
})
}
/>
} }
isOpen={kebabOpen} isOpen={
onSelect={() => setSelectedCredential(credential)} kebabOpen.status && kebabOpen.rowKey === credential.id
}
onSelect={() => {
setSelectedCredential(credential);
}}
dropdownItems={[ dropdownItems={[
<DropdownItem <DropdownItem
key={`delete-dropdown-item-${credential.id}`} key={`delete-dropdown-item-${credential.id}`}
@ -586,7 +652,10 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
component="button" component="button"
onClick={() => { onClick={() => {
toggleDeleteDialog(); toggleDeleteDialog();
setKebabOpen(false); setKebabOpen({
status: false,
rowKey: credential.id!,
});
}} }}
> >
{t("deleteBtn")} {t("deleteBtn")}
@ -595,8 +664,8 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
/> />
</Td> </Td>
</> </>
))} </Tr>
</Tr> ))}
</Tbody> </Tbody>
</TableComposable> </TableComposable>
) : ( ) : (

View file

@ -174,3 +174,11 @@ article.pf-c-card.pf-m-flat.kc-available-idps > div > div > h1 {
.kc-editUserLabel-cancelBtn { .kc-editUserLabel-cancelBtn {
padding-left: 8px !important; padding-left: 8px !important;
} }
.pf-c-table.pf-m-compact tr:not(.pf-c-table__expandable-row)>:last-child {
overflow-wrap: anywhere;
}
.setPasswordBtn-table {
margin: 25px 0 25px 25px;
}