Skip to content

Commit

Permalink
wip: début de suppression de useMutate, runMutation et useMutation
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Feb 11, 2025
1 parent 3b02562 commit a005d20
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 121 deletions.
39 changes: 6 additions & 33 deletions front/src/components/ArticleContributors.jsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,32 @@
import React, { useCallback } from 'react'
import { useArticleContributorActions } from '../hooks/contributor.js'
import { useMutate, useMutation } from '../hooks/graphql.js'

import styles from './articleContributors.module.scss'
import ContactSearch from './ContactSearch.jsx'
import {
addContributor,
removeContributor,
} from './ArticleContributors.graphql'

import { getArticleContributors } from './Article.graphql'
import { useToasts } from '@geist-ui/core'

export default function ArticleContributors({ article, contributors }) {
const mutation = useMutation()
const { setToast } = useToasts()
const articleId = article._id
const { mutate } = useMutate({
query: getArticleContributors,
variables: { articleId },
const { addContributor, removeContributor } = useArticleContributorActions({
articleId,
})

const handleUserUpdated = useCallback(
async ({ user, action }) => {
const { _id: userId } = user
if (action === 'select') {
// add contributor
try {
const response = await mutation({
query: addContributor,
variables: { userId, articleId },
})
await addContributor(userId)
setToast({
text: `Contributeur ${
user.displayName || user.username
} ajouté à l'article.`,
type: 'default',
})
await mutate(
{
article: {
contributors: response.article.addContributor.contributors,
},
},
{ revalidate: false }
)
} catch (err) {
setToast({
text: String(err),
Expand All @@ -51,24 +35,13 @@ export default function ArticleContributors({ article, contributors }) {
}
} else if (action === 'unselect') {
try {
const response = await mutation({
query: removeContributor,
variables: { userId, articleId },
})
await removeContributor(userId)
setToast({
text: `Contributeur ${
user.displayName || user.username
} supprimé de l'article.`,
type: 'warning',
})
await mutate(
{
article: {
contributors: response.article.removeContributor.contributors,
},
},
{ revalidate: false }
)
} catch (err) {
setToast({
text: String(err),
Expand Down
53 changes: 37 additions & 16 deletions front/src/helpers/graphQL.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ async function getErrorResponse(response) {
}

/**
* @param {string} sessionToken
* @param {string} query
* @param {{[string: key]: value}|undefined} variables
* @param {string} query request query (as string)
* @param {{[string: key]: value}|undefined} variables request variables
* @param {string} sessionToken session token (for authentication)
* @param {'fetch'|'mutate'} [type='fetch'] request type (either fetch or mutate)
* @returns {Promise<string|object>}
*/
async function executeRequest({ sessionToken, query, variables }) {
async function executeRequest({
query,
variables,
sessionToken,
type = 'fetch',
}) {
const response = await fetch(applicationConfig.graphqlEndpoint, {
method: 'POST',
mode: 'cors',
Expand All @@ -47,22 +53,30 @@ async function executeRequest({ sessionToken, query, variables }) {
if (!response.ok) {
const errorResponse = await getErrorResponse(response)
console.error(
`Something wrong happened during => ${response.status}, ${
`Something wrong happened during ${type} => ${response.status}, ${
response.statusText
}: ${JSON.stringify(errorResponse)}`
)
const errorMessage =
errorResponse && errorResponse.errors && errorResponse.errors.length
? errorResponse.errors[0].message
: 'Unexpected error!'
throw new Error(errorMessage)
const error = new Error(errorMessage)
error.messages = errorResponse?.errors ?? [errorMessage]
throw error
}

const json = await response.json()
if (json.errors) {
throw new Error(json.errors[0].message)
const body = await response.json()
if (body.errors) {
const errorMessage =
type === 'fetch'
? 'Something wrong happened while fetching data.'
: 'Something wrong happened while mutating data.'
const error = new Error(errorMessage)
error.messages = body.errors
throw error
}
return json.data
return body.data
}

export function useGraphQLClient() {
Expand All @@ -74,13 +88,20 @@ export function useGraphQLClient() {
}

/**
*
* @param {string} sessionToken
* @param {DocumentNode|string} queryOrAST
* @param {{[string: key]: value}|undefined} variables
* @param {Object} context query context
* @param {DocumentNode|string} context.query request query (as AST or string)
* @param {{[string: key]: any}|undefined} context.variables request variables
* @param {string} context.sessionToken session token (for authentication)
* @param {'fetch'|'mutate'} [context.type='fetch'] request type (either fetch or mutate)
* @returns {Promise<string|object>}
* @throws Error if something went wrong
*/
export function executeQuery({ sessionToken, query: queryOrAST, variables }) {
export function executeQuery({
query: queryOrAST,
variables,
sessionToken,
type = 'fetch',
}) {
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
return executeRequest({ query, variables, sessionToken })
return executeRequest({ query, variables, sessionToken, type })
}
45 changes: 45 additions & 0 deletions front/src/hooks/contributor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useSelector } from 'react-redux'
import { useSWRConfig } from 'swr'
import { executeQuery } from '../helpers/graphQL.js'
import {
addContributor as addContributorQuery,
removeContributor as removeContributorQuery,
} from '../components/ArticleContributors.graphql'
import { getArticleContributors } from '../components/Article.graphql'
import { useSWRKey } from './graphql.js'

export function useArticleContributorActions({ articleId }) {
const { mutate } = useSWRConfig()
const key = useSWRKey()({ query: getArticleContributors })
const sessionToken = useSelector((state) => state.sessionToken)
const addContributor = async (contributorId) => {
const response = await executeQuery({
sessionToken,
query: addContributorQuery,
variables: { userId: contributorId, articleId },
})
await mutate(key, async (_) => ({
article: {
contributors: response.article.addContributor.contributors,
},
}))
}

const removeContributor = async (contributorId) => {
const response = await executeQuery({
sessionToken,
query: removeContributorQuery,
variables: { userId: contributorId, articleId },
})
await mutate(key, async (_) => ({
article: {
contributors: response.article.removeContributor.contributors,
},
}))
}

return {
addContributor,
removeContributor,
}
}
69 changes: 20 additions & 49 deletions front/src/hooks/graphql.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,15 @@
import useSWR, { preload } from 'swr'
import { useSelector } from 'react-redux'
import { print } from 'graphql/language/printer'
import { applicationConfig } from '../config.js'

async function fetcher({ query, variables, sessionToken }) {
return request({ query, variables, sessionToken })
}
import { useSelector } from 'react-redux'
import useSWR from 'swr'
import { executeQuery } from '../helpers/graphQL.js'

async function request({ query, variables, sessionToken, type = 'fetch' }) {
const errorMessage =
type === 'fetch'
? 'Something wrong happened while fetching data.'
: 'Something wrong happened while mutating data.'
const response = await fetch(applicationConfig.graphqlEndpoint, {
method: 'POST',
mode: 'cors',
credentials: 'omit',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
// Authorization header is provided only when we have a token
...(sessionToken ? { Authorization: `Bearer ${sessionToken}` } : {}),
},
body: JSON.stringify({ query, variables }),
async function fetch({ query, variables, sessionToken }) {
return executeQuery({
query,
variables,
sessionToken,
type: 'fetch',
})

if (response.ok) {
const body = await response.json()
if (body.errors) {
const error = new Error(errorMessage)
error.messages = body.errors
throw error
}
return body.data
}

const error = new Error(errorMessage)
error.info = await response.json().errors
error.status = response.status
throw error
}

/**
Expand All @@ -53,29 +24,38 @@ export default function useGraphQL({ query: queryOrAST, variables }, options) {
const sessionToken = useSelector((state) => state.sessionToken)
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)

return useSWR({ query, variables, sessionToken }, fetcher, options)
return useSWR({ query, variables, sessionToken }, fetch, options)
}

/**
* @deprecated
*/
export function useMutation() {
const sessionToken = useSelector((state) => state.sessionToken)

return runMutation.bind(null, { sessionToken })
}

/**
* @deprecated
*/
export function runMutation(
{ sessionToken },
{ query: queryOrAST, variables }
) {
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)

return request({
return executeQuery({
query,
variables,
sessionToken,
type: 'mutation',
})
}

/**
* @deprecated
*/
export function useMutate({ query: queryOrAST, variables }) {
const sessionToken = useSelector((state) => state.sessionToken)
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
Expand All @@ -91,12 +71,3 @@ export function useSWRKey() {
return { query, variables, sessionToken }
}
}

export function usePreload() {
const sessionToken = useSelector((state) => state.sessionToken)
return ({ query: queryOrAST, variables }) => {
const query =
typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
return preload({ query, variables, sessionToken }, fetcher)
}
}
42 changes: 19 additions & 23 deletions front/src/hooks/workspace.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useSelector } from 'react-redux'
import { useSWRConfig } from 'swr'
import {
create as createMutation,
getWorkspaceMembers,
getWorkspaces,
inviteMember as inviteMemberMutation,
removeMember as removeMemberMutation,
create as createMutation,
leave as leaveMutation,
removeMember as removeMemberMutation,
} from '../components/workspace/Workspaces.graphql'
import { executeQuery } from '../helpers/graphQL.js'
import useGraphQL, { useMutation, useSWRKey } from './graphql.js'
Expand Down Expand Up @@ -110,34 +110,30 @@ export function useWorkspaceActions() {
const key = useSWRKey()({ query: getWorkspaces })
const sessionToken = useSelector((state) => state.sessionToken)
const addWorkspace = async (workspace) => {
await executeQuery(
{ sessionToken },
{
query: createMutation,
variables: {
data: {
color: workspace.color,
description: workspace.description,
name: workspace.name,
},
await executeQuery({
sessionToken,
query: createMutation,
variables: {
data: {
color: workspace.color,
description: workspace.description,
name: workspace.name,
},
}
)
},
})
await mutate(key, async (data) => ({
workspaces: [workspace, ...data.workspaces],
}))
}

const leaveWorkspace = async (workspaceId) => {
await executeQuery(
{ sessionToken },
{
query: leaveMutation,
variables: {
workspaceId,
},
}
)
await executeQuery({
sessionToken,
query: leaveMutation,
variables: {
workspaceId,
},
})
await mutate(
key,
async (data) => ({
Expand Down

0 comments on commit a005d20

Please sign in to comment.