codegen.yml: the ID scalar should be a number | add edit user functionality

This commit is contained in:
Dawid Wysokiński 2021-03-12 11:17:14 +01:00
parent 2f73ef1b62
commit f0782f143f
5 changed files with 292 additions and 251 deletions

View File

@ -6,4 +6,6 @@ generates:
- "typescript"
- "typescript-operations"
config:
skipTypename: true
skipTypename: true
scalars:
ID: number

View File

@ -7,7 +7,13 @@ import {
} from 'use-query-params';
import SortParam, { decodeSort } from 'libs/serialize-query-params/SortParam';
import useUsers from './UsersPage.useUsers';
import { MutationCreateUserArgs, UserInput } from 'libs/graphql/types';
import {
Maybe,
MutationCreateUserArgs,
MutationUpdateUserArgs,
User,
UserInput,
} from 'libs/graphql/types';
import { validateRowsPerPage } from 'common/Table/helpers';
import { COLUMNS, DEFAULT_SORT, DialogType } from './constants';
@ -17,7 +23,7 @@ import Table from 'common/Table/Table';
import TableToolbar from './components/TableToolbar/TableToolbar';
import FormDialog from './components/FormDialog/FormDialog';
import { ApolloError, useMutation } from '@apollo/client';
import { MUTATION_CREATE_USER } from './mutations';
import { MUTATION_CREATE_USER, MUTATION_UPDATE_USER } from './mutations';
import { useSnackbar } from 'material-ui-snackbar-provider';
const UsersPage = () => {
@ -25,7 +31,12 @@ const UsersPage = () => {
MUTATION_CREATE_USER,
{ ignoreResults: true }
);
const [updateUserMutation] = useMutation<any, MutationUpdateUserArgs>(
MUTATION_UPDATE_USER,
{ ignoreResults: true }
);
const [dialogType, setDialogType] = useState<DialogType>(DialogType.None);
const [userBeingEdited, setUserBeingEdited] = useState<Maybe<User>>(null);
const snackbar = useSnackbar();
const [{ page, sort, search, ...rest }, setQueryParams] = useQueryParams({
limit: NumberParam,
@ -41,9 +52,15 @@ const UsersPage = () => {
search
);
const handleCreateUser = async (input: UserInput) => {
const handleFormDialogSubmit = async (input: UserInput) => {
try {
await createUserMutation({ variables: { input } });
if (dialogType === DialogType.Create) {
await createUserMutation({ variables: { input } });
} else {
await updateUserMutation({
variables: { input, id: userBeingEdited?.id ?? -1 },
});
}
await refetch();
return true;
} catch (e) {
@ -61,7 +78,10 @@ const UsersPage = () => {
<Paper>
<TableToolbar
search={search}
onClickCreateUser={() => setDialogType(DialogType.Create)}
onClickCreateUser={() => {
setUserBeingEdited(null);
setDialogType(DialogType.Create);
}}
onChangeSearchValue={val => {
setQueryParams({ page: 0, search: val });
}}
@ -74,7 +94,12 @@ const UsersPage = () => {
{
icon: row => {
return (
<IconButton>
<IconButton
onClick={() => {
setUserBeingEdited(row);
setDialogType(DialogType.Edit);
}}
>
<EditIcon />
</IconButton>
);
@ -108,7 +133,8 @@ const UsersPage = () => {
open={
dialogType === DialogType.Create || dialogType === DialogType.Edit
}
onSubmit={handleCreateUser}
user={userBeingEdited as UserInput}
onSubmit={handleFormDialogSubmit}
onClose={() => setDialogType(DialogType.None)}
/>
</Container>

View File

@ -37,9 +37,7 @@ export interface FormDialogProps extends Pick<DialogProps, 'open'> {
const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
const editMode = Boolean(user);
const { register, handleSubmit, errors } = useForm<UserInput>({
defaultValues: user,
});
const { register, handleSubmit, errors } = useForm<UserInput>({});
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
const classes = useStyles();
@ -52,10 +50,9 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
)
: data;
const success = await onSubmit(filtered);
setIsSubmitting(false);
if (success) {
onClose();
} else {
setIsSubmitting(false);
}
};
@ -75,6 +72,7 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
fullWidth
label="Nazwa użytkownika"
name="displayName"
defaultValue={user?.displayName}
inputRef={register({
required: 'Te pole jest wymagane.',
minLength: {
@ -93,6 +91,7 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
fullWidth
label="Adres e-mail"
name="email"
defaultValue={user?.email}
inputRef={register({
required: 'Te pole jest wymagane.',
validate: (email: string) => {
@ -110,7 +109,7 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
type="password"
name="password"
inputRef={register({
required: 'Te pole jest wymagane.',
required: editMode ? false : 'Te pole jest wymagane.',
minLength: {
value: MIN_PASSWORD_LENGTH,
message: `Hasło musi zawierać co najmniej ${MIN_PASSWORD_LENGTH} znaków.`,
@ -125,7 +124,7 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
/>
<FormControl>
<FormLabel>Rola</FormLabel>
<RadioGroup name="role" defaultValue={Role.User}>
<RadioGroup name="role" defaultValue={user?.role ?? Role.User}>
{[Role.Admin, Role.User].map(role => {
return (
<FormControlLabel
@ -141,7 +140,13 @@ const FormDialog = ({ open, onClose, user, onSubmit }: FormDialogProps) => {
</FormControl>
<FormGroup>
<FormControlLabel
control={<Checkbox inputRef={register} name="activated" />}
control={
<Checkbox
inputRef={register}
name="activated"
defaultChecked={user?.activated ?? false}
/>
}
label="Aktywowany"
/>
</FormGroup>

View File

@ -7,3 +7,11 @@ export const MUTATION_CREATE_USER = gql`
}
}
`;
export const MUTATION_UPDATE_USER = gql`
mutation updateUser($id: ID!, $input: UserInput!) {
updateUser(id: $id, input: $input) {
id
}
}
`;

View File

@ -4,7 +4,7 @@ export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?:
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
ID: number;
String: string;
Boolean: boolean;
Int: number;
@ -16,6 +16,28 @@ export type Scalars = {
export type UpdateManyUsersInput = {
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type QualificationFilterOr = {
nameMatch?: Maybe<Scalars['String']>;
nameIEQ?: Maybe<Scalars['String']>;
codeMatch?: Maybe<Scalars['String']>;
codeIEQ?: Maybe<Scalars['String']>;
};
export type QuestionList = {
total: Scalars['Int'];
items?: Maybe<Array<Question>>;
};
export type ProfessionList = {
total: Scalars['Int'];
items?: Maybe<Array<Profession>>;
};
export type QuestionInput = {
content?: Maybe<Scalars['String']>;
from?: Maybe<Scalars['String']>;
@ -38,173 +60,6 @@ export type QuestionInput = {
deleteAnswerDImage?: Maybe<Scalars['Boolean']>;
};
export type Profession = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
};
export type ProfessionInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
};
export type ProfessionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type Question = {
id: Scalars['ID'];
from?: Maybe<Scalars['String']>;
content: Scalars['String'];
explanation?: Maybe<Scalars['String']>;
correctAnswer: Answer;
image?: Maybe<Scalars['String']>;
answerA?: Maybe<Answer>;
answerAImage?: Maybe<Scalars['String']>;
answerB?: Maybe<Answer>;
answerBImage?: Maybe<Scalars['String']>;
answerC?: Maybe<Answer>;
answerCImage?: Maybe<Scalars['String']>;
answerD?: Maybe<Answer>;
answerDImage?: Maybe<Scalars['String']>;
qualification?: Maybe<Qualification>;
createdAt: Scalars['Time'];
updatedAt: Scalars['Time'];
};
export type QualificationList = {
total: Scalars['Int'];
items?: Maybe<Array<Qualification>>;
};
export enum Role {
Admin = 'admin',
User = 'user'
}
export type QualificationFilterOr = {
nameMatch?: Maybe<Scalars['String']>;
nameIEQ?: Maybe<Scalars['String']>;
codeMatch?: Maybe<Scalars['String']>;
codeIEQ?: Maybe<Scalars['String']>;
};
export type QualificationFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
formula?: Maybe<Array<Scalars['String']>>;
formulaNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
code?: Maybe<Array<Scalars['String']>>;
codeNEQ?: Maybe<Array<Scalars['String']>>;
codeIEQ?: Maybe<Scalars['String']>;
codeMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
professionID?: Maybe<Array<Scalars['Int']>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
or?: Maybe<QualificationFilterOr>;
};
export type User = {
id: Scalars['ID'];
displayName: Scalars['String'];
role: Role;
email: Scalars['String'];
activated: Scalars['Boolean'];
createdAt: Scalars['Time'];
};
export type QualificationInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
code?: Maybe<Scalars['String']>;
formula?: Maybe<Scalars['String']>;
associateProfession?: Maybe<Array<Scalars['Int']>>;
dissociateProfession?: Maybe<Array<Scalars['Int']>>;
};
export type UserFilterOr = {
displayNameIEQ?: Maybe<Scalars['String']>;
displayNameMATCH?: Maybe<Scalars['String']>;
emailIEQ?: Maybe<Scalars['String']>;
emailMATCH?: Maybe<Scalars['String']>;
};
export type UserList = {
total: Scalars['Int'];
items?: Maybe<Array<User>>;
};
export type UserInput = {
displayName?: Maybe<Scalars['String']>;
password?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type ProfessionList = {
total: Scalars['Int'];
items?: Maybe<Array<Profession>>;
};
export enum Answer {
A = 'a',
B = 'b',
C = 'c',
D = 'd'
}
export type QuestionList = {
total: Scalars['Int'];
items?: Maybe<Array<Question>>;
};
export type QuestionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
from?: Maybe<Array<Scalars['String']>>;
contentIEQ?: Maybe<Scalars['String']>;
contentMATCH?: Maybe<Scalars['String']>;
qualificationID?: Maybe<Array<Scalars['Int']>>;
qualificationIDNEQ?: Maybe<Array<Scalars['Int']>>;
qualificationFilter?: Maybe<QualificationFilter>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type UserFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
@ -227,11 +82,164 @@ export type UserFilter = {
or?: Maybe<UserFilterOr>;
};
export type Profession = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
};
export enum Answer {
A = 'a',
B = 'b',
C = 'c',
D = 'd'
}
export type QuestionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
from?: Maybe<Array<Scalars['String']>>;
contentIEQ?: Maybe<Scalars['String']>;
contentMATCH?: Maybe<Scalars['String']>;
qualificationID?: Maybe<Array<Scalars['Int']>>;
qualificationIDNEQ?: Maybe<Array<Scalars['Int']>>;
qualificationFilter?: Maybe<QualificationFilter>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type UserFilterOr = {
displayNameIEQ?: Maybe<Scalars['String']>;
displayNameMATCH?: Maybe<Scalars['String']>;
emailIEQ?: Maybe<Scalars['String']>;
emailMATCH?: Maybe<Scalars['String']>;
};
export type ProfessionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type QualificationList = {
total: Scalars['Int'];
items?: Maybe<Array<Qualification>>;
};
export type Question = {
id: Scalars['ID'];
from?: Maybe<Scalars['String']>;
content: Scalars['String'];
explanation?: Maybe<Scalars['String']>;
correctAnswer: Answer;
image?: Maybe<Scalars['String']>;
answerA?: Maybe<Answer>;
answerAImage?: Maybe<Scalars['String']>;
answerB?: Maybe<Answer>;
answerBImage?: Maybe<Scalars['String']>;
answerC?: Maybe<Answer>;
answerCImage?: Maybe<Scalars['String']>;
answerD?: Maybe<Answer>;
answerDImage?: Maybe<Scalars['String']>;
qualification?: Maybe<Qualification>;
createdAt: Scalars['Time'];
updatedAt: Scalars['Time'];
};
export type UserList = {
total: Scalars['Int'];
items?: Maybe<Array<User>>;
};
export type UserWithToken = {
token: Scalars['String'];
user: User;
};
export type Query = {
professions: ProfessionList;
profession?: Maybe<Profession>;
qualifications: QualificationList;
qualification?: Maybe<Qualification>;
questions: QuestionList;
generateTest?: Maybe<Array<Question>>;
users: UserList;
user?: Maybe<User>;
me?: Maybe<User>;
};
export type QueryProfessionsArgs = {
filter?: Maybe<ProfessionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryProfessionArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQualificationsArgs = {
filter?: Maybe<QualificationFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryQualificationArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQuestionsArgs = {
filter?: Maybe<QuestionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryGenerateTestArgs = {
qualificationIDs: Array<Scalars['ID']>;
limit?: Maybe<Scalars['Int']>;
};
export type QueryUsersArgs = {
filter?: Maybe<UserFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryUserArgs = {
id: Scalars['Int'];
};
export type Mutation = {
createProfession?: Maybe<Profession>;
updateProfession?: Maybe<Profession>;
@ -326,6 +334,34 @@ export type MutationSignInArgs = {
staySignedIn?: Maybe<Scalars['Boolean']>;
};
export type ProfessionInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
};
export type QualificationInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
code?: Maybe<Scalars['String']>;
formula?: Maybe<Scalars['String']>;
associateProfession?: Maybe<Array<Scalars['Int']>>;
dissociateProfession?: Maybe<Array<Scalars['Int']>>;
};
export enum Role {
Admin = 'admin',
User = 'user'
}
export type UserInput = {
displayName?: Maybe<Scalars['String']>;
password?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type Qualification = {
id: Scalars['ID'];
slug: Scalars['String'];
@ -336,74 +372,38 @@ export type Qualification = {
createdAt: Scalars['Time'];
};
export type UpdateManyUsersInput = {
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type Query = {
professions: ProfessionList;
profession?: Maybe<Profession>;
qualifications: QualificationList;
qualification?: Maybe<Qualification>;
questions: QuestionList;
generateTest?: Maybe<Array<Question>>;
users: UserList;
user?: Maybe<User>;
me?: Maybe<User>;
export type QualificationFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
formula?: Maybe<Array<Scalars['String']>>;
formulaNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
code?: Maybe<Array<Scalars['String']>>;
codeNEQ?: Maybe<Array<Scalars['String']>>;
codeIEQ?: Maybe<Scalars['String']>;
codeMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
professionID?: Maybe<Array<Scalars['Int']>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
or?: Maybe<QualificationFilterOr>;
};
export type QueryProfessionsArgs = {
filter?: Maybe<ProfessionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryProfessionArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQualificationsArgs = {
filter?: Maybe<QualificationFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryQualificationArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQuestionsArgs = {
filter?: Maybe<QuestionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryGenerateTestArgs = {
qualificationIDs: Array<Scalars['ID']>;
limit?: Maybe<Scalars['Int']>;
};
export type QueryUsersArgs = {
filter?: Maybe<UserFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryUserArgs = {
id: Scalars['Int'];
export type User = {
id: Scalars['ID'];
displayName: Scalars['String'];
role: Role;
email: Scalars['String'];
activated: Scalars['Boolean'];
createdAt: Scalars['Time'];
};