diff --git a/packages/sanity/src/core/tasks/components/form/tasksFormBuilder/FormCreate.tsx b/packages/sanity/src/core/tasks/components/form/tasksFormBuilder/FormCreate.tsx index d4c8f5210a3..4e14d304f6d 100644 --- a/packages/sanity/src/core/tasks/components/form/tasksFormBuilder/FormCreate.tsx +++ b/packages/sanity/src/core/tasks/components/form/tasksFormBuilder/FormCreate.tsx @@ -2,6 +2,7 @@ import {TrashIcon} from '@sanity/icons' import {useTelemetry} from '@sanity/telemetry/react' import {Box, Flex, Switch, Text, useToast} from '@sanity/ui' import {useCallback, useEffect, useState} from 'react' +import {useEffectEvent} from 'use-effect-event' import {Button} from '../../../../../ui-components' import {type ObjectInputProps, set} from '../../../../form' @@ -47,46 +48,48 @@ export function FormCreate(props: ObjectInputProps) { const {data} = useTasks() const savedTask = data.find((task) => task._id === value._id) + const handleCreatingSuccess = useEffectEvent(() => { + telemetry.log(TaskCreated) + toast.push({ + closable: true, + status: 'success', + title: t('form.status.success'), + }) + + setCreating(false) + if (createMore) { + setViewMode({type: 'create'}) + } else { + setActiveTab('subscribed') + } + }) useEffect(() => { // This useEffect takes care of closing the form when a task entered the "creation" state. // That action is async and we don't have access to the promise, once the value is updated in the form we will close the form. if (creating && savedTask?.createdByUser) { - telemetry.log(TaskCreated) - toast.push({ - closable: true, - status: 'success', - title: t('form.status.success'), - }) - - setCreating(false) - if (createMore) { - setViewMode({type: 'create'}) - } else { - setActiveTab('subscribed') - } + handleCreatingSuccess() } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [creating, savedTask?.createdByUser]) + }, [creating, handleCreatingSuccess, savedTask?.createdByUser]) + const handleCreatingTimeout = useEffectEvent(() => { + setCreating(false) + toast.push({ + closable: true, + status: 'error', + title: t('form.status.error.creation-failed'), + }) + }) useEffect(() => { // If after 10 seconds the task is still in the "creating" state, show an error and reset the creating state. let timeoutId: ReturnType | null = null if (creating) { - timeoutId = setTimeout(() => { - setCreating(false) - toast.push({ - closable: true, - status: 'error', - title: t('form.status.error.creation-failed'), - }) - }, 10000) + timeoutId = setTimeout(() => handleCreatingTimeout(), 10000) } // Cleanup function to clear the timeout return () => { if (timeoutId) clearTimeout(timeoutId) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [creating]) + }, [creating, handleCreatingTimeout]) const handleCreate = useCallback(async () => { setCreating(true) diff --git a/packages/sanity/src/core/tasks/hooks/useActivityLog.ts b/packages/sanity/src/core/tasks/hooks/useActivityLog.ts index 07c93a13016..6fb44d12597 100644 --- a/packages/sanity/src/core/tasks/hooks/useActivityLog.ts +++ b/packages/sanity/src/core/tasks/hooks/useActivityLog.ts @@ -1,5 +1,6 @@ import {type TransactionLogEventWithEffects} from '@sanity/types' import {useCallback, useEffect, useState} from 'react' +import {useEffectEvent} from 'use-effect-event' import {useClient} from '../../hooks' import {getJsonStream} from '../../store/_legacy/history/history/getJsonStream' @@ -65,10 +66,12 @@ export function useActivityLog(task: TaskDocument): { [transactionsUrl, token, publishedId], ) + const handleFetchAndParse = useEffectEvent(() => fetchAndParse(task)) useEffect(() => { - fetchAndParse(task) // Task is updated on every change, wait until the revision changes to update the activity log. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [fetchAndParse, task._rev]) + if (task._rev) { + handleFetchAndParse() + } + }, [handleFetchAndParse, task._rev]) return {changes} } diff --git a/packages/sanity/src/structure/panes/document/documentPanel/documentViews/FormView.tsx b/packages/sanity/src/structure/panes/document/documentPanel/documentViews/FormView.tsx index 930d27386e4..c983f41b983 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/documentViews/FormView.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/documentViews/FormView.tsx @@ -15,6 +15,7 @@ import { useDocumentStore, useTranslation, } from 'sanity' +import {useEffectEvent} from 'use-effect-event' import {Delay} from '../../../../components' import {structureLocaleNamespace} from '../../../../i18n' @@ -102,21 +103,23 @@ export const FormView = forwardRef(function FormV }, [documentId, documentStore, documentType, patchChannel]) const hasRev = Boolean(value?._rev) + const handleInitialValue = useEffectEvent(() => { + // this is a workaround for an issue that caused the document pushed to withDocument to get + // stuck at the first initial value. + // This effect is triggered only when the document goes from not having a revision, to getting one + // so it will kick in as soon as the document is received from the backend + patchChannel.publish({ + type: 'mutation', + patches: [], + snapshot: value, + }) + }) useEffect(() => { if (hasRev) { - // this is a workaround for an issue that caused the document pushed to withDocument to get - // stuck at the first initial value. - // This effect is triggered only when the document goes from not having a revision, to getting one - // so it will kick in as soon as the document is received from the backend - patchChannel.publish({ - type: 'mutation', - patches: [], - snapshot: value, - }) + handleInitialValue() } // React to changes in hasRev only - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [hasRev]) + }, [handleInitialValue, hasRev]) const [formRef, setFormRef] = useState(null) diff --git a/packages/sanity/src/structure/panes/documentList/DocumentListPaneContent.tsx b/packages/sanity/src/structure/panes/documentList/DocumentListPaneContent.tsx index 8d9a2a8c7e7..483261307a5 100644 --- a/packages/sanity/src/structure/panes/documentList/DocumentListPaneContent.tsx +++ b/packages/sanity/src/structure/panes/documentList/DocumentListPaneContent.tsx @@ -247,10 +247,6 @@ export function DocumentListPaneContent(props: DocumentListPaneContentProps) { ) - // Explicitly don't include `noDocumentsContent` in the deps array, as it's - // causing a visual bug where the "No documents" message is shown for a split second - // when clearing a search query with no results - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ collapsed, error, @@ -260,11 +256,13 @@ export function DocumentListPaneContent(props: DocumentListPaneContentProps) { items, layout, loadingVariant, - // noDocumentsContent, + noDocumentsContent, onRetry, + paneTitle, renderItem, searchInputElement, shouldRender, + t, ]) return (