diff --git a/packages/sanity/src/core/form/inputs/CrossDatasetReferenceInput/utils/TimeAgo.tsx b/packages/sanity/src/core/form/inputs/CrossDatasetReferenceInput/utils/TimeAgo.tsx deleted file mode 100644 index 1c131bb6540..00000000000 --- a/packages/sanity/src/core/form/inputs/CrossDatasetReferenceInput/utils/TimeAgo.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, {useEffect, useReducer} from 'react' -import formatDistanceToNow from 'date-fns/formatDistanceToNow' - -function useInterval(ms: number) { - const [tick, update] = useReducer((n) => n + 1, 0) - - useEffect(() => { - const i = setInterval(update, ms) - return () => clearInterval(i) - }, [ms]) - return tick -} - -export function TimeAgo({time}: {time: string}) { - useInterval(1000) - const timeSince = formatDistanceToNow(new Date(time)) - return {timeSince} ago -} diff --git a/packages/sanity/src/core/form/inputs/ReferenceInput/ReferencePreview.tsx b/packages/sanity/src/core/form/inputs/ReferenceInput/ReferencePreview.tsx index 87d4d413de9..f6454cc98ac 100644 --- a/packages/sanity/src/core/form/inputs/ReferenceInput/ReferencePreview.tsx +++ b/packages/sanity/src/core/form/inputs/ReferenceInput/ReferencePreview.tsx @@ -4,9 +4,9 @@ import {Box, Flex, Inline, Label, Text, Tooltip, useRootTheme} from '@sanity/ui' import {EditIcon, PublishIcon} from '@sanity/icons' import {RenderPreviewCallback} from '../../types' import {PreviewLayoutKey, TextWithTone} from '../../../components' +import {useTimeAgo} from '../../../hooks' import {useDocumentPresence} from '../../../store' import {DocumentPreviewPresence} from '../../../presence' -import {TimeAgo} from './utils/TimeAgo' import {ReferenceInfo} from './types' /** @@ -53,6 +53,16 @@ export function ReferencePreview(props: { [layout, previewStub, refType], ) + const timeSincePublished = useTimeAgo(preview.published?._updatedAt || '', { + minimal: true, + agoSuffix: true, + }) + + const timeSinceEdited = useTimeAgo(preview.draft?._updatedAt || '', { + minimal: true, + agoSuffix: true, + }) + return ( {renderPreview(previewProps)} @@ -76,13 +86,9 @@ export function ReferencePreview(props: { content={ - {preview.published?._updatedAt ? ( - <> - Published - - ) : ( - <>Not published - )} + {preview.published?._updatedAt + ? `Published ${timeSincePublished}` + : 'Not published'} } @@ -104,13 +110,9 @@ export function ReferencePreview(props: { content={ - {preview.draft?._updatedAt ? ( - <> - Edited - - ) : ( - <>No unpublished edits - )} + {preview.draft?._updatedAt + ? `Edited ${timeSinceEdited}` + : 'No unpublished edits'} } diff --git a/packages/sanity/src/core/form/inputs/ReferenceInput/utils/TimeAgo.tsx b/packages/sanity/src/core/form/inputs/ReferenceInput/utils/TimeAgo.tsx deleted file mode 100644 index 1c131bb6540..00000000000 --- a/packages/sanity/src/core/form/inputs/ReferenceInput/utils/TimeAgo.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, {useEffect, useReducer} from 'react' -import formatDistanceToNow from 'date-fns/formatDistanceToNow' - -function useInterval(ms: number) { - const [tick, update] = useReducer((n) => n + 1, 0) - - useEffect(() => { - const i = setInterval(update, ms) - return () => clearInterval(i) - }, [ms]) - return tick -} - -export function TimeAgo({time}: {time: string}) { - useInterval(1000) - const timeSince = formatDistanceToNow(new Date(time)) - return {timeSince} ago -} diff --git a/packages/sanity/src/desk/components/DraftStatus.tsx b/packages/sanity/src/desk/components/DraftStatus.tsx index 19c2e04b2fa..dc271e1f4d3 100644 --- a/packages/sanity/src/desk/components/DraftStatus.tsx +++ b/packages/sanity/src/desk/components/DraftStatus.tsx @@ -2,25 +2,21 @@ import React from 'react' import {EditIcon} from '@sanity/icons' import {PreviewValue, SanityDocument} from '@sanity/types' import {Box, Text, Tooltip} from '@sanity/ui' -import {TimeAgo} from './TimeAgo' -import {TextWithTone} from 'sanity' +import {TextWithTone, useTimeAgo} from 'sanity' export function DraftStatus(props: {document?: PreviewValue | Partial | null}) { const {document} = props const updatedAt = document && '_updatedAt' in document && document._updatedAt + // Label with abbreviations and suffix + const lastUpdatedTimeAgo = useTimeAgo(updatedAt || '', {minimal: true, agoSuffix: true}) + return ( - - {document ? ( - <>Edited {updatedAt && } - ) : ( - <>No unpublished edits - )} - + {document ? `Edited ${lastUpdatedTimeAgo}` : 'No unpublished edits'} } > diff --git a/packages/sanity/src/desk/components/PublishedStatus.tsx b/packages/sanity/src/desk/components/PublishedStatus.tsx index 0f257979df1..4b076539e06 100644 --- a/packages/sanity/src/desk/components/PublishedStatus.tsx +++ b/packages/sanity/src/desk/components/PublishedStatus.tsx @@ -2,26 +2,22 @@ import React from 'react' import {PublishIcon} from '@sanity/icons' import {PreviewValue, SanityDocument} from '@sanity/types' import {Box, Text, Tooltip} from '@sanity/ui' -import {TimeAgo} from './TimeAgo' -import {TextWithTone} from 'sanity' +import {TextWithTone, useTimeAgo} from 'sanity' export function PublishedStatus(props: {document?: PreviewValue | Partial | null}) { const {document} = props const updatedAt = document && '_updatedAt' in document && document._updatedAt const statusLabel = document ? 'Published' : 'Not published' + // Label with abbreviations and suffix + const lastUpdatedTimeAgo = useTimeAgo(updatedAt || '', {minimal: true, agoSuffix: true}) + return ( - - {document ? ( - <>Published {updatedAt && } - ) : ( - <>Not published - )} - + {document ? `Published ${lastUpdatedTimeAgo}` : 'Not published'} } > diff --git a/packages/sanity/src/desk/components/TimeAgo.tsx b/packages/sanity/src/desk/components/TimeAgo.tsx deleted file mode 100644 index 35edcddea50..00000000000 --- a/packages/sanity/src/desk/components/TimeAgo.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import {useTimeAgo} from 'sanity' - -export interface TimeAgoProps { - time: string | Date -} - -export function TimeAgo({time}: TimeAgoProps) { - const timeAgo = useTimeAgo(time) - - return {timeAgo} ago -} diff --git a/packages/sanity/src/desk/components/index.ts b/packages/sanity/src/desk/components/index.ts index d5e63400f44..5832cfb91cb 100644 --- a/packages/sanity/src/desk/components/index.ts +++ b/packages/sanity/src/desk/components/index.ts @@ -2,7 +2,6 @@ export * from './Delay' export * from './DocTitle' export * from './RenderActionCollectionState' export * from './RenderBadgeCollectionState' -export * from './TimeAgo' export * from './confirmDeleteDialog' export * from './pane' export * from './paneHeaderActions' diff --git a/packages/sanity/src/desk/documentActions/PublishAction.tsx b/packages/sanity/src/desk/documentActions/PublishAction.tsx index 8a07bd574c4..b99d2556809 100644 --- a/packages/sanity/src/desk/documentActions/PublishAction.tsx +++ b/packages/sanity/src/desk/documentActions/PublishAction.tsx @@ -1,7 +1,6 @@ import {CheckmarkIcon, PublishIcon} from '@sanity/icons' import {isValidationErrorMarker} from '@sanity/types' import React, {useCallback, useEffect, useState} from 'react' -import {TimeAgo} from '../components' import {useDocumentPane} from '../panes/document/useDocumentPane' import { DocumentActionComponent, @@ -11,6 +10,7 @@ import { useDocumentPairPermissions, useEditState, useSyncState, + useTimeAgo, useValidationStatus, } from 'sanity' @@ -28,9 +28,7 @@ function getDisabledReason( if (reason === 'ALREADY_PUBLISHED' && publishedAt) { return ( <> - - Published - + Published {publishedAt} ) } @@ -63,9 +61,14 @@ export const PublishAction: DocumentActionComponent = (props) => { const currentUser = useCurrentUser() + const lastPublishedTimeAgo = useTimeAgo(published?._updatedAt || '', { + minimal: true, + agoSuffix: true, + }) + // eslint-disable-next-line no-nested-ternary const title = publish.disabled - ? getDisabledReason(publish.disabled, (published || {})._updatedAt) || '' + ? getDisabledReason(publish.disabled, lastPublishedTimeAgo) || '' : hasValidationErrors ? 'There are validation errors that need to be fixed before this document can be published' : ''