diff --git a/packages/sanity/src/core/releases/__fixtures__/release.fixture.ts b/packages/sanity/src/core/releases/__fixtures__/release.fixture.ts index b939335fc54..3ec28f9b81d 100644 --- a/packages/sanity/src/core/releases/__fixtures__/release.fixture.ts +++ b/packages/sanity/src/core/releases/__fixtures__/release.fixture.ts @@ -66,6 +66,7 @@ export const publishedASAPRelease: ReleaseDocument = { _type: 'system.release', _createdAt: '2023-10-10T08:00:00Z', _updatedAt: '2023-10-10T09:00:00Z', + publishedAt: '2023-10-10T10:00:00Z', state: 'published', metadata: { title: 'published Release', diff --git a/packages/sanity/src/core/releases/hooks/useReleaseTime.ts b/packages/sanity/src/core/releases/hooks/useReleaseTime.ts new file mode 100644 index 00000000000..2908d538aea --- /dev/null +++ b/packages/sanity/src/core/releases/hooks/useReleaseTime.ts @@ -0,0 +1,28 @@ +import {format} from 'date-fns' +import {useCallback} from 'react' + +import useTimeZone, {getLocalTimeZone} from '../../scheduledPublishing/hooks/useTimeZone' +import {type TableRelease} from '../tool/overview/ReleasesOverview' +import {getPublishDateFromRelease} from '../util/util' + +export const useReleaseTime = (): ((release: TableRelease) => string | null) => { + const {timeZone, utcToCurrentZoneDate} = useTimeZone() + const {abbreviation: localeTimeZoneAbbreviation} = getLocalTimeZone() + + const getTimezoneAbbreviation = useCallback( + () => + timeZone.abbreviation === localeTimeZoneAbbreviation ? '' : `(${timeZone.abbreviation})`, + [localeTimeZoneAbbreviation, timeZone.abbreviation], + ) + + return useCallback( + (release: TableRelease) => { + const publishDate = getPublishDateFromRelease(release) + + return publishDate + ? `${format(utcToCurrentZoneDate(publishDate), 'PPpp')} ${getTimezoneAbbreviation()}` + : null + }, + [getTimezoneAbbreviation, utcToCurrentZoneDate], + ) +} diff --git a/packages/sanity/src/core/releases/store/createReleaseStore.ts b/packages/sanity/src/core/releases/store/createReleaseStore.ts index ebbd1fd2777..5c69a280958 100644 --- a/packages/sanity/src/core/releases/store/createReleaseStore.ts +++ b/packages/sanity/src/core/releases/store/createReleaseStore.ts @@ -45,6 +45,7 @@ const QUERY_PROJECTION = `{ state, finalDocumentStates, publishAt, + publishedAt, "metadata": coalesce(metadata, { "title": "", "releaseType": "${DEFAULT_RELEASE_TYPE}", diff --git a/packages/sanity/src/core/releases/store/types.ts b/packages/sanity/src/core/releases/store/types.ts index b44b9ca0d0f..ccc814c1ea7 100644 --- a/packages/sanity/src/core/releases/store/types.ts +++ b/packages/sanity/src/core/releases/store/types.ts @@ -46,6 +46,10 @@ export interface ReleaseDocument extends SanityDocument { * If defined, it takes precedence over the intendedPublishAt, the state should be 'scheduled' */ publishAt?: string + /** + * If defined, it provides the time the release was actually published + */ + publishedAt?: string metadata: { title: string description?: string diff --git a/packages/sanity/src/core/releases/tool/components/ReleaseTime.tsx b/packages/sanity/src/core/releases/tool/components/ReleaseTime.tsx new file mode 100644 index 00000000000..f808fe65439 --- /dev/null +++ b/packages/sanity/src/core/releases/tool/components/ReleaseTime.tsx @@ -0,0 +1,19 @@ +import {useTranslation} from '../../../i18n' +import {useReleaseTime} from '../../hooks/useReleaseTime' +import {type TableRelease} from '../overview/ReleasesOverview' + +export const ReleaseTime: React.FC<{release: TableRelease}> = ({release}) => { + const {t} = useTranslation() + const getReleaseTime = useReleaseTime() + + const {metadata} = release + + if (metadata.releaseType === 'asap') { + return t('release.type.asap') + } + if (metadata.releaseType === 'undecided') { + return t('release.type.undecided') + } + + return getReleaseTime(release) +} diff --git a/packages/sanity/src/core/releases/tool/overview/__tests__/columnCells/ReleaseTime.test.tsx b/packages/sanity/src/core/releases/tool/components/__tests__/ReleaseTime.test.tsx similarity index 69% rename from packages/sanity/src/core/releases/tool/overview/__tests__/columnCells/ReleaseTime.test.tsx rename to packages/sanity/src/core/releases/tool/components/__tests__/ReleaseTime.test.tsx index 451b230147b..6ef50b9d040 100644 --- a/packages/sanity/src/core/releases/tool/overview/__tests__/columnCells/ReleaseTime.test.tsx +++ b/packages/sanity/src/core/releases/tool/components/__tests__/ReleaseTime.test.tsx @@ -1,20 +1,23 @@ import {render, screen, waitFor} from '@testing-library/react' -import {format} from 'date-fns' import {type ComponentProps} from 'react' import {describe, expect, it, vi} from 'vitest' -import {createTestProvider} from '../../../../../../../test/testUtils/TestProvider' -import {useTimeZoneMockReturn} from '../../../../../scheduledPublishing/hooks/__tests__/__mocks__/useTimeZone.mock' +import {getByDataUi} from '../../../../../../test/setup/customQueries' +import {createTestProvider} from '../../../../../../test/testUtils/TestProvider' +import {useTimeZoneMockReturn} from '../../../../scheduledPublishing/hooks/__tests__/__mocks__/useTimeZone.mock' import { activeASAPRelease, activeUndecidedRelease, scheduledRelease, -} from '../../../../__fixtures__/release.fixture' -import {releasesUsEnglishLocaleBundle} from '../../../../i18n' -import {ReleaseTime} from '../../columnCells/ReleaseTime' -import {type TableRelease} from '../../ReleasesOverview' +} from '../../../__fixtures__/release.fixture' +import {releasesUsEnglishLocaleBundle} from '../../../i18n' +import {type TableRelease} from '../../overview/ReleasesOverview' +import {ReleaseTime} from '../ReleaseTime' -vi.mock('../../../../scheduledPublishing/hooks/useTimeZone', () => useTimeZoneMockReturn) +vi.mock( + '../../../scheduledPublishing/hooks/useTimeZone', + vi.fn(() => useTimeZoneMockReturn), +) const renderTest = async (props: ComponentProps) => { const wrapper = await createTestProvider({ @@ -56,11 +59,11 @@ describe('ReleaseTime', () => { release: { ...scheduledRelease, publishAt: undefined, + publishedAt: undefined, metadata: {...scheduledRelease.metadata, intendedPublishAt: undefined}, } as TableRelease, }) - const formattedDate = `${format(new Date(), 'PPpp')}` - expect(screen.getByText(formattedDate, {exact: false})).toBeInTheDocument() + expect(getByDataUi(document.body, 'Box')).toBeEmptyDOMElement() }) }) diff --git a/packages/sanity/src/core/releases/tool/detail/ReleaseTypePicker.tsx b/packages/sanity/src/core/releases/tool/detail/ReleaseTypePicker.tsx index 23de132f5ea..acd765aeb55 100644 --- a/packages/sanity/src/core/releases/tool/detail/ReleaseTypePicker.tsx +++ b/packages/sanity/src/core/releases/tool/detail/ReleaseTypePicker.tsx @@ -13,13 +13,14 @@ import {getCalendarLabels} from '../../../form/inputs/DateInputs/utils' import {useTranslation} from '../../../i18n/hooks/useTranslation' import useTimeZone from '../../../scheduledPublishing/hooks/useTimeZone' import {ReleaseAvatar} from '../../components/ReleaseAvatar' +import {useReleaseTime} from '../../hooks/useReleaseTime' import {releasesLocaleNamespace} from '../../i18n' import {type ReleaseDocument, type ReleaseType} from '../../store' import {useReleaseOperations} from '../../store/useReleaseOperations' import {getIsScheduledDateInPast} from '../../util/getIsScheduledDateInPast' import {getReleaseTone} from '../../util/getReleaseTone' import {getPublishDateFromRelease, isReleaseScheduledOrScheduling} from '../../util/util' -import {ReleaseTime} from '../overview/columnCells/ReleaseTime' +import {ReleaseTime} from '../components/ReleaseTime' const dateInputFormat = 'PP HH:mm' @@ -36,6 +37,7 @@ export function ReleaseTypePicker(props: {release: ReleaseDocument}): React.JSX. const {updateRelease} = useReleaseOperations() const toast = useToast() const {utcToCurrentZoneDate, zoneDateToUtc} = useTimeZone() + const getReleaseTime = useReleaseTime() const [open, setOpen] = useState(false) const [releaseType, setReleaseType] = useState(release.metadata.releaseType) @@ -108,16 +110,16 @@ export function ReleaseTypePicker(props: {release: ReleaseDocument}): React.JSX. const publishDateLabel = useMemo(() => { if (release.state === 'published') { - if (isPublishDateInPast && release.publishAt) + if (isPublishDateInPast && publishDate) return tRelease('dashboard.details.published-on', { - date: format(new Date(publishDate), 'MMM d, yyyy, pp'), + date: getReleaseTime(release), }) return tRelease('dashboard.details.published-asap') } return - }, [isPublishDateInPast, publishDate, release, tRelease]) + }, [getReleaseTime, isPublishDateInPast, publishDate, release, tRelease]) const handleButtonReleaseTypeChange = useCallback((pickedReleaseType: ReleaseType) => { setReleaseType(pickedReleaseType) diff --git a/packages/sanity/src/core/releases/tool/detail/__tests__/ReleaseTypePicker.test.tsx b/packages/sanity/src/core/releases/tool/detail/__tests__/ReleaseTypePicker.test.tsx index 72ecc97c9d7..2ffa93eea99 100644 --- a/packages/sanity/src/core/releases/tool/detail/__tests__/ReleaseTypePicker.test.tsx +++ b/packages/sanity/src/core/releases/tool/detail/__tests__/ReleaseTypePicker.test.tsx @@ -76,7 +76,7 @@ describe('ReleaseTypePicker', () => { expect(screen.getByTestId('published-release-type-label')).toBeInTheDocument() - expect(screen.getByText('Published')).toBeInTheDocument() + expect(screen.getByText('Published on Oct 10, 2023, 3:00:00 AM')).toBeInTheDocument() }) it('renders the label with a published text when release was schedule published', async () => { diff --git a/packages/sanity/src/core/releases/tool/overview/ReleasesOverviewColumnDefs.tsx b/packages/sanity/src/core/releases/tool/overview/ReleasesOverviewColumnDefs.tsx index 1bb53eb1e2c..5124d209ae1 100644 --- a/packages/sanity/src/core/releases/tool/overview/ReleasesOverviewColumnDefs.tsx +++ b/packages/sanity/src/core/releases/tool/overview/ReleasesOverviewColumnDefs.tsx @@ -7,11 +7,11 @@ import {ToneIcon} from '../../../../ui-components/toneIcon/ToneIcon' import {Tooltip} from '../../../../ui-components/tooltip/Tooltip' import {RelativeTime} from '../../../components' import {getPublishDateFromRelease, isReleaseScheduledOrScheduling} from '../../util/util' +import {ReleaseTime} from '../components/ReleaseTime' import {Headers} from '../components/Table/TableHeader' import {type Column} from '../components/Table/types' import {ReleaseDocumentsCounter} from './columnCells/ReleaseDocumentsCounter' import {ReleaseNameCell} from './columnCells/ReleaseName' -import {ReleaseTime} from './columnCells/ReleaseTime' import {type TableRelease} from './ReleasesOverview' export const releasesOverviewColumnDefs: ( diff --git a/packages/sanity/src/core/releases/tool/overview/columnCells/ReleaseTime.tsx b/packages/sanity/src/core/releases/tool/overview/columnCells/ReleaseTime.tsx deleted file mode 100644 index 5963ee3b532..00000000000 --- a/packages/sanity/src/core/releases/tool/overview/columnCells/ReleaseTime.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import {format} from 'date-fns' -import {useCallback, useMemo} from 'react' - -import {useTranslation} from '../../../../i18n' -import useTimeZone, {getLocalTimeZone} from '../../../../scheduledPublishing/hooks/useTimeZone' -import {getPublishDateFromRelease} from '../../../util/util' -import {type TableRelease} from '../ReleasesOverview' - -export const ReleaseTime = ({release}: {release: TableRelease}) => { - const {t} = useTranslation() - const {timeZone, utcToCurrentZoneDate} = useTimeZone() - const {abbreviation: localeTimeZoneAbbreviation} = getLocalTimeZone() - - const {metadata} = release - - const getTimezoneAbbreviation = useCallback( - () => - timeZone.abbreviation === localeTimeZoneAbbreviation ? '' : `(${timeZone.abbreviation})`, - [localeTimeZoneAbbreviation, timeZone.abbreviation], - ) - - const timeString = useMemo(() => { - if (metadata.releaseType === 'asap') { - return t('release.type.asap') - } - if (metadata.releaseType === 'undecided') { - return t('release.type.undecided') - } - - const publishDate = getPublishDateFromRelease(release) - - return publishDate - ? `${format(utcToCurrentZoneDate(publishDate), 'PPpp')} ${getTimezoneAbbreviation()}` - : null - }, [metadata.releaseType, release, utcToCurrentZoneDate, getTimezoneAbbreviation, t]) - - return timeString -} diff --git a/packages/sanity/src/core/releases/util/util.ts b/packages/sanity/src/core/releases/util/util.ts index ba1f1207c1f..b9750c7b9ab 100644 --- a/packages/sanity/src/core/releases/util/util.ts +++ b/packages/sanity/src/core/releases/util/util.ts @@ -37,10 +37,9 @@ export function isDraftOrPublished(versionName: string): boolean { /** @internal */ export function getPublishDateFromRelease(release: ReleaseDocument): Date | null { - if (release.metadata.releaseType !== 'scheduled') return null + const dateString = release.publishedAt || release.publishAt || release.metadata.intendedPublishAt - const dateString = release.publishAt || release.metadata.intendedPublishAt - if (!dateString) return new Date() + if (!dateString) return null return new Date(dateString) }