From c3bc0d8a3edd4e7c31fe6e967249d38c785b9244 Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Tue, 4 Feb 2025 14:50:53 +0100
Subject: [PATCH 01/12] chore: rename useGraphQL to useGraphQLClient
---
front/src/components/ArticleCreate.jsx | 4 ++--
front/src/components/Chapter.jsx | 4 ++--
front/src/components/Corpus.jsx | 4 ++--
front/src/components/Credentials.jsx | 4 ++--
front/src/components/Register.jsx | 4 ++--
front/src/components/TagCreate.jsx | 4 ++--
front/src/components/UserInfos.jsx | 4 ++--
front/src/components/Write/Versions.jsx | 4 ++--
front/src/components/Write/Write.jsx | 4 ++--
front/src/components/Write/bibliographe/ZoteroPanel.jsx | 4 ++--
front/src/components/Write/providers/monaco/DiffEditor.jsx | 4 ++--
front/src/components/corpus/Corpus.jsx | 4 ++--
front/src/components/corpus/CorpusCreate.jsx | 4 ++--
front/src/components/corpus/CorpusItem.jsx | 4 ++--
front/src/components/corpus/CorpusMetadataModal.jsx | 4 ++--
front/src/components/corpus/CorpusSelectItem.jsx | 4 ++--
front/src/components/corpus/CorpusUpdate.jsx | 4 ++--
front/src/components/workspace/WorkspaceSelectItem.jsx | 4 ++--
front/src/components/workspace/Workspaces.jsx | 4 ++--
front/src/helpers/graphQL.js | 2 +-
20 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/front/src/components/ArticleCreate.jsx b/front/src/components/ArticleCreate.jsx
index 69df170a0..087f62efc 100644
--- a/front/src/components/ArticleCreate.jsx
+++ b/front/src/components/ArticleCreate.jsx
@@ -3,7 +3,7 @@ import React, { useState, useCallback, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import { createArticle } from './Articles.graphql'
import Field from './Field.jsx'
import { getTags } from './Tag.graphql'
@@ -30,7 +30,7 @@ export default function ArticleCreate({ onSubmit, workspaceId = null }) {
const { setToast } = useToasts()
const [tags, setTags] = useState([])
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const workspaces = useSelector((state) => state.activeUser.workspaces)
useEffect(() => {
diff --git a/front/src/components/Chapter.jsx b/front/src/components/Chapter.jsx
index 97ce2d2e6..f3b0a6312 100644
--- a/front/src/components/Chapter.jsx
+++ b/front/src/components/Chapter.jsx
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import { Check, Edit3 } from 'react-feather'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import { renameArticle as query } from './Article.graphql'
import Button from './Button'
import buttonStyles from './button.module.scss'
@@ -25,7 +25,7 @@ export default function Chapter({ article }) {
const [title, setTitle] = useState(article.title)
const [tempTitle, setTempTitle] = useState(article.title)
const activeUser = useCurrentUser()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const rename = async (e) => {
e.preventDefault()
diff --git a/front/src/components/Corpus.jsx b/front/src/components/Corpus.jsx
index 97f2053b6..8124b1a4f 100644
--- a/front/src/components/Corpus.jsx
+++ b/front/src/components/Corpus.jsx
@@ -15,7 +15,7 @@ import Export from './Export.jsx'
import Chapter from './Chapter.jsx'
import etv from '../helpers/eventTargetValue.js'
-import { useGraphQL } from '../helpers/graphQL.js'
+import { useGraphQLClient } from '../helpers/graphQL.js'
import { updateTag as query } from './Corpus.graphql'
import styles from './articles.module.scss'
@@ -38,7 +38,7 @@ export default function Book({ name: tagName, _id, updatedAt, articles }) {
const [isRenaming, setIsRenaming] = useState(false)
const { t } = useTranslation()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const renameBook = useCallback(
async (event) => {
diff --git a/front/src/components/Credentials.jsx b/front/src/components/Credentials.jsx
index bea93b3cc..f39e1ebc3 100644
--- a/front/src/components/Credentials.jsx
+++ b/front/src/components/Credentials.jsx
@@ -2,7 +2,7 @@ import React, { useMemo, useState } from 'react'
import { useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import { changePassword as query } from './Credentials.graphql'
import styles from './credentials.module.scss'
import fieldStyles from './field.module.scss'
@@ -19,7 +19,7 @@ export default function Credentials() {
const hasExistingPassword = useSelector((state) =>
state.activeUser.authTypes.includes('local')
)
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const { t } = useTranslation()
const canSubmit = useMemo(() => {
diff --git a/front/src/components/Register.jsx b/front/src/components/Register.jsx
index 239efaf13..5665f336c 100644
--- a/front/src/components/Register.jsx
+++ b/front/src/components/Register.jsx
@@ -2,7 +2,7 @@ import React, { useCallback, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { Link, useHistory } from 'react-router-dom'
import { useToasts } from '@geist-ui/core'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import * as queries from './Credentials.graphql'
import styles from './login.module.scss'
@@ -18,7 +18,7 @@ export default function Register() {
const passwordRef = useRef()
const passwordConfirmationRef = useRef()
const history = useHistory()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const handleFormSubmit = useCallback(async (event) => {
event.preventDefault()
diff --git a/front/src/components/TagCreate.jsx b/front/src/components/TagCreate.jsx
index 73bec1386..1690a3ccf 100644
--- a/front/src/components/TagCreate.jsx
+++ b/front/src/components/TagCreate.jsx
@@ -3,7 +3,7 @@ import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { randomColor } from '../helpers/colors.js'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import { useMutate } from '../hooks/graphql'
import { createTag, getTags } from './Tag.graphql'
@@ -20,7 +20,7 @@ export default function TagCreate() {
const { state: color, bindings: colorBindings } = useInput(randomColor())
const activeUser = useCurrentUser()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const variables = {
user: activeUser._id,
diff --git a/front/src/components/UserInfos.jsx b/front/src/components/UserInfos.jsx
index 7a1e0a1af..dc5c0fa18 100644
--- a/front/src/components/UserInfos.jsx
+++ b/front/src/components/UserInfos.jsx
@@ -5,7 +5,7 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux'
import { CopyToClipboard } from 'react-copy-to-clipboard'
import { Helmet } from 'react-helmet'
-import { useGraphQL } from '../helpers/graphQL'
+import { useGraphQLClient } from '../helpers/graphQL'
import { updateUser } from './Credentials.graphql'
import etv from '../helpers/eventTargetValue'
import styles from './credentials.module.scss'
@@ -17,7 +17,7 @@ import TimeAgo from './TimeAgo.jsx'
export default function UserInfos() {
const dispatch = useDispatch()
const { t } = useTranslation()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const activeUser = useSelector((state) => state.activeUser, shallowEqual)
const zoteroToken = useSelector((state) => state.activeUser.zoteroToken)
const sessionToken = useSelector((state) => state.sessionToken)
diff --git a/front/src/components/Write/Versions.jsx b/front/src/components/Write/Versions.jsx
index c77cc0e10..036208dac 100644
--- a/front/src/components/Write/Versions.jsx
+++ b/front/src/components/Write/Versions.jsx
@@ -17,7 +17,7 @@ import styles from './versions.module.scss'
import menuStyles from './menu.module.scss'
import buttonStyles from '../button.module.scss'
-import { useGraphQL } from '../../helpers/graphQL'
+import { useGraphQLClient } from '../../helpers/graphQL'
import { renameVersion } from './Write.graphql'
import Modal from '../Modal'
@@ -62,7 +62,7 @@ function Version({ articleId, compareTo, readOnly, selectedVersion, v }) {
[styles.compareTo]: isComparing && articleVersionId === compareTo,
})
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const [renaming, setRenaming] = useState(false)
const [title, setTitle] = useState(v.message)
const versionType = v.type || 'userAction'
diff --git a/front/src/components/Write/Write.jsx b/front/src/components/Write/Write.jsx
index efd5c95fc..0de5bbc7c 100644
--- a/front/src/components/Write/Write.jsx
+++ b/front/src/components/Write/Write.jsx
@@ -21,7 +21,7 @@ import ErrorMessageCard from '../ErrorMessageCard.jsx'
import styles from './write.module.scss'
import { useActiveUserId } from '../../hooks/user'
-import { useGraphQL } from '../../helpers/graphQL'
+import { useGraphQLClient } from '../../helpers/graphQL'
import { getEditableArticle as query, stopSoloSession } from './Write.graphql'
import ArticleEditorMenu from './ArticleEditorMenu.jsx'
@@ -59,7 +59,7 @@ export default function Write() {
)
const userId = useActiveUserId()
const dispatch = useDispatch()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const routeMatch = useRouteMatch()
const [collaborativeSessionActive, setCollaborativeSessionActive] =
useState(false)
diff --git a/front/src/components/Write/bibliographe/ZoteroPanel.jsx b/front/src/components/Write/bibliographe/ZoteroPanel.jsx
index b23a20159..8a9836468 100644
--- a/front/src/components/Write/bibliographe/ZoteroPanel.jsx
+++ b/front/src/components/Write/bibliographe/ZoteroPanel.jsx
@@ -6,7 +6,7 @@ import {
fetchAllCollectionsPerLibrary,
fetchBibliographyFromCollectionHref,
} from '../../../helpers/zotero'
-import { useGraphQL } from '../../../helpers/graphQL'
+import { useGraphQLClient } from '../../../helpers/graphQL'
import { useProfile } from '../../../helpers/userProfile'
import { applicationConfig } from '../../../config.js'
import { linkToZotero as query } from '../../Article.graphql'
@@ -40,7 +40,7 @@ export default function ZoteroPanel({
const [zoteroCollections, setZoteroCollections] = useState([])
const [isSaving, setSaving] = useState(false)
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const refreshProfile = useProfile()
const handleZoteroLinkChange = useCallback(
diff --git a/front/src/components/Write/providers/monaco/DiffEditor.jsx b/front/src/components/Write/providers/monaco/DiffEditor.jsx
index 0e6af33ad..0ba151d58 100644
--- a/front/src/components/Write/providers/monaco/DiffEditor.jsx
+++ b/front/src/components/Write/providers/monaco/DiffEditor.jsx
@@ -4,7 +4,7 @@ import CompareSelect from './CompareSelect'
import styles from './DiffEditor.module.scss'
import * as monaco from 'monaco-editor'
import { DiffEditor, loader } from '@monaco-editor/react'
-import { useGraphQL } from '../../../../helpers/graphQL'
+import { useGraphQLClient } from '../../../../helpers/graphQL'
import { compareVersion as query } from '../../Write.graphql'
import { defineFlippedDiffTheme } from './support'
loader.config({ monaco })
@@ -19,7 +19,7 @@ export default function MonacoDiffEditor({
onTextUpdate,
}) {
const [modifiedText, setModifiedText] = useState('')
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const handleEditorDidMount = useCallback((editor, monaco) => {
defineFlippedDiffTheme(monaco)
diff --git a/front/src/components/corpus/Corpus.jsx b/front/src/components/corpus/Corpus.jsx
index 4b94b20b2..d72356b30 100644
--- a/front/src/components/corpus/Corpus.jsx
+++ b/front/src/components/corpus/Corpus.jsx
@@ -10,7 +10,7 @@ import { shallowEqual, useSelector } from 'react-redux'
import { Helmet } from 'react-helmet'
import { CurrentUserContext } from '../../contexts/CurrentUser'
-import { useGraphQL } from '../../helpers/graphQL'
+import { useGraphQLClient } from '../../helpers/graphQL'
import { useActiveWorkspace } from '../../hooks/workspace.js'
import styles from './corpus.module.scss'
import CorpusCreate from './CorpusCreate.jsx'
@@ -49,7 +49,7 @@ export default function Corpus() {
bindings: createCorpusModalBinding,
} = useModal()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const handleCreateNewCorpus = useCallback(() => {
setCreateCorpusVisible(false)
diff --git a/front/src/components/corpus/CorpusCreate.jsx b/front/src/components/corpus/CorpusCreate.jsx
index b0f3be444..5d17eb05a 100644
--- a/front/src/components/corpus/CorpusCreate.jsx
+++ b/front/src/components/corpus/CorpusCreate.jsx
@@ -2,7 +2,7 @@ import { Button, Textarea, useInput, useToasts } from '@geist-ui/core'
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
import { useActiveWorkspace } from '../../hooks/workspace.js'
import Field from '../Field.jsx'
@@ -18,7 +18,7 @@ export default function CorpusCreate({ onSubmit }) {
const { state: title, bindings: titleBindings } = useInput('')
const { state: description, bindings: descriptionBindings } = useInput('')
const titleInputRef = useRef()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const activeWorkspace = useActiveWorkspace()
const activeWorkspaceId = useMemo(
() => activeWorkspace?._id,
diff --git a/front/src/components/corpus/CorpusItem.jsx b/front/src/components/corpus/CorpusItem.jsx
index 8c1c58f52..7ae6db36a 100644
--- a/front/src/components/corpus/CorpusItem.jsx
+++ b/front/src/components/corpus/CorpusItem.jsx
@@ -12,7 +12,7 @@ import {
import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux'
import { Link } from 'react-router-dom'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
import Button from '../Button.jsx'
import buttonStyles from '../button.module.scss'
import Export from '../Export.jsx'
@@ -47,7 +47,7 @@ export default function CorpusItem({ corpus }) {
bindings: editCorpusBindings,
} = useModal()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const corpusId = useMemo(() => corpus._id, [corpus])
const handleCorpusUpdated = useCallback(() => {
diff --git a/front/src/components/corpus/CorpusMetadataModal.jsx b/front/src/components/corpus/CorpusMetadataModal.jsx
index d8053969f..ffaf83154 100644
--- a/front/src/components/corpus/CorpusMetadataModal.jsx
+++ b/front/src/components/corpus/CorpusMetadataModal.jsx
@@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux'
import { useTranslation } from 'react-i18next'
import { updateMetadata } from './Corpus.graphql'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
import MetadataForm from '../metadata/MetadataForm.jsx'
import corpusMetadataSchema from '../../schemas/corpus-journal-metadata.schema.json'
import corpusUiSchema from '../../schemas/corpus-journal-ui-schema.json'
@@ -16,7 +16,7 @@ import Select from '../Select.jsx'
export default function CorpusMetadataModal({ corpusId, initialValue }) {
const { t } = useTranslation()
const dispatch = useDispatch()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const [corpusMetadata, setCorpusMetadata] = useState(initialValue)
const {
visible: editMetadataVisible,
diff --git a/front/src/components/corpus/CorpusSelectItem.jsx b/front/src/components/corpus/CorpusSelectItem.jsx
index fe78c7720..c84c02d5c 100644
--- a/front/src/components/corpus/CorpusSelectItem.jsx
+++ b/front/src/components/corpus/CorpusSelectItem.jsx
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import { removeArticleFromCorpus, addArticleToCorpus } from './Corpus.graphql'
import styles from './CorpusSelectItem.module.scss'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
export default function CorpusSelectItem({
selected,
@@ -13,7 +13,7 @@ export default function CorpusSelectItem({
articleId,
onChange,
}) {
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const toggleCorpusArticle = useCallback(
async (event) => {
event.preventDefault()
diff --git a/front/src/components/corpus/CorpusUpdate.jsx b/front/src/components/corpus/CorpusUpdate.jsx
index 46663068f..cc3cc56ad 100644
--- a/front/src/components/corpus/CorpusUpdate.jsx
+++ b/front/src/components/corpus/CorpusUpdate.jsx
@@ -1,7 +1,7 @@
import { Button, Textarea, useInput, useToasts } from '@geist-ui/core'
import React, { useCallback, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
import Field from '../Field.jsx'
@@ -17,7 +17,7 @@ export default function CorpusUpdate({ corpus, onSubmit }) {
corpus.description
)
const titleInputRef = useRef()
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
useEffect(() => {
if (titleInputRef.current !== undefined) {
diff --git a/front/src/components/workspace/WorkspaceSelectItem.jsx b/front/src/components/workspace/WorkspaceSelectItem.jsx
index 54a825d9d..ac714ad6f 100644
--- a/front/src/components/workspace/WorkspaceSelectItem.jsx
+++ b/front/src/components/workspace/WorkspaceSelectItem.jsx
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types'
import { removeArticle, addArticle } from './Workspaces.graphql'
import styles from './WorkspaceSelectItem.module.scss'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
export default function WorkspaceSelectItem({
articleId,
@@ -15,7 +15,7 @@ export default function WorkspaceSelectItem({
name,
onChange,
}) {
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
const activeUser = useSelector((state) => state.activeUser)
const toggleWorkspaceArticle = useCallback(
async (event) => {
diff --git a/front/src/components/workspace/Workspaces.jsx b/front/src/components/workspace/Workspaces.jsx
index 4e54247e6..4a24857f0 100644
--- a/front/src/components/workspace/Workspaces.jsx
+++ b/front/src/components/workspace/Workspaces.jsx
@@ -10,7 +10,7 @@ import Field from '../../components/Field.jsx'
import WorkspaceItem from '../../components/workspace/WorkspaceItem.jsx'
import { CurrentUserContext } from '../../contexts/CurrentUser'
-import { useGraphQL } from '../../helpers/graphQL.js'
+import { useGraphQLClient } from '../../helpers/graphQL.js'
import { useWorkspaces } from '../../hooks/workspace.js'
import Loading from '../Loading.jsx'
import CreateWorkspaceModal from './CreateWorkspaceModal.jsx'
@@ -30,7 +30,7 @@ export default function Workspaces() {
personal: true,
members: [],
})
- const runQuery = useGraphQL()
+ const runQuery = useGraphQLClient()
useEffect(() => {
;(async () => {
diff --git a/front/src/helpers/graphQL.js b/front/src/helpers/graphQL.js
index c39b29380..d159bb639 100644
--- a/front/src/helpers/graphQL.js
+++ b/front/src/helpers/graphQL.js
@@ -60,7 +60,7 @@ export default async function askGraphQL(
return json.data
}
-export function useGraphQL() {
+export function useGraphQLClient() {
const sessionToken = useSelector((state) => state.sessionToken)
return runQuery.bind(null, { sessionToken })
}
From d466ef7c1f35914c1ba9f0faede1909d5a25d53d Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Tue, 4 Feb 2025 15:02:40 +0100
Subject: [PATCH 02/12] wip! renommage
---
front/src/helpers/graphQL.js | 23 ++++++++++++++++-------
front/src/helpers/userProfile.js | 10 +++++-----
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/front/src/helpers/graphQL.js b/front/src/helpers/graphQL.js
index d159bb639..304c7ccd4 100644
--- a/front/src/helpers/graphQL.js
+++ b/front/src/helpers/graphQL.js
@@ -1,5 +1,5 @@
-import { useSelector } from 'react-redux'
import { print } from 'graphql/language/printer'
+import { useSelector } from 'react-redux'
import { applicationConfig } from '../config.js'
/**
@@ -21,7 +21,7 @@ async function getErrorResponse(response) {
}
}
-export default async function askGraphQL(
+async function askGraphQL(
payload,
action = 'fetching from the server',
sessionToken = null
@@ -62,16 +62,25 @@ export default async function askGraphQL(
export function useGraphQLClient() {
const sessionToken = useSelector((state) => state.sessionToken)
- return runQuery.bind(null, { sessionToken })
+ return {
+ query: (query, variables) => runQuery({ query, variables, sessionToken }),
+ }
}
/**
- * @param {string} sessionToken
- * @param {DocumentNode|string} queryOrAST
- * @param {{[string: key]: value}} variables
+ * @typedef {Object} QueryParameters
+ * @property {{
+ * sessionToken: string,
+ * query: DocumentNode|string,
+ * variables: {[string: key]: value}
+ * }}
+ */
+
+/**
+ * @param {QueryParameters} queryParameters
* @returns {Promise}
*/
-export function runQuery({ sessionToken }, { query: queryOrAST, variables }) {
+export function runQuery({ sessionToken, query: queryOrAST, variables }) {
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
return askGraphQL({ query, variables }, null, sessionToken)
diff --git a/front/src/helpers/userProfile.js b/front/src/helpers/userProfile.js
index 22e3268ab..45ac1507c 100644
--- a/front/src/helpers/userProfile.js
+++ b/front/src/helpers/userProfile.js
@@ -1,6 +1,6 @@
-import { useDispatch, useSelector } from 'react-redux'
-import { runQuery } from './graphQL.js'
-import { getFullUserProfile as query } from '../components/Credentials.graphql'
+import { useDispatch } from 'react-redux'
+import { runQuery, useGraphQLClient } from './graphQL.js'
+import { getFullUserProfile as getUserProfileQuery } from '../components/Credentials.graphql'
export function getUserProfile({ sessionToken }) {
return runQuery({ sessionToken }, { query })
@@ -8,10 +8,10 @@ export function getUserProfile({ sessionToken }) {
export function useProfile() {
const dispatch = useDispatch()
- const sessionToken = useSelector((state) => state.sessionToken)
+ const { query } = useGraphQLClient()
return function refreshProfile() {
- return getUserProfile({ sessionToken }).then((response) =>
+ return query({ query: getUserProfileQuery }).then((response) =>
dispatch({ type: 'PROFILE', ...response })
)
}
From 082e935c23e0682f42f45c1bfb1d7fa97ea885c0 Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Tue, 4 Feb 2025 16:18:19 +0100
Subject: [PATCH 03/12] =?UTF-8?q?chore:=20retourne=20un=20client=20permett?=
=?UTF-8?q?ant=20d'ex=C3=A9cuter=20des=20requ=C3=AAtes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
front/src/components/ArticleCreate.jsx | 6 +--
front/src/components/Chapter.jsx | 4 +-
front/src/components/Corpus.jsx | 4 +-
front/src/components/Credentials.jsx | 4 +-
front/src/components/Register.jsx | 4 +-
front/src/components/TagCreate.jsx | 4 +-
front/src/components/UserInfos.jsx | 6 +--
front/src/components/Write/Versions.jsx | 4 +-
front/src/components/Write/Write.jsx | 4 +-
.../Write/bibliographe/ZoteroPanel.jsx | 4 +-
.../Write/providers/monaco/DiffEditor.jsx | 4 +-
front/src/components/corpus/Corpus.jsx | 4 +-
front/src/components/corpus/CorpusCreate.jsx | 4 +-
front/src/components/corpus/CorpusItem.jsx | 4 +-
.../components/corpus/CorpusMetadataModal.jsx | 6 +--
.../components/corpus/CorpusSelectItem.jsx | 4 +-
front/src/components/corpus/CorpusUpdate.jsx | 4 +-
.../workspace/WorkspaceSelectItem.jsx | 4 +-
front/src/components/workspace/Workspaces.jsx | 4 +-
front/src/helpers/graphQL.js | 41 +++++++++----------
front/src/helpers/userProfile.js | 4 +-
front/src/hooks/workspace.js | 6 +--
front/src/services/ArticleService.js | 10 ++---
23 files changed, 71 insertions(+), 72 deletions(-)
diff --git a/front/src/components/ArticleCreate.jsx b/front/src/components/ArticleCreate.jsx
index 087f62efc..3f3567208 100644
--- a/front/src/components/ArticleCreate.jsx
+++ b/front/src/components/ArticleCreate.jsx
@@ -30,7 +30,7 @@ export default function ArticleCreate({ onSubmit, workspaceId = null }) {
const { setToast } = useToasts()
const [tags, setTags] = useState([])
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const workspaces = useSelector((state) => state.activeUser.workspaces)
useEffect(() => {
@@ -39,7 +39,7 @@ export default function ArticleCreate({ onSubmit, workspaceId = null }) {
try {
const {
user: { tags },
- } = await runQuery({ query: getTags, variables: {} })
+ } = await query({ query: getTags, variables: {} })
setTags(tags)
} catch (err) {
setToast({
@@ -54,7 +54,7 @@ export default function ArticleCreate({ onSubmit, workspaceId = null }) {
try {
event.preventDefault()
const createArticleInput = fromFormData(event.target)
- const { createArticle: createdArticle } = await runQuery({
+ const { createArticle: createdArticle } = await query({
query: createArticle,
variables: { createArticleInput },
})
diff --git a/front/src/components/Chapter.jsx b/front/src/components/Chapter.jsx
index f3b0a6312..d922783fe 100644
--- a/front/src/components/Chapter.jsx
+++ b/front/src/components/Chapter.jsx
@@ -25,7 +25,7 @@ export default function Chapter({ article }) {
const [title, setTitle] = useState(article.title)
const [tempTitle, setTempTitle] = useState(article.title)
const activeUser = useCurrentUser()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const rename = async (e) => {
e.preventDefault()
@@ -34,7 +34,7 @@ export default function Chapter({ article }) {
article: articleId,
title: tempTitle,
}
- await runQuery({ query, variables })
+ await query({ query, variables })
setTitle(tempTitle)
setRenaming(false)
}
diff --git a/front/src/components/Corpus.jsx b/front/src/components/Corpus.jsx
index 8124b1a4f..cb20f068c 100644
--- a/front/src/components/Corpus.jsx
+++ b/front/src/components/Corpus.jsx
@@ -38,7 +38,7 @@ export default function Book({ name: tagName, _id, updatedAt, articles }) {
const [isRenaming, setIsRenaming] = useState(false)
const { t } = useTranslation()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const renameBook = useCallback(
async (event) => {
@@ -48,7 +48,7 @@ export default function Book({ name: tagName, _id, updatedAt, articles }) {
tag: _id,
name: tempName,
}
- const newTag = await runQuery({ query, variables })
+ const newTag = await query({ query, variables })
setName(newTag.updateTag.name)
setIsRenaming(false)
},
diff --git a/front/src/components/Credentials.jsx b/front/src/components/Credentials.jsx
index f39e1ebc3..1d8269c4d 100644
--- a/front/src/components/Credentials.jsx
+++ b/front/src/components/Credentials.jsx
@@ -19,7 +19,7 @@ export default function Credentials() {
const hasExistingPassword = useSelector((state) =>
state.activeUser.authTypes.includes('local')
)
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const { t } = useTranslation()
const canSubmit = useMemo(() => {
@@ -39,7 +39,7 @@ export default function Credentials() {
new: password,
user: userId,
}
- await runQuery({ query, variables })
+ await query({ query, variables })
setPassword('')
setPasswordO('')
setPasswordC('')
diff --git a/front/src/components/Register.jsx b/front/src/components/Register.jsx
index 5665f336c..e9a1bf151 100644
--- a/front/src/components/Register.jsx
+++ b/front/src/components/Register.jsx
@@ -18,14 +18,14 @@ export default function Register() {
const passwordRef = useRef()
const passwordConfirmationRef = useRef()
const history = useHistory()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const handleFormSubmit = useCallback(async (event) => {
event.preventDefault()
const details = fromFormData(event.target)
try {
- await runQuery({ query: queries.createUser, variables: { details } })
+ await query({ query: queries.createUser, variables: { details } })
// if no error thrown, we can navigate to /
setToast({
type: 'default',
diff --git a/front/src/components/TagCreate.jsx b/front/src/components/TagCreate.jsx
index 1690a3ccf..10ebc1b2d 100644
--- a/front/src/components/TagCreate.jsx
+++ b/front/src/components/TagCreate.jsx
@@ -20,7 +20,7 @@ export default function TagCreate() {
const { state: color, bindings: colorBindings } = useInput(randomColor())
const activeUser = useCurrentUser()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const variables = {
user: activeUser._id,
@@ -34,7 +34,7 @@ export default function TagCreate() {
event.preventDefault()
;(async () => {
try {
- const result = await runQuery({
+ const result = await query({
query: createTag,
variables,
})
diff --git a/front/src/components/UserInfos.jsx b/front/src/components/UserInfos.jsx
index dc5c0fa18..39968c1b3 100644
--- a/front/src/components/UserInfos.jsx
+++ b/front/src/components/UserInfos.jsx
@@ -17,7 +17,7 @@ import TimeAgo from './TimeAgo.jsx'
export default function UserInfos() {
const dispatch = useDispatch()
const { t } = useTranslation()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const activeUser = useSelector((state) => state.activeUser, shallowEqual)
const zoteroToken = useSelector((state) => state.activeUser.zoteroToken)
const sessionToken = useSelector((state) => state.sessionToken)
@@ -44,7 +44,7 @@ export default function UserInfos() {
event.preventDefault()
const variables = { user: activeUser._id, details: { zoteroToken: null } }
- await runQuery({ query: updateUser, variables })
+ await query({ query: updateUser, variables })
clearZoteroToken()
setIsSaving(false)
}, [])
@@ -57,7 +57,7 @@ export default function UserInfos() {
user: activeUser._id,
details: { displayName, firstName, lastName, institution },
}
- const { updateUser: userDetails } = await runQuery({
+ const { updateUser: userDetails } = await query({
query: updateUser,
variables,
})
diff --git a/front/src/components/Write/Versions.jsx b/front/src/components/Write/Versions.jsx
index 036208dac..7a86b068e 100644
--- a/front/src/components/Write/Versions.jsx
+++ b/front/src/components/Write/Versions.jsx
@@ -62,7 +62,7 @@ function Version({ articleId, compareTo, readOnly, selectedVersion, v }) {
[styles.compareTo]: isComparing && articleVersionId === compareTo,
})
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const [renaming, setRenaming] = useState(false)
const [title, setTitle] = useState(v.message)
const versionType = v.type || 'userAction'
@@ -80,7 +80,7 @@ function Version({ articleId, compareTo, readOnly, selectedVersion, v }) {
async (event) => {
event.preventDefault()
const variables = { version: articleVersionId, name: title }
- await runQuery({ query: renameVersion, variables })
+ await query({ query: renameVersion, variables })
setTitle(title)
setRenaming(false)
},
diff --git a/front/src/components/Write/Write.jsx b/front/src/components/Write/Write.jsx
index 0de5bbc7c..7fc50296f 100644
--- a/front/src/components/Write/Write.jsx
+++ b/front/src/components/Write/Write.jsx
@@ -59,7 +59,7 @@ export default function Write() {
)
const userId = useActiveUserId()
const dispatch = useDispatch()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const routeMatch = useRouteMatch()
const [collaborativeSessionActive, setCollaborativeSessionActive] =
useState(false)
@@ -226,7 +226,7 @@ export default function Write() {
setIsLoading(true)
;(async () => {
- const data = await runQuery({ query, variables }).catch((error) => {
+ const data = await query({ query, variables }).catch((error) => {
setGraphQLError(error)
return {}
})
diff --git a/front/src/components/Write/bibliographe/ZoteroPanel.jsx b/front/src/components/Write/bibliographe/ZoteroPanel.jsx
index 8a9836468..80bd33c7f 100644
--- a/front/src/components/Write/bibliographe/ZoteroPanel.jsx
+++ b/front/src/components/Write/bibliographe/ZoteroPanel.jsx
@@ -40,7 +40,7 @@ export default function ZoteroPanel({
const [zoteroCollections, setZoteroCollections] = useState([])
const [isSaving, setSaving] = useState(false)
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const refreshProfile = useProfile()
const handleZoteroLinkChange = useCallback(
@@ -79,7 +79,7 @@ export default function ZoteroPanel({
user: userId,
article: articleId,
}
- await runQuery({ query, variables })
+ await query({ query, variables })
} catch (err) {
alert(err)
}
diff --git a/front/src/components/Write/providers/monaco/DiffEditor.jsx b/front/src/components/Write/providers/monaco/DiffEditor.jsx
index 0ba151d58..8d5520a0e 100644
--- a/front/src/components/Write/providers/monaco/DiffEditor.jsx
+++ b/front/src/components/Write/providers/monaco/DiffEditor.jsx
@@ -19,7 +19,7 @@ export default function MonacoDiffEditor({
onTextUpdate,
}) {
const [modifiedText, setModifiedText] = useState('')
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const handleEditorDidMount = useCallback((editor, monaco) => {
defineFlippedDiffTheme(monaco)
@@ -38,7 +38,7 @@ export default function MonacoDiffEditor({
}, [])
useEffect(() => {
- runQuery({
+ query({
query,
variables: {
article: articleId,
diff --git a/front/src/components/corpus/Corpus.jsx b/front/src/components/corpus/Corpus.jsx
index d72356b30..b645b9c4c 100644
--- a/front/src/components/corpus/Corpus.jsx
+++ b/front/src/components/corpus/Corpus.jsx
@@ -49,7 +49,7 @@ export default function Corpus() {
bindings: createCorpusModalBinding,
} = useModal()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const handleCreateNewCorpus = useCallback(() => {
setCreateCorpusVisible(false)
@@ -61,7 +61,7 @@ export default function Corpus() {
const variables = activeWorkspaceId
? { filter: { workspaceId: activeWorkspaceId } }
: {}
- const data = await runQuery({ query: getCorpus, variables })
+ const data = await query({ query: getCorpus, variables })
setCorpus(data.corpus)
setIsLoading(false)
} catch (err) {
diff --git a/front/src/components/corpus/CorpusCreate.jsx b/front/src/components/corpus/CorpusCreate.jsx
index 5d17eb05a..af7315a54 100644
--- a/front/src/components/corpus/CorpusCreate.jsx
+++ b/front/src/components/corpus/CorpusCreate.jsx
@@ -18,7 +18,7 @@ export default function CorpusCreate({ onSubmit }) {
const { state: title, bindings: titleBindings } = useInput('')
const { state: description, bindings: descriptionBindings } = useInput('')
const titleInputRef = useRef()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const activeWorkspace = useActiveWorkspace()
const activeWorkspaceId = useMemo(
() => activeWorkspace?._id,
@@ -35,7 +35,7 @@ export default function CorpusCreate({ onSubmit }) {
async (event) => {
try {
event.preventDefault()
- const response = await runQuery({
+ const response = await query({
query: createCorpus,
variables: {
createCorpusInput: {
diff --git a/front/src/components/corpus/CorpusItem.jsx b/front/src/components/corpus/CorpusItem.jsx
index 7ae6db36a..ee05431e1 100644
--- a/front/src/components/corpus/CorpusItem.jsx
+++ b/front/src/components/corpus/CorpusItem.jsx
@@ -47,7 +47,7 @@ export default function CorpusItem({ corpus }) {
bindings: editCorpusBindings,
} = useModal()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const corpusId = useMemo(() => corpus._id, [corpus])
const handleCorpusUpdated = useCallback(() => {
@@ -60,7 +60,7 @@ export default function CorpusItem({ corpus }) {
const handleDeleteCorpus = useCallback(async () => {
try {
- await runQuery({ query: deleteCorpus, variables: { corpusId } })
+ await query({ query: deleteCorpus, variables: { corpusId } })
dispatch({ type: 'SET_LATEST_CORPUS_DELETED', data: { corpusId } })
setToast({
text: t('corpus.delete.toastSuccess'),
diff --git a/front/src/components/corpus/CorpusMetadataModal.jsx b/front/src/components/corpus/CorpusMetadataModal.jsx
index ffaf83154..acc9da104 100644
--- a/front/src/components/corpus/CorpusMetadataModal.jsx
+++ b/front/src/components/corpus/CorpusMetadataModal.jsx
@@ -16,7 +16,7 @@ import Select from '../Select.jsx'
export default function CorpusMetadataModal({ corpusId, initialValue }) {
const { t } = useTranslation()
const dispatch = useDispatch()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const [corpusMetadata, setCorpusMetadata] = useState(initialValue)
const {
visible: editMetadataVisible,
@@ -25,7 +25,7 @@ export default function CorpusMetadataModal({ corpusId, initialValue }) {
} = useModal()
const handleUpdateMetadata = useCallback(async () => {
- await runQuery({
+ await query({
query: updateMetadata,
variables: {
corpusId: corpusId,
@@ -37,7 +37,7 @@ export default function CorpusMetadataModal({ corpusId, initialValue }) {
data: { corpusId, date: new Date() },
})
setEditMetadataVisible(false)
- }, [corpusId, dispatch, runQuery, updateMetadata, corpusId, corpusMetadata])
+ }, [corpusId, dispatch, query, updateMetadata, corpusId, corpusMetadata])
const handleMetadataUpdated = useCallback(
(metadata) => {
diff --git a/front/src/components/corpus/CorpusSelectItem.jsx b/front/src/components/corpus/CorpusSelectItem.jsx
index c84c02d5c..df517570f 100644
--- a/front/src/components/corpus/CorpusSelectItem.jsx
+++ b/front/src/components/corpus/CorpusSelectItem.jsx
@@ -13,13 +13,13 @@ export default function CorpusSelectItem({
articleId,
onChange,
}) {
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const toggleCorpusArticle = useCallback(
async (event) => {
event.preventDefault()
const [corpusId, checked] = [event.target.value, event.target.checked]
const query = checked ? addArticleToCorpus : removeArticleFromCorpus
- await runQuery({
+ await query({
query,
variables: { articleId: articleId, corpusId: corpusId },
})
diff --git a/front/src/components/corpus/CorpusUpdate.jsx b/front/src/components/corpus/CorpusUpdate.jsx
index cc3cc56ad..220ccb058 100644
--- a/front/src/components/corpus/CorpusUpdate.jsx
+++ b/front/src/components/corpus/CorpusUpdate.jsx
@@ -17,7 +17,7 @@ export default function CorpusUpdate({ corpus, onSubmit }) {
corpus.description
)
const titleInputRef = useRef()
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
useEffect(() => {
if (titleInputRef.current !== undefined) {
@@ -29,7 +29,7 @@ export default function CorpusUpdate({ corpus, onSubmit }) {
async (event) => {
try {
event.preventDefault()
- await runQuery({
+ await query({
query: updateCorpus,
variables: {
corpusId: corpus._id,
diff --git a/front/src/components/workspace/WorkspaceSelectItem.jsx b/front/src/components/workspace/WorkspaceSelectItem.jsx
index ac714ad6f..b8618e5c5 100644
--- a/front/src/components/workspace/WorkspaceSelectItem.jsx
+++ b/front/src/components/workspace/WorkspaceSelectItem.jsx
@@ -15,14 +15,14 @@ export default function WorkspaceSelectItem({
name,
onChange,
}) {
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
const activeUser = useSelector((state) => state.activeUser)
const toggleWorkspaceArticle = useCallback(
async (event) => {
event.preventDefault()
const [id, checked] = [event.target.value, event.target.checked]
const query = checked ? addArticle : removeArticle
- await runQuery({
+ await query({
query,
variables: { articleId: articleId, workspaceId: id },
})
diff --git a/front/src/components/workspace/Workspaces.jsx b/front/src/components/workspace/Workspaces.jsx
index 4a24857f0..a0096844e 100644
--- a/front/src/components/workspace/Workspaces.jsx
+++ b/front/src/components/workspace/Workspaces.jsx
@@ -30,12 +30,12 @@ export default function Workspaces() {
personal: true,
members: [],
})
- const runQuery = useGraphQLClient()
+ const { query } = useGraphQLClient()
useEffect(() => {
;(async () => {
try {
- const getUserStatsResponse = await runQuery({ query: getUserStats })
+ const getUserStatsResponse = await query({ query: getUserStats })
const userStats = getUserStatsResponse.user.stats
setPersonalWorkspace({
_id: activeUser._id,
diff --git a/front/src/helpers/graphQL.js b/front/src/helpers/graphQL.js
index 304c7ccd4..0c908df13 100644
--- a/front/src/helpers/graphQL.js
+++ b/front/src/helpers/graphQL.js
@@ -21,11 +21,13 @@ async function getErrorResponse(response) {
}
}
-async function askGraphQL(
- payload,
- action = 'fetching from the server',
- sessionToken = null
-) {
+/**
+ * @param {string} sessionToken
+ * @param {string} query
+ * @param {{[string: key]: value}|undefined} variables
+ * @returns {Promise}
+ */
+async function executeRequest({ sessionToken, query, variables }) {
const response = await fetch(applicationConfig.graphqlEndpoint, {
method: 'POST',
mode: 'cors',
@@ -36,13 +38,16 @@ async function askGraphQL(
// Authorization header is provided only when we have a token
...(sessionToken ? { Authorization: `Bearer ${sessionToken}` } : {}),
},
- body: JSON.stringify(payload),
+ body: JSON.stringify({
+ query,
+ variables,
+ }),
})
if (!response.ok) {
const errorResponse = await getErrorResponse(response)
console.error(
- `Something wrong happened during: ${action} => ${response.status}, ${
+ `Something wrong happened during => ${response.status}, ${
response.statusText
}: ${JSON.stringify(errorResponse)}`
)
@@ -63,25 +68,19 @@ async function askGraphQL(
export function useGraphQLClient() {
const sessionToken = useSelector((state) => state.sessionToken)
return {
- query: (query, variables) => runQuery({ query, variables, sessionToken }),
+ query: (query, variables) =>
+ executeQuery({ query, variables, sessionToken }),
}
}
/**
- * @typedef {Object} QueryParameters
- * @property {{
- * sessionToken: string,
- * query: DocumentNode|string,
- * variables: {[string: key]: value}
- * }}
- */
-
-/**
- * @param {QueryParameters} queryParameters
+ *
+ * @param {string} sessionToken
+ * @param {DocumentNode|string} queryOrAST
+ * @param {{[string: key]: value}|undefined} variables
* @returns {Promise}
*/
-export function runQuery({ sessionToken, query: queryOrAST, variables }) {
+export function executeQuery({ sessionToken, query: queryOrAST, variables }) {
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
-
- return askGraphQL({ query, variables }, null, sessionToken)
+ return executeRequest({ query, variables, sessionToken })
}
diff --git a/front/src/helpers/userProfile.js b/front/src/helpers/userProfile.js
index 45ac1507c..3d0e0ea4f 100644
--- a/front/src/helpers/userProfile.js
+++ b/front/src/helpers/userProfile.js
@@ -1,9 +1,9 @@
import { useDispatch } from 'react-redux'
-import { runQuery, useGraphQLClient } from './graphQL.js'
+import { executeQuery, useGraphQLClient } from './graphQL.js'
import { getFullUserProfile as getUserProfileQuery } from '../components/Credentials.graphql'
export function getUserProfile({ sessionToken }) {
- return runQuery({ sessionToken }, { query })
+ return executeQuery({ sessionToken, query: getUserProfileQuery })
}
export function useProfile() {
diff --git a/front/src/hooks/workspace.js b/front/src/hooks/workspace.js
index 026f40c61..cd13d8ee0 100644
--- a/front/src/hooks/workspace.js
+++ b/front/src/hooks/workspace.js
@@ -8,7 +8,7 @@ import {
create as createMutation,
leave as leaveMutation,
} from '../components/workspace/Workspaces.graphql'
-import { runQuery } from '../helpers/graphQL.js'
+import { executeQuery } from '../helpers/graphQL.js'
import useGraphQL, { useMutation, useSWRKey } from './graphql.js'
export function useActiveWorkspace() {
@@ -110,7 +110,7 @@ export function useWorkspaceActions() {
const key = useSWRKey()({ query: getWorkspaces })
const sessionToken = useSelector((state) => state.sessionToken)
const addWorkspace = async (workspace) => {
- await runQuery(
+ await executeQuery(
{ sessionToken },
{
query: createMutation,
@@ -129,7 +129,7 @@ export function useWorkspaceActions() {
}
const leaveWorkspace = async (workspaceId) => {
- await runQuery(
+ await executeQuery(
{ sessionToken },
{
query: leaveMutation,
diff --git a/front/src/services/ArticleService.js b/front/src/services/ArticleService.js
index 1fdffd30d..7b34c0f5a 100644
--- a/front/src/services/ArticleService.js
+++ b/front/src/services/ArticleService.js
@@ -1,4 +1,4 @@
-import { runQuery } from '../helpers/graphQL.js'
+import { executeQuery } from '../helpers/graphQL.js'
import { updateWorkingVersion, createVersion } from './ArticleService.graphql'
@@ -12,7 +12,7 @@ export default class ArticleService {
async saveText(md) {
const { sessionToken } = this
- return runQuery(
+ return executeQuery(
{ sessionToken },
{
query: updateWorkingVersion,
@@ -28,7 +28,7 @@ export default class ArticleService {
async saveBibliography(bib) {
const { sessionToken } = this
- return runQuery(
+ return executeQuery(
{ sessionToken },
{
query: updateWorkingVersion,
@@ -44,7 +44,7 @@ export default class ArticleService {
async saveMetadata(metadata) {
const { sessionToken } = this
- return runQuery(
+ return executeQuery(
{ sessionToken },
{
query: updateWorkingVersion,
@@ -60,7 +60,7 @@ export default class ArticleService {
async createNewVersion(major = false, message = '') {
const { sessionToken } = this
- return await runQuery(
+ return await executeQuery(
{ sessionToken },
{
query: createVersion,
From 09542b3ad8b39a8db4a28c3e81489a42950b2980 Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Tue, 4 Feb 2025 17:52:03 +0100
Subject: [PATCH 04/12] =?UTF-8?q?wip:=20d=C3=A9but=20de=20suppression=20de?=
=?UTF-8?q?=20useMutate,=20runMutation=20et=20useMutation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
front/src/components/ArticleContributors.jsx | 39 ++---------
front/src/helpers/graphQL.js | 53 ++++++++++-----
front/src/hooks/contributor.js | 45 +++++++++++++
front/src/hooks/graphql.js | 69 ++++++--------------
front/src/hooks/workspace.js | 42 ++++++------
5 files changed, 127 insertions(+), 121 deletions(-)
create mode 100644 front/src/hooks/contributor.js
diff --git a/front/src/components/ArticleContributors.jsx b/front/src/components/ArticleContributors.jsx
index ec49b55e5..fefe9acbc 100644
--- a/front/src/components/ArticleContributors.jsx
+++ b/front/src/components/ArticleContributors.jsx
@@ -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),
@@ -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),
diff --git a/front/src/helpers/graphQL.js b/front/src/helpers/graphQL.js
index 0c908df13..9f37c9efa 100644
--- a/front/src/helpers/graphQL.js
+++ b/front/src/helpers/graphQL.js
@@ -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}
*/
-async function executeRequest({ sessionToken, query, variables }) {
+async function executeRequest({
+ query,
+ variables,
+ sessionToken,
+ type = 'fetch',
+}) {
const response = await fetch(applicationConfig.graphqlEndpoint, {
method: 'POST',
mode: 'cors',
@@ -47,7 +53,7 @@ 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)}`
)
@@ -55,14 +61,22 @@ async function executeRequest({ sessionToken, query, variables }) {
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() {
@@ -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}
+ * @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 })
}
diff --git a/front/src/hooks/contributor.js b/front/src/hooks/contributor.js
new file mode 100644
index 000000000..87ac0f30d
--- /dev/null
+++ b/front/src/hooks/contributor.js
@@ -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,
+ }
+}
diff --git a/front/src/hooks/graphql.js b/front/src/hooks/graphql.js
index 1030005e5..3be78bee9 100644
--- a/front/src/hooks/graphql.js
+++ b/front/src/hooks/graphql.js
@@ -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
}
/**
@@ -53,22 +24,28 @@ 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,
@@ -76,6 +53,9 @@ export function runMutation(
})
}
+/**
+ * @deprecated
+ */
export function useMutate({ query: queryOrAST, variables }) {
const sessionToken = useSelector((state) => state.sessionToken)
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)
@@ -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)
- }
-}
diff --git a/front/src/hooks/workspace.js b/front/src/hooks/workspace.js
index cd13d8ee0..5dc62c67f 100644
--- a/front/src/hooks/workspace.js
+++ b/front/src/hooks/workspace.js
@@ -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'
@@ -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) => ({
From 5bd2867ccd580b7e7d691c84e6b58c17573a56ac Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Tue, 11 Feb 2025 12:08:09 +0100
Subject: [PATCH 05/12] fix: passe les arguments en tant qu'objet
---
front/src/components/Credentials.jsx | 4 ++--
front/src/helpers/graphQL.js | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/front/src/components/Credentials.jsx b/front/src/components/Credentials.jsx
index 1d8269c4d..199d23358 100644
--- a/front/src/components/Credentials.jsx
+++ b/front/src/components/Credentials.jsx
@@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import { useGraphQLClient } from '../helpers/graphQL'
-import { changePassword as query } from './Credentials.graphql'
+import { changePassword as changePasswordQuery } from './Credentials.graphql'
import styles from './credentials.module.scss'
import fieldStyles from './field.module.scss'
import Button from './Button'
@@ -39,7 +39,7 @@ export default function Credentials() {
new: password,
user: userId,
}
- await query({ query, variables })
+ await query({ query: changePasswordQuery, variables })
setPassword('')
setPasswordO('')
setPasswordC('')
diff --git a/front/src/helpers/graphQL.js b/front/src/helpers/graphQL.js
index 9f37c9efa..bd7c449d8 100644
--- a/front/src/helpers/graphQL.js
+++ b/front/src/helpers/graphQL.js
@@ -82,7 +82,7 @@ async function executeRequest({
export function useGraphQLClient() {
const sessionToken = useSelector((state) => state.sessionToken)
return {
- query: (query, variables) =>
+ query: ({query, variables}) =>
executeQuery({ query, variables, sessionToken }),
}
}
From b57fb29b9c4d242603c24926cf07dddbd0abc538 Mon Sep 17 00:00:00 2001
From: Thomas Parisot
Date: Wed, 26 Feb 2025 12:34:05 +0100
Subject: [PATCH 06/12] chore: utilise des traductions pour les toasts d'ajout
d'article
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Supprime des imports inutilisés.
---
front/src/components/ArticleContributors.jsx | 18 +++++++++---------
front/src/locales/en/translation.json | 2 ++
front/src/locales/fr/translation.json | 2 ++
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/front/src/components/ArticleContributors.jsx b/front/src/components/ArticleContributors.jsx
index fefe9acbc..502d5d591 100644
--- a/front/src/components/ArticleContributors.jsx
+++ b/front/src/components/ArticleContributors.jsx
@@ -1,15 +1,15 @@
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 { getArticleContributors } from './Article.graphql'
import { useToasts } from '@geist-ui/core'
+import { useTranslation } from 'react-i18next'
export default function ArticleContributors({ article, contributors }) {
const { setToast } = useToasts()
+ const { t } = useTranslation()
const articleId = article._id
const { addContributor, removeContributor } = useArticleContributorActions({
articleId,
@@ -22,9 +22,9 @@ export default function ArticleContributors({ article, contributors }) {
try {
await addContributor(userId)
setToast({
- text: `Contributeur ${
- user.displayName || user.username
- } ajouté à l'article.`,
+ text: t('article.contributors.added', {
+ name: user.displayName || user.username,
+ }),
type: 'default',
})
} catch (err) {
@@ -37,10 +37,10 @@ export default function ArticleContributors({ article, contributors }) {
try {
await removeContributor(userId)
setToast({
- text: `Contributeur ${
- user.displayName || user.username
- } supprimé de l'article.`,
- type: 'warning',
+ text: t('article.contributors.removed', {
+ name: user.displayName || user.username,
+ }),
+ type: 'default',
})
} catch (err) {
setToast({
diff --git a/front/src/locales/en/translation.json b/front/src/locales/en/translation.json
index 2973957a4..bae2bc82b 100644
--- a/front/src/locales/en/translation.json
+++ b/front/src/locales/en/translation.json
@@ -54,6 +54,8 @@
"time.fewSecondsAgo": "a few seconds ago",
"search.placeholder": "Search",
"articles.page.title": "Articles - {{ workspace }}",
+ "article.contributors.added": "{{ name }} is now a contributor.",
+ "article.contributors.removed": "{{ name }} has been removed from contributors.",
"article.count_zero": "no article",
"article.count_one": "{{ count }} article",
"article.count_other": "{{ count }} articles",
diff --git a/front/src/locales/fr/translation.json b/front/src/locales/fr/translation.json
index aad08bce1..43893436b 100644
--- a/front/src/locales/fr/translation.json
+++ b/front/src/locales/fr/translation.json
@@ -54,6 +54,8 @@
"time.fewSecondsAgo": "à lʼinstant",
"search.placeholder": "Recherche",
"articles.page.title": "Articles - {{ workspace }}",
+ "article.contributors.added": "{{ name }} peut désormais contribuer à cet article.",
+ "article.contributors.removed": "{{ name }} a été retiré·e des contributeur·ices.",
"article.count_zero": "aucun article",
"article.count_one": "{{ count }} article",
"article.count_other": "{{ count }} articles",
From 3a448e4352db9491150ccfc083806b576421202c Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Wed, 26 Feb 2025 12:54:57 +0100
Subject: [PATCH 07/12] =?UTF-8?q?fix:=20corrige=20l'=C3=A9crasement=20de?=
=?UTF-8?q?=20variables=20query?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
front/src/components/corpus/CorpusSelectItem.jsx | 6 ++++--
front/src/components/workspace/WorkspaceSelectItem.jsx | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/front/src/components/corpus/CorpusSelectItem.jsx b/front/src/components/corpus/CorpusSelectItem.jsx
index df517570f..3c41f6e65 100644
--- a/front/src/components/corpus/CorpusSelectItem.jsx
+++ b/front/src/components/corpus/CorpusSelectItem.jsx
@@ -18,9 +18,11 @@ export default function CorpusSelectItem({
async (event) => {
event.preventDefault()
const [corpusId, checked] = [event.target.value, event.target.checked]
- const query = checked ? addArticleToCorpus : removeArticleFromCorpus
+ const graphqlQuery = checked
+ ? addArticleToCorpus
+ : removeArticleFromCorpus
await query({
- query,
+ query: graphqlQuery,
variables: { articleId: articleId, corpusId: corpusId },
})
onChange({ corpusId })
diff --git a/front/src/components/workspace/WorkspaceSelectItem.jsx b/front/src/components/workspace/WorkspaceSelectItem.jsx
index b8618e5c5..4a12f4691 100644
--- a/front/src/components/workspace/WorkspaceSelectItem.jsx
+++ b/front/src/components/workspace/WorkspaceSelectItem.jsx
@@ -21,9 +21,9 @@ export default function WorkspaceSelectItem({
async (event) => {
event.preventDefault()
const [id, checked] = [event.target.value, event.target.checked]
- const query = checked ? addArticle : removeArticle
+ const graphqlQuery = checked ? addArticle : removeArticle
await query({
- query,
+ query: graphqlQuery,
variables: { articleId: articleId, workspaceId: id },
})
onChange({ workspaceId: id })
From 9b18be16731332c8cca4ae04bb028e9236b9ddf2 Mon Sep 17 00:00:00 2001
From: Guillaume Grossetie
Date: Wed, 26 Feb 2025 12:56:34 +0100
Subject: [PATCH 08/12] =?UTF-8?q?fix:=20renomme=20la=20variable=20pour=20?=
=?UTF-8?q?=C3=A9viter=20d'=C3=A9craser=20la=20fonction=20query?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
front/src/components/Chapter.jsx | 2 +-
front/src/components/Write/Write.jsx | 10 ++++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/front/src/components/Chapter.jsx b/front/src/components/Chapter.jsx
index d922783fe..a15fbe052 100644
--- a/front/src/components/Chapter.jsx
+++ b/front/src/components/Chapter.jsx
@@ -66,7 +66,7 @@ export default function Chapter({ article }) {
)}
- {renaming && renaming && (
+ {renaming && (