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:
parent
d7973a8008
commit
4d4dfe0308
2 changed files with 105 additions and 28 deletions
|
@ -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>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue