ui(admin): add role select for user management

This commit is contained in:
Matthew Penner 2021-07-25 15:51:39 -06:00
parent 58f0bbbb9b
commit 25feeaa9f5
16 changed files with 202 additions and 52 deletions

View file

@ -37,7 +37,7 @@ export default () => {
<FlashMessageRender byKey={'user:create'} css={tw`mb-4`}/>
<InformationContainer title={'Create User'} onSubmit={submit}/>
<InformationContainer title={'Create User'} onSubmit={submit} role={null}/>
</AdminContentBlock>
);
};

View file

@ -0,0 +1,55 @@
import React, { useState } from 'react';
import { useFormikContext } from 'formik';
import { Role } from '@/api/admin/roles/getRoles';
import searchRoles from '@/api/admin/roles/searchRoles';
import SearchableSelect, { Option } from '@/components/elements/SearchableSelect';
export default ({ selected }: { selected: Role | null }) => {
const context = useFormikContext();
const [ role, setRole ] = useState<Role | null>(selected);
const [ roles, setRoles ] = useState<Role[] | null>(null);
const onSearch = (query: string): Promise<void> => {
return new Promise((resolve, reject) => {
searchRoles({ name: query })
.then(roles => {
setRoles(roles);
return resolve();
})
.catch(reject);
});
};
const onSelect = (role: Role | null) => {
setRole(role);
context.setFieldValue('adminRoleId', role?.id || null);
};
const getSelectedText = (role: Role | null): string | undefined => {
return role?.name;
};
return (
<SearchableSelect
id={'adminRoleId'}
name={'adminRoleId'}
label={'Role'}
placeholder={'Select a role...'}
items={roles}
selected={role}
setSelected={setRole}
setItems={setRoles}
onSearch={onSearch}
onSelect={onSelect}
getSelectedText={getSelectedText}
nullable
>
{roles?.map(d => (
<Option key={d.id} selectId={'adminRoleId'} id={d.id} item={d} active={d.id === role?.id}>
{d.name}
</Option>
))}
</SearchableSelect>
);
};

View file

@ -12,9 +12,11 @@ import AdminBox from '@/components/admin/AdminBox';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import { Form, Formik, FormikHelpers } from 'formik';
import { object, string } from 'yup';
import Field from '@/components/elements/Field';
import Button from '@/components/elements/Button';
import { Role } from '@/api/admin/roles/getRoles';
import updateUser, { Values } from '@/api/admin/users/updateUser';
import Button from '@/components/elements/Button';
import Field from '@/components/elements/Field';
import RoleSelect from '@/components/admin/users/RoleSelect';
import UserDeleteButton from '@/components/admin/users/UserDeleteButton';
interface ctx {
@ -37,9 +39,11 @@ export interface Params {
onSubmit: (values: Values, helpers: FormikHelpers<Values>) => void;
exists?: boolean;
role: Role | null;
}
export function InformationContainer ({ title, initialValues, children, onSubmit, exists }: Params) {
export function InformationContainer ({ title, initialValues, children, onSubmit, exists, role }: Params) {
const submit = (values: Values, helpers: FormikHelpers<Values>) => {
onSubmit(values, helpers);
};
@ -51,7 +55,7 @@ export function InformationContainer ({ title, initialValues, children, onSubmit
firstName: '',
lastName: '',
password: '',
roleId: 0,
adminRoleId: 0,
};
}
@ -126,7 +130,9 @@ export function InformationContainer ({ title, initialValues, children, onSubmit
/>
</div>
<div css={tw`md:w-full md:flex md:flex-col md:ml-4 mt-6 md:mt-0`}/>
<div css={tw`md:w-full md:flex md:flex-col md:ml-4 mt-6 md:mt-0`}>
<RoleSelect selected={role}/>
</div>
</div>
<div css={tw`w-full flex flex-row items-center mt-6`}>
@ -180,10 +186,11 @@ function EditInformationContainer () {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
roleId: user.roleId,
adminRoleId: user.adminRoleId,
password: '',
}}
onSubmit={submit}
role={user?.relationships.role || null}
exists
>
<div css={tw`flex`}>
@ -208,7 +215,7 @@ function UserEditContainer () {
useEffect(() => {
clearFlashes('user');
getUser(Number(match.params?.id))
getUser(Number(match.params?.id), [ 'role' ])
.then(user => setUser(user))
.catch(error => {
console.error(error);