add create user page

This commit is contained in:
jenny-s51 2021-03-03 13:56:03 -05:00
parent d45bb1d5ad
commit 669c8d7377
4 changed files with 278 additions and 134 deletions

View file

@ -27,6 +27,7 @@ export type ViewHeaderProps = {
badge?: string;
badgeId?: string;
badgeIsRead?: boolean;
dividerComponent?: "div" | "hr" | "li" | undefined;
subKey: string;
actionsDropdownId?: string;
subKeyLinkProps?: FormattedLinkProps;
@ -43,6 +44,7 @@ export const ViewHeader = ({
badge,
badgeId,
badgeIsRead,
dividerComponent,
subKey,
subKeyLinkProps,
dropdownItems,
@ -157,7 +159,7 @@ export const ViewHeader = ({
/>
)}
</PageSection>
<Divider />
<Divider component={dividerComponent} />
</>
);
};

View file

@ -1,88 +1,226 @@
import React from "react";
import React, { useState } from "react";
import {
ActionGroup,
Button,
FormGroup,
Select,
SelectOption,
Switch,
TextArea,
TextInput,
// ValidatedOptions,
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { UseFormMethods } from "react-hook-form";
import { Controller, UseFormMethods } from "react-hook-form";
import { useHistory } from "react-router-dom";
import { FormAccess } from "../components/form-access/FormAccess";
import UserRepresentation from "keycloak-admin/lib/defs/userRepresentation";
// import { RoleFormType } from "./RealmRoleTabs";
import { HelpItem } from "../components/help-enabler/HelpItem";
import { useRealm } from "../context/realm-context/RealmContext";
export type UserFormProps = {
form: UseFormMethods<UserRepresentation>;
save: (user: UserRepresentation) => void;
editMode: boolean;
reset: () => void;
};
export const UserForm = ({
form,
save,
editMode,
reset,
}: UserFormProps) => {
export const UserForm = ({ form, save }: UserFormProps) => {
const { t } = useTranslation("users");
const { realm } = useRealm();
const [
isRequiredUserActionsDropdownOpen,
setRequiredUserActionsDropdownOpen,
] = useState(false);
const [selected, setSelected] = useState<string[]>([]);
const history = useHistory();
const requiredUserActionsOptions = [
<SelectOption key={0} value="Configure OTP">
{t("configureOTP")}
</SelectOption>,
<SelectOption key={1} value="Update Password">
{t("updatePassword")}
</SelectOption>,
<SelectOption key={2} value="Update Profile">
{t("updateProfile")}
</SelectOption>,
<SelectOption key={3} value="Verify Email">
{t("verifyEmail")}
</SelectOption>,
<SelectOption key={4} value="Update User Locale">
{t("updateUserLocale")}
</SelectOption>,
];
const clearSelection = () => {
setSelected([]);
setRequiredUserActionsDropdownOpen(false);
};
return (
<FormAccess
isHorizontal
onSubmit={form.handleSubmit(save)}
role="manage-realm"
role="manage-users"
className="pf-u-mt-lg"
>
<FormGroup
label={t("roleName")}
fieldId="kc-name"
label={t("username")}
fieldId="kc-username"
isRequired
// validated={form.errors.name ? "error" : "default"}
validated={form.errors.username ? "error" : "default"}
helperTextInvalid={t("common:required")}
>
<TextInput
ref={form.register({ required: !editMode })}
ref={form.register()}
type="text"
id="kc-name"
name="name"
isReadOnly={editMode}
id="kc-username"
name="username"
/>
</FormGroup>
<FormGroup
label={t("common:description")}
label={t("email")}
fieldId="kc-description"
// validated={
// form.errors.description
// ? ValidatedOptions.error
// : ValidatedOptions.default
// }
// helperTextInvalid={form.errors.description?.message}
validated={form.errors.email ? "error" : "default"}
helperTextInvalid={form.errors.email?.message}
>
<TextArea
name="description"
ref={form.register({
maxLength: {
value: 255,
message: t("common:maxLength", { length: 255 }),
},
})}
<TextInput
ref={form.register()}
type="text"
// validated={
// form.errors.description
// ? ValidatedOptions.error
// : ValidatedOptions.default
// }
id="kc-role-description"
id="kc-email"
name="email"
/>
</FormGroup>
<FormGroup
label={t("emailVerified")}
fieldId="kc-email-verified"
helperTextInvalid={t("common:required")}
labelIcon={
<HelpItem
helpText={t("emailVerifiedHelpText")}
forLabel={t("emailVerified")}
forID="email-verified"
/>
}
>
<Controller
name="user-email-verified"
defaultValue={false}
control={form.control}
render={({ onChange, value }) => (
<Switch
id={"kc-user-email-verified"}
isDisabled={false}
onChange={(value) => onChange([`${value}`])}
isChecked={value[0] === "true"}
label={t("common:on")}
labelOff={t("common:off")}
/>
)}
></Controller>
</FormGroup>
<FormGroup
label={t("firstName")}
fieldId="kc-firstname"
validated={form.errors.firstName ? "error" : "default"}
helperTextInvalid={t("common:required")}
>
<TextInput
ref={form.register()}
type="text"
id="kc-firstname"
name="firstname"
/>
</FormGroup>
<FormGroup
label={t("lastName")}
fieldId="kc-name"
validated={form.errors.lastName ? "error" : "default"}
>
<TextInput
ref={form.register()}
type="text"
id="kc-lastname"
name="lastname"
/>
</FormGroup>
<FormGroup
label={t("common:enabled")}
fieldId="kc-enabled"
labelIcon={
<HelpItem
helpText={t("disabledHelpText")}
forLabel={t("enabled")}
forID="enabled-label"
/>
}
>
<Controller
name="user-enabled"
defaultValue={false}
control={form.control}
render={({ onChange, value }) => (
<Switch
id={"kc-user-enabled"}
isDisabled={false}
onChange={(value) => onChange([`${value}`])}
isChecked={value[0] === "true"}
label={t("common:on")}
labelOff={t("common:off")}
/>
)}
></Controller>
</FormGroup>
<FormGroup
label={t("requiredUserActions")}
fieldId="kc-required-user-actions"
validated={form.errors.requiredActions ? "error" : "default"}
helperTextInvalid={t("common:required")}
labelIcon={
<HelpItem
helpText={t("requiredUserActionsHelpText")}
forLabel={t("requiredUserActions")}
forID="required-user-actions-label"
/>
}
>
<Controller
name="required-user-actions"
defaultValue={["0"]}
typeAheadAriaLabel="Select an action"
control={form.control}
render={() => (
<Select
placeholderText="Select action"
toggleId="kc-required-user-actions"
onToggle={() =>
setRequiredUserActionsDropdownOpen(
!isRequiredUserActionsDropdownOpen
)
}
isOpen={isRequiredUserActionsDropdownOpen}
selections={selected}
onSelect={(_, value) => {
const option = value as string;
if (selected.includes(option)) {
setSelected(selected.filter((item) => item !== option));
} else {
setSelected([...selected, option]);
}
}}
onClear={clearSelection}
variant="typeaheadmulti"
>
{requiredUserActionsOptions}
</Select>
)}
></Controller>
</FormGroup>
<ActionGroup>
<Button variant="primary" type="submit">
{t("common:save")}
{t("common:Create")}
</Button>
<Button onClick={() => reset()} variant="link">
{editMode ? t("common:reload") : t("common:cancel")}
<Button onClick={() => history.push(`/${realm}/users`)} variant="link">
{t("common:cancel")}
</Button>
</ActionGroup>
</FormAccess>

View file

@ -1,8 +1,6 @@
import React, { useEffect, useState } from "react";
import { useHistory, useParams, useRouteMatch } from "react-router-dom";
import {
PageSection,
} from "@patternfly/react-core";
import { Divider, PageSection } from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { useFieldArray, useForm } from "react-hook-form";
@ -16,104 +14,99 @@ import { UserForm } from "./UserForm";
export const UsersTabs = () => {
const { t } = useTranslation("roles");
const form = useForm<UserRepresentation>({ mode: "onChange" });
// const history = useHistory();
// const history = useHistory();
// const adminClient = useAdminClient();
// const [role, setRole] = useState<RoleFormType>();
// const adminClient = useAdminClient();
// const [role, setRole] = useState<RoleFormType>();
// const { id, clientId } = useParams<{ id: string; clientId: string }>();
// const { url } = useRouteMatch();
// const { id, clientId } = useParams<{ id: string; clientId: string }>();
// const { url } = useRouteMatch();
// const { realm } = useRealm();
// const { realm } = useRealm();
// const [key, setKey] = useState("");
// const [key, setKey] = useState("");
// const { addAlert } = useAlerts();
// const { addAlert } = useAlerts();
// const { fields, append, remove } = useFieldArray({
// control: form.control,
// name: "attributes",
// });
// const { fields, append, remove } = useFieldArray({
// control: form.control,
// name: "attributes",
// });
// useEffect(() => append({ key: "", value: "" }), [append, role]);
useEffect(() => append({ key: "", value: "" }), [append, role]);
// const save = async (user: UserRepresentation) => {
// try {
// const { attributes, ...rest } = role;
// const roleRepresentation: RoleRepresentation = rest;
// if (id) {
// if (attributes) {
// roleRepresentation.attributes = arrayToAttributes(attributes);
// }
// if (!clientId) {
// await adminClient.roles.updateById({ id }, roleRepresentation);
// } else {
// await adminClient.clients.updateRole(
// { id: clientId, roleName: role.name! },
// roleRepresentation
// );
// }
// const save = async (user: UserRepresentation) => {
// try {
// const { attributes, ...rest } = role;
// const roleRepresentation: RoleRepresentation = rest;
// if (id) {
// if (attributes) {
// roleRepresentation.attributes = arrayToAttributes(attributes);
// }
// if (!clientId) {
// await adminClient.roles.updateById({ id }, roleRepresentation);
// } else {
// await adminClient.clients.updateRole(
// { id: clientId, roleName: role.name! },
// roleRepresentation
// );
// }
// await adminClient.roles.createComposite(
// { roleId: id, realm },
// additionalRoles
// );
// await adminClient.roles.createComposite(
// { roleId: id, realm },
// additionalRoles
// );
// setRole(role);
// } else {
// let createdRole;
// if (!clientId) {
// await adminClient.roles.create(roleRepresentation);
// createdRole = await adminClient.roles.findOneByName({
// name: role.name!,
// });
// } else {
// await adminClient.clients.createRole({
// id: clientId,
// name: role.name,
// });
// if (role.description) {
// await adminClient.clients.updateRole(
// { id: clientId, roleName: role.name! },
// roleRepresentation
// );
// }
// createdRole = await adminClient.clients.findRole({
// id: clientId,
// roleName: role.name!,
// });
// }
// setRole(convert(createdRole));
// history.push(
// url.substr(0, url.lastIndexOf("/") + 1) + createdRole.id + "/details"
// );
// }
// addAlert(t(id ? "roleSaveSuccess" : "roleCreated"), AlertVariant.success);
// } catch (error) {
// addAlert(
// t((id ? "roleSave" : "roleCreate") + "Error", {
// error: error.response.data?.errorMessage || error,
// }),
// AlertVariant.danger
// );
// }
// };
// setRole(role);
// } else {
// let createdRole;
// if (!clientId) {
// await adminClient.roles.create(roleRepresentation);
// createdRole = await adminClient.roles.findOneByName({
// name: role.name!,
// });
// } else {
// await adminClient.clients.createRole({
// id: clientId,
// name: role.name,
// });
// if (role.description) {
// await adminClient.clients.updateRole(
// { id: clientId, roleName: role.name! },
// roleRepresentation
// );
// }
// createdRole = await adminClient.clients.findRole({
// id: clientId,
// roleName: role.name!,
// });
// }
// setRole(convert(createdRole));
// history.push(
// url.substr(0, url.lastIndexOf("/") + 1) + createdRole.id + "/details"
// );
// }
// addAlert(t(id ? "roleSaveSuccess" : "roleCreated"), AlertVariant.success);
// } catch (error) {
// addAlert(
// t((id ? "roleSave" : "roleCreate") + "Error", {
// error: error.response.data?.errorMessage || error,
// }),
// AlertVariant.danger
// );
// }
// };
return (
<>
<ViewHeader
titleKey={role?.name || t("createRole")}
subKey={id ? "" : "roles:roleCreateExplain"}
actionsDropdownId="roles-actions-dropdown"
/>
<ViewHeader titleKey={t("users:createUser")} subKey="" dividerComponent="div" />
<PageSection variant="light">
<UserForm
reset={() => form.reset()}
form={form}
save={save}
editMode={false}
/>
<UserForm
reset={() => form.reset()}
form={form}
save={() => {}}
editMode={false}
/>
</PageSection>
</>
);

View file

@ -10,18 +10,29 @@
"emptyInstructions": "Change your search criteria or add a user",
"username": "Username",
"email": "Email",
"emailVerified": "Email verified",
"lastName": "Last name",
"firstName": "First name",
"status": "Status",
"disabled": "Disabled",
"disabledHelpText": "A disabled user cannot log in.",
"emailVerifiedHelpText": "Has the user's email been verified?",
"temporaryDisabled": "Temporarily disabled",
"notVerified": "Not verified",
"requiredUserActions": "Required user actions",
"requiredUserActionsHelpText": "Require an action when the user logs in. 'Verify email' sends an email to the user to verify their email address. 'Update profile' requires user to enter in new personal information. 'Update password' requires user to enter in a new password. 'Configure OTP' requires setup of a mobile password generator.",
"addUser": "Add user",
"deleteUser": "Delete user",
"deleteConfirm": "Delete user?",
"deleteConfirmDialog": "Are you sure you want to permanently delete {{count}} selected user",
"deleteConfirmDialog_plural": "Are you sure you want to permanently delete {{count}} selected users",
"userDeletedSuccess": "The user has been deleted",
"userDeletedError": "The user could not be deleted {{error}}"
"userDeletedError": "The user could not be deleted {{error}}",
"configureOTP": "Configure OTP",
"updatePassword": "Update Password",
"updateProfile": "Update Profile",
"verifyEmail": "Verify Email",
"updateUserLocale": "Update User Locale"
}
}