From cb963d9378627d25ec3c22ff2e53e9e3861c6ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C6=B0=C6=A1ng=20=C4=90=E1=BB=97?= Date: Mon, 2 Sep 2019 23:55:56 +0700 Subject: [PATCH] refactor(web): move all query and mutation hooks in to apollo/*.ts (#207) * refactor(web): [apollo] rename users.gql.ts to users.ts * feat(web): [apollo] add useCreateUserMutation * feat(web): [apollo] add useImportUserMutation * feat(web): [apollo] add useSignInMutation --- packages/web/src/Routes.tsx | 4 +- .../web/src/apollo/{users.gql.ts => users.ts} | 20 ++++++++++ .../src/components/CreateUser/CreateUser.tsx | 28 +++---------- .../components/ImportUsers/ImportUsers.tsx | 25 +++--------- packages/web/src/components/SignIn/SignIn.tsx | 5 +-- .../components/forms/CreateUpdateUserForm.tsx | 17 +------- packages/web/src/hooks/useAuth.tsx | 10 ++--- packages/web/src/typings/User.d.ts | 39 ++++++++++++++++++- packages/web/src/typings/index.d.ts | 1 + 9 files changed, 79 insertions(+), 70 deletions(-) rename packages/web/src/apollo/{users.gql.ts => users.ts} (70%) create mode 100644 packages/web/src/typings/index.d.ts diff --git a/packages/web/src/Routes.tsx b/packages/web/src/Routes.tsx index 98f2dda3..1f1d9b07 100644 --- a/packages/web/src/Routes.tsx +++ b/packages/web/src/Routes.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react' import { useQuery } from '@apollo/react-hooks' import { CircularProgress } from '@material-ui/core' -import { AUTHENTICATE } from 'apollo/users.gql' +import { AUTHENTICATE } from 'apollo/users' import Dashboard from 'components/Dashboard' import SignIn from 'components/SignIn' import { @@ -12,7 +12,7 @@ import { RouteComponentProps, Switch, } from 'react-router-dom' -import IUser from 'typings/User' +import { IUser } from 'typings' const Routes: FC = () => { return ( diff --git a/packages/web/src/apollo/users.gql.ts b/packages/web/src/apollo/users.ts similarity index 70% rename from packages/web/src/apollo/users.gql.ts rename to packages/web/src/apollo/users.ts index 454eaf3d..b702b068 100644 --- a/packages/web/src/apollo/users.gql.ts +++ b/packages/web/src/apollo/users.ts @@ -1,4 +1,11 @@ +import { useMutation } from '@apollo/react-hooks' import gql from 'graphql-tag' +import { + CreateUserData, + CreateUserVariables, + IUser, + NotImportedUser, +} from 'typings' export const USER_FRAGMENT = gql` fragment UserFragment on User { @@ -31,6 +38,9 @@ export const CREATE_USER = gql` ${USER_FRAGMENT} ` +export const useCreateUserMutation = () => + useMutation(CREATE_USER) + export const IMPORT_USERS = gql` mutation ImportUsers($file: Upload!, $overrideCheckerIds: Boolean) { importUsers(file: $file, overrideCheckerIds: $overrideCheckerIds) { @@ -49,12 +59,22 @@ export const IMPORT_USERS = gql` } ` +export const useImportUserMutation = () => + useMutation<{ + importUsers: { + importedUsers: IUser[] + notImportedUsers: NotImportedUser[] + } + }>(IMPORT_USERS) + export const SIGN_IN = gql` mutation SignIn($username: String!, $password: String!) { signIn(username: $username, password: $password) } ` +export const useSignInMutation = () => useMutation<{ signIn: string }>(SIGN_IN) + export const AUTHENTICATE = gql` query Authenticate { authenticate { diff --git a/packages/web/src/components/CreateUser/CreateUser.tsx b/packages/web/src/components/CreateUser/CreateUser.tsx index 9b7f0413..4667c612 100644 --- a/packages/web/src/components/CreateUser/CreateUser.tsx +++ b/packages/web/src/components/CreateUser/CreateUser.tsx @@ -1,18 +1,15 @@ import React, { FC, useCallback, useMemo } from 'react' -import { useMutation } from '@apollo/react-hooks' import { Box, Grid, makeStyles, Paper, Typography } from '@material-ui/core' -import { CREATE_USER } from 'apollo/users.gql' +import { useCreateUserMutation } from 'apollo/users' import { getGraphQLErrors } from 'apollo/utils' import ErrorMessage from 'components/ErrorMessage' -import CreateUpdateUserForm, { - CreateUpdateUserValues, -} from 'components/forms/CreateUpdateUserForm' +import CreateUpdateUserForm from 'components/forms/CreateUpdateUserForm' import ContentContainer from 'components/shared/ContentContainer' import PageTitle from 'components/shared/PageTitle' import { FormikActions } from 'formik' import { useSnackbar } from 'notistack' -import IUser from 'typings/User' +import { CreateUpdateUserValues } from 'typings' const initialValues: CreateUpdateUserValues = { name: '', @@ -28,25 +25,10 @@ const initialValues: CreateUpdateUserValues = { boardingRoom: '', } -type CreateUserData = { - createUser: { - createdUser: IUser - overriddenCheckerIdUser: IUser - } -} - -type CreateUserVariables = { - input: CreateUpdateUserValues - options: { - overrideCheckerId?: boolean - generatePasswordFromUsername?: boolean - } -} - const CreateUser: FC = (props) => { const classes = useStyles(props) // prettier-ignore - const [createUser, { error }] = useMutation(CREATE_USER) + const [createUser, { error }] = useCreateUserMutation() const { enqueueSnackbar } = useSnackbar() const errors = useMemo(() => { @@ -130,7 +112,7 @@ const CreateUser: FC = (props) => { ) } -const useStyles = makeStyles(({ spacing, shape, palette }) => ({ +const useStyles = makeStyles(({ spacing }) => ({ formTitle: { marginBottom: spacing(2), }, diff --git a/packages/web/src/components/ImportUsers/ImportUsers.tsx b/packages/web/src/components/ImportUsers/ImportUsers.tsx index 14e4eaca..2859e8f4 100644 --- a/packages/web/src/components/ImportUsers/ImportUsers.tsx +++ b/packages/web/src/components/ImportUsers/ImportUsers.tsx @@ -1,6 +1,5 @@ import React, { FC, useCallback, useMemo, useState } from 'react' -import { useMutation } from '@apollo/react-hooks' import { Box, Button, @@ -12,7 +11,7 @@ import { Typography, } from '@material-ui/core' import { green } from '@material-ui/core/colors' -import { IMPORT_USERS } from 'apollo/users.gql' +import { useImportUserMutation } from 'apollo/users' import { getGraphQLErrors } from 'apollo/utils' import ContentContainer from 'components/shared/ContentContainer' import PageTitle from 'components/shared/PageTitle' @@ -22,29 +21,15 @@ import { useDropzone } from 'react-dropzone' import JSONTree from 'react-json-tree' import { Link } from 'react-router-dom' import { ERROR_BACKGROUND, SUCCESS_BACKGROUND } from 'theme' -import IUser from 'typings/User' +import { NotImportedUser } from 'typings' type ImportUsersProps = {} -type NotImportedUser = { - user: { - username: IUser['username'] - checkerId: IUser['checkerId'] - } - reason: string -} const ImportUsers: React.FC = (props) => { - // const loading = true - const classes = useStyles(props) const [file, setFile] = useState(null) const [overrideCheckerIds, setOverrideCheckerIds] = useState(false) - const [upload, { data, error, loading }] = useMutation<{ - importUsers: { - importedUsers: IUser[] - notImportedUsers: NotImportedUser[] - } - }>(IMPORT_USERS) + const [upload, { data, error, loading }] = useImportUserMutation() const onDrop = useCallback( (acceptedFiles) => { // Do something with the files @@ -154,7 +139,7 @@ const ImportUsers: React.FC = (props) => { ) && data.importUsers.notImportedUsers.map((notImportedUser, idx) => ( - + ))} {errors && @@ -174,7 +159,7 @@ const ImportUsers: React.FC = (props) => { ) } -const NotImportedUser: FC<{ notImportedUser: NotImportedUser }> = ({ +const TheNotImportedUser: FC<{ notImportedUser: NotImportedUser }> = ({ notImportedUser, }) => { const classes = useStyles() diff --git a/packages/web/src/components/SignIn/SignIn.tsx b/packages/web/src/components/SignIn/SignIn.tsx index 9c0bc04c..28caf557 100644 --- a/packages/web/src/components/SignIn/SignIn.tsx +++ b/packages/web/src/components/SignIn/SignIn.tsx @@ -1,6 +1,5 @@ import React, { FC, useCallback, useEffect } from 'react' -import { useMutation } from '@apollo/react-hooks' import { Box, Button, @@ -10,7 +9,7 @@ import { TextField, Typography, } from '@material-ui/core' -import { SIGN_IN } from 'apollo/users.gql' +import { useSignInMutation } from 'apollo/users' import Logo from 'components/shared/Logo' import { Field, FieldProps, Form, Formik, FormikProps } from 'formik' import { ArrowRight } from 'mdi-material-ui' @@ -28,7 +27,7 @@ type Values = typeof initialValues const SignIn: FC = (props) => { const classes = useStyles(props) - const [signIn, { loading, error }] = useMutation<{ signIn: string }>(SIGN_IN) + const [signIn, { loading, error }] = useSignInMutation() const [, setCookie, removeCookie] = useCookies(['access_token']) useEffect(() => { diff --git a/packages/web/src/components/forms/CreateUpdateUserForm.tsx b/packages/web/src/components/forms/CreateUpdateUserForm.tsx index 72ccf85b..d76f7b51 100644 --- a/packages/web/src/components/forms/CreateUpdateUserForm.tsx +++ b/packages/web/src/components/forms/CreateUpdateUserForm.tsx @@ -20,26 +20,13 @@ import { OutlinedTextFieldProps } from '@material-ui/core/TextField' import { selectValues } from 'constants/users' import { Field, FieldProps, Form, Formik, FormikActions } from 'formik' import { Check } from 'mdi-material-ui' -import IUser from 'typings/User' import * as yup from 'yup' +import { CreateUpdateUserValues } from 'typings' -export type CreateUpdateUserValues = { - name: IUser['name'] - username: IUser['username'] - password: string | null - checkerId: string - birthdate: string - hometown: IUser['hometown'] - sex: IUser['sex'] - class: IUser['class'] - schoolYear: IUser['schoolYear'] | null - group: IUser['group'] - boardingRoom: IUser['boardingRoom'] -} type Values = CreateUpdateUserValues const fieldsProps: { - [field in keyof CreateUpdateUserValues]: Partial & { + [field in keyof Values]: Partial & { grid?: GridProps selectValues?: { [key: string]: ReactNode diff --git a/packages/web/src/hooks/useAuth.tsx b/packages/web/src/hooks/useAuth.tsx index 1a3d0051..07482b08 100644 --- a/packages/web/src/hooks/useAuth.tsx +++ b/packages/web/src/hooks/useAuth.tsx @@ -1,10 +1,10 @@ import { useCallback, useMemo } from 'react' -import { useMutation, useQuery } from '@apollo/react-hooks' -import { AUTHENTICATE, SIGN_IN } from 'apollo/users.gql' +import { useQuery } from '@apollo/react-hooks' +import { AUTHENTICATE, useSignInMutation } from 'apollo/users' import createUseContext from 'constate' import { useCookies } from 'react-cookie' -import IUser from 'typings/User' +import { IUser } from 'typings' const useAuthHook = () => { const [cookies, setCookies, removeCookie] = useCookies(['access_token']) @@ -12,9 +12,7 @@ const useAuthHook = () => { const { data } = useQuery<{ authenticate: IUser }>(AUTHENTICATE, { skip: !cookies['access_token'], }) - const [signInMutation, { loading, error }] = useMutation<{ signIn: string }>( - SIGN_IN, - ) + const [signInMutation, { loading, error }] = useSignInMutation() const user = useMemo(() => data && data.authenticate, [data]) diff --git a/packages/web/src/typings/User.d.ts b/packages/web/src/typings/User.d.ts index 7f97a68a..e708debc 100644 --- a/packages/web/src/typings/User.d.ts +++ b/packages/web/src/typings/User.d.ts @@ -20,7 +20,7 @@ export type IUserGroup = export type IUserRole = 'admin' | 'student' | 'deactivated' -export default interface IUser { +export interface IUser { id: string name: string username: string @@ -34,3 +34,40 @@ export default interface IUser { checkerId?: string boardingRoom?: string } + +export type CreateUserData = { + createUser: { + createdUser: IUser + overriddenCheckerIdUser: IUser + } +} + +export type NotImportedUser = { + user: { + username: IUser['username'] + checkerId: IUser['checkerId'] + } + reason: string +} + +export type CreateUpdateUserValues = { + name: IUser['name'] + username: IUser['username'] + password: string | null + checkerId: string + birthdate: string + hometown: IUser['hometown'] + sex: IUser['sex'] + class: IUser['class'] + schoolYear: IUser['schoolYear'] | null + group: IUser['group'] + boardingRoom: IUser['boardingRoom'] +} + +export type CreateUserVariables = { + input: CreateUpdateUserValues + options: { + overrideCheckerId?: boolean + generatePasswordFromUsername?: boolean + } +} diff --git a/packages/web/src/typings/index.d.ts b/packages/web/src/typings/index.d.ts new file mode 100644 index 00000000..9b29ee67 --- /dev/null +++ b/packages/web/src/typings/index.d.ts @@ -0,0 +1 @@ +export * from './User'