diff --git a/front/src/components/Article.graphql b/front/src/components/Article.graphql index f9aa99005..946dc5c92 100644 --- a/front/src/components/Article.graphql +++ b/front/src/components/Article.graphql @@ -1,11 +1,11 @@ -query renameArticle($article: ID!, $title: String!) { - article(article: $article) { +query renameArticle($articleId: ID!, $title: String!) { + article(article: $articleId) { rename(title: $title) } } -query linkToZotero($article: ID!, $zotero: String!) { - article(article: $article) { +query linkToZotero($articleId: ID!, $zotero: String!) { + article(article: $articleId) { setZoteroLink(zotero: $zotero) } } @@ -46,14 +46,14 @@ query getArticleContributors($articleId: ID!) { } } -query deleteArticle($article: ID!) { - article(article: $article) { +query deleteArticle($articleId: ID!) { + article(article: $articleId) { delete(dryRun: false) } } -mutation duplicateArticle($user: ID, $article: ID!, $to: ID!) { - duplicateArticle(article: $article, to: $to, user: $user) { +mutation duplicateArticle($user: ID, $articleId: ID!, $to: ID!) { + duplicateArticle(article: $articleId, to: $to, user: $user) { _id title createdAt @@ -61,8 +61,8 @@ mutation duplicateArticle($user: ID, $article: ID!, $to: ID!) { } } -query addTags($article: ID!, $tags: [ID]!) { - article(article: $article) { +query addTags($articleId: ID!, $tags: [ID]!) { + article(article: $articleId) { addTags(tags: $tags) { _id name @@ -71,8 +71,8 @@ query addTags($article: ID!, $tags: [ID]!) { } } -query removeTags($article: ID!, $tags: [ID]!) { - article(article: $article) { +query removeTags($articleId: ID!, $tags: [ID]!) { + article(article: $articleId) { removeTags(tags: $tags) { _id name diff --git a/front/src/components/Article.jsx b/front/src/components/Article.jsx index 58393914d..1280a5e03 100644 --- a/front/src/components/Article.jsx +++ b/front/src/components/Article.jsx @@ -38,23 +38,18 @@ import { UserPlus, } from 'react-feather' -import { - duplicateArticle, - renameArticle, - deleteArticle, - getArticleTags, - getArticleContributors, -} from './Article.graphql' +import { getArticleTags, getArticleContributors } from './Article.graphql' import SoloSessionAction from './solo/SoloSessionAction.jsx' import { getTags } from './Tag.graphql' -import useGraphQL, { useMutation } from '../hooks/graphql' +import useFetchData from '../hooks/graphql' import TimeAgo from './TimeAgo.jsx' import WorkspaceSelectionItems from './workspace/WorkspaceSelectionItems.jsx' import { useSelector } from 'react-redux' import ArticleContributors from './ArticleContributors.jsx' import ArticleSendCopy from './ArticleSendCopy.jsx' +import { useArticleActions } from '../hooks/article.js' export default function Article({ article, @@ -69,22 +64,24 @@ export default function Article({ () => activeWorkspace?._id, [activeWorkspace] ) - - const { data: contributorsQueryData, error: contributorsError } = useGraphQL( - { query: getArticleContributors, variables: { articleId } }, - { - fallbackData: { - article, - }, - revalidateIfStale: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ) + const articleActions = useArticleActions({ articleId }) + + const { data: contributorsQueryData, error: contributorsError } = + useFetchData( + { query: getArticleContributors, variables: { articleId } }, + { + fallbackData: { + article, + }, + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + } + ) const contributors = ( contributorsQueryData?.article?.contributors || [] ).filter((c) => c.user._id !== article.owner._id) - const { data: userTagsQueryData } = useGraphQL( + const { data: userTagsQueryData } = useFetchData( { query: getTags, variables: {} }, { revalidateIfStale: false, @@ -93,7 +90,7 @@ export default function Article({ } ) const userTags = userTagsQueryData?.user?.tags || [] - const { data: articleTagsQueryData } = useGraphQL( + const { data: articleTagsQueryData } = useFetchData( { query: getArticleTags, variables: { articleId } }, { fallbackData: { @@ -113,7 +110,6 @@ export default function Article({ bindings: deleteArticleModalBinding, } = useModal() - const mutation = useMutation() const [expanded, setExpanded] = useState(false) const [exporting, setExporting] = useState(false) const [renaming, setRenaming] = useState(false) @@ -144,14 +140,7 @@ export default function Article({ ) const duplicate = async () => { - const duplicatedArticleQuery = await mutation({ - query: duplicateArticle, - variables: { - user: activeUser._id, - to: activeUser._id, - article: articleId, - }, - }) + const duplicatedArticleQuery = await articleActions.duplicate() onArticleCreated({ ...article, ...duplicatedArticleQuery.duplicateArticle, @@ -162,10 +151,7 @@ export default function Article({ const rename = async (e) => { e.preventDefault() - await mutation({ - query: renameArticle, - variables: { user: activeUser._id, article: articleId, title: newTitle }, - }) + await articleActions.rename(newTitle) onArticleUpdated({ ...article, title: newTitle, @@ -175,10 +161,7 @@ export default function Article({ const handleDeleteArticle = async () => { try { - await mutation({ - query: deleteArticle, - variables: { article: articleId }, - }) + await articleActions.remove() onArticleDeleted(article) setToast({ type: 'default', diff --git a/front/src/components/ArticleSendCopy.jsx b/front/src/components/ArticleSendCopy.jsx index de1e7520f..771aa9864 100644 --- a/front/src/components/ArticleSendCopy.jsx +++ b/front/src/components/ArticleSendCopy.jsx @@ -4,25 +4,20 @@ import { useToasts } from '@geist-ui/core' import { Send } from 'react-feather' import { useTranslation } from 'react-i18next' -import { duplicateArticle } from './Article.graphql' - import styles from './articleSendCopy.module.scss' import ContactSearch from './ContactSearch.jsx' -import { useMutation } from '../hooks/graphql.js' +import { useArticleActions } from '../hooks/article.js' export default function ArticleSendCopy({ article }) { const { setToast } = useToasts() - const mutation = useMutation() + const { copy } = useArticleActions({ articleId: article._id }) const { t } = useTranslation() const handleUserUpdated = useCallback( async ({ user, action }) => { if (action === 'select' || action === 'unselect') { try { - await mutation({ - query: duplicateArticle, - variables: { user: null, to: user._id, article: article._id }, - }) + await copy(user._id) setToast({ text: t('article.sendCopy.successNotification', { username: user.displayName || user.username, diff --git a/front/src/components/ArticleTags.jsx b/front/src/components/ArticleTags.jsx index 6ab4a7261..a8bfe3969 100644 --- a/front/src/components/ArticleTags.jsx +++ b/front/src/components/ArticleTags.jsx @@ -1,47 +1,23 @@ import { Loading } from '@geist-ui/core' import React, { useCallback } from 'react' -import useGraphQL, { useMutation } from '../hooks/graphql' import ArticleTag from './Tag' -import { addTags, removeTags, getArticleTags } from './Article.graphql' +import { useArticleTagActions } from '../hooks/article.js' export default function ArticleTags({ articleId, userTags, onArticleTagsUpdated, }) { - const { data, isLoading, mutate } = useGraphQL( - { query: getArticleTags, variables: { articleId } }, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ) - const mutation = useMutation() - - const articleTags = data?.article?.tags || [] - const articleTagIds = articleTags.map(({ _id }) => _id) + const { tags, isLoading, error, remove, add } = useArticleTagActions({ + articleId, + }) const handleClick = useCallback( async (event) => { const [id, checked] = [event.target.value, event.target.checked] - const query = checked ? addTags : removeTags - const result = await mutation({ - query, - variables: { article: articleId, tags: [id] }, - }) - const updatedTags = checked - ? result.article.addTags - : result.article.removeTags - mutate( - { - article: { - tags: updatedTags, - }, - }, - { revalidate: false } - ) + const updatedTags = checked ? await add(id) : await remove(id) onArticleTagsUpdated({ articleId, updatedTags }) }, [articleId] @@ -51,6 +27,11 @@ export default function ArticleTags({ return } + if (error) { + return
Error: {error.message}
+ } + + const articleTagIds = tags.map(({ _id }) => _id) return (