Skip to content

Commit

Permalink
fix(corel): refactor version history to fetch all release documents
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrobonamin committed Jul 12, 2024
1 parent 18686e5 commit c8c950c
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 81 deletions.
10 changes: 9 additions & 1 deletion packages/sanity/src/core/releases/tool/detail/ReleaseDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {type BundleDocument} from '../../../store/bundles/types'
import {API_VERSION} from '../../../tasks/constants'
import {BundleMenuButton} from '../../components/BundleMenuButton/BundleMenuButton'
import {type ReleasesRouterState} from '../../types/router'
import {useReleaseHistory} from './documentTable/useReleaseHistory'
import {ReleaseOverview} from './ReleaseOverview'

type Screen = 'overview' | 'review'
Expand All @@ -29,6 +30,8 @@ export const ReleaseDetail = () => {
const {data, loading} = useBundles()
const {documents: bundleDocuments, loading: documentsLoading} =
useFetchBundleDocuments(parsedBundleName)
const history = useReleaseHistory(bundleDocuments)

const bundle = data?.find((storeBundle) => storeBundle.name === parsedBundleName)
const bundleHasDocuments = !!bundleDocuments.length
const showPublishButton = loading || !bundle?.publishedAt
Expand Down Expand Up @@ -120,7 +123,12 @@ export const ReleaseDetail = () => {
) : (
<>
{activeScreen === 'overview' && (
<ReleaseOverview documents={bundleDocuments} release={bundle} />
<ReleaseOverview
documents={bundleDocuments}
release={bundle}
documentsHistory={history.documentsHistory}
collaborators={history.collaborators}
/>
)}
</>
)}
Expand Down
17 changes: 10 additions & 7 deletions packages/sanity/src/core/releases/tool/detail/ReleaseOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ import {type BundleDocument} from '../../../store/bundles/types'
import {useAddonDataset} from '../../../studio/addonDataset/useAddonDataset'
import {Chip} from '../../components/Chip'
import {DocumentTable} from './documentTable'
import {type DocumentHistory} from './documentTable/useReleaseHistory'

export function ReleaseOverview(props: {documents: SanityDocument[]; release: BundleDocument}) {
const {documents, release} = props
export function ReleaseOverview(props: {
documents: SanityDocument[]
documentsHistory: Map<string, DocumentHistory>
collaborators: string[]
release: BundleDocument
}) {
const {documents, documentsHistory, release, collaborators} = props
const {client} = useAddonDataset()
/**
* This state is created here but will be updated by the DocumentRow component when fetching the history
*/
const [collaborators, setCollaborators] = useState<string[]>([])

const [iconValue, setIconValue] = useState<BundleIconEditorPickerValue>({
hue: release.hue ?? 'gray',
icon: release.icon ?? 'documents',
Expand Down Expand Up @@ -132,7 +135,7 @@ export function ReleaseOverview(props: {documents: SanityDocument[]; release: Bu
<DocumentTable
documents={documents}
release={release}
setCollaborators={setCollaborators}
documentsHistory={documentsHistory}
/>
)}
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import {CheckmarkCircleIcon, EmptyIcon, Progress50Icon} from '@sanity/icons'
import {type SanityDocument} from '@sanity/types'
import {AvatarStack, Box, Card, Flex, Text} from '@sanity/ui'
import {
type Dispatch,
type ForwardedRef,
forwardRef,
type SetStateAction,
useEffect,
useMemo,
} from 'react'
import {type ForwardedRef, forwardRef, useMemo} from 'react'
import {getPublishedId, RelativeTime, SanityDefaultPreview, UserAvatar} from 'sanity'
import {IntentLink} from 'sanity/router'

import {Tooltip} from '../../../../../ui-components'
import {type BundleDocument} from '../../../../store/bundles/types'
import {DocumentActions} from './DocumentActions'
import {useDocumentPreviewValues} from './useDocumentPreviewValues'
import {useVersionHistory} from './useVersionHistory'
import {type DocumentHistory} from './useReleaseHistory'

const DOCUMENT_STATUS = {
ready: {
Expand Down Expand Up @@ -63,19 +56,22 @@ export function DocumentRow(props: {
searchTerm: string
document: SanityDocument
release: BundleDocument
setCollaborators: Dispatch<SetStateAction<string[]>>
history: DocumentHistory | undefined
}) {
const {document, release, searchTerm, setCollaborators} = props
const {
document,
release,
searchTerm,
history = {
editors: [],
createdBy: undefined,
lastEditedBy: undefined,
},
} = props
const documentId = document._id
const documentTypeName = document._type
const {previewValues, isLoading} = useDocumentPreviewValues({document, release})

const history = useVersionHistory(documentId, document?._rev)

useEffect(() => {
setCollaborators((pre) => Array.from(new Set([...pre, ...history.editors])))
}, [history.editors, setCollaborators])

const LinkComponent = useMemo(
() =>
// eslint-disable-next-line @typescript-eslint/no-shadow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {type SanityDocument} from '@sanity/types'
import {Stack} from '@sanity/ui'
import {type Dispatch, type SetStateAction, useMemo, useState} from 'react'
import {useMemo, useState} from 'react'
import {styled} from 'styled-components'

import {type BundleDocument} from '../../../../store/bundles/types'
import {DocumentHeader} from './DocumentHeader'
import {DocumentRow} from './DocumentRow'
import {type DocumentSort} from './types'
import {type DocumentHistory} from './useReleaseHistory'

const RowStack = styled(Stack)({
'& > *:not(:first-child)': {
Expand All @@ -23,10 +24,10 @@ const RowStack = styled(Stack)({

export function DocumentTable(props: {
documents: SanityDocument[]
documentsHistory: Map<string, DocumentHistory>
release: BundleDocument
setCollaborators: Dispatch<SetStateAction<string[]>>
}) {
const {documents, release, setCollaborators} = props
const {documents, release, documentsHistory} = props
// Filter will happen at the DocumentRow level because we don't have access here to the preview values.
const [searchTerm, setSearchTerm] = useState<string>('')
const [sort, setSort] = useState<DocumentSort>({property: '_updatedAt', order: 'desc'})
Expand Down Expand Up @@ -66,7 +67,7 @@ export function DocumentTable(props: {
document={d}
key={d._id}
release={release}
setCollaborators={setCollaborators}
history={documentsHistory.get(d._id)}
/>
))}
</RowStack>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {useCallback, useEffect, useMemo, useState} from 'react'
import {
type BundleDocument,
getPublishedId,
type TransactionLogEventWithEffects,
useClient,
} from 'sanity'

import {getJsonStream} from '../../../../store/_legacy/history/history/getJsonStream'
import {API_VERSION} from '../../../../tasks/constants'

export type DocumentHistory = {
history: TransactionLogEventWithEffects[]
createdBy: string
lastEditedBy: string
editors: string[]
}

// TODO: Update this to contemplate the _revision change on any of the internal bundle documents, and fetch only the history of that document if changes.
export function useReleaseHistory(bundleDocuments: BundleDocument[]): {
documentsHistory: Map<string, DocumentHistory>
collaborators: string[]
loading: boolean
} {
const client = useClient({apiVersion: API_VERSION})
const {dataset, token} = client.config()
const [history, setHistory] = useState<TransactionLogEventWithEffects[]>([])
const queryParams = `tag=sanity.studio.tasks.history&effectFormat=mendoza&excludeContent=true&includeIdentifiedDocumentsOnly=true`
const bundleDocumentsIds = useMemo(() => bundleDocuments.map((doc) => doc._id), [bundleDocuments])

const publishedIds = bundleDocumentsIds.map((id) => getPublishedId(id)).join(',')
const transactionsUrl = client.getUrl(
`/data/history/${dataset}/transactions/${publishedIds}?${queryParams}`,
)

const fetchAndParseAll = useCallback(async () => {
if (!publishedIds) return
const transactions: TransactionLogEventWithEffects[] = []
const stream = await getJsonStream(transactionsUrl, token)
const reader = stream.getReader()
let result
for (;;) {
result = await reader.read()
if (result.done) {
break
}
if ('error' in result.value) {
throw new Error(result.value.error.description || result.value.error.type)
}
transactions.push(result.value)
}
setHistory(transactions)
}, [publishedIds, transactionsUrl, token])

useEffect(() => {
fetchAndParseAll()
// When revision changes, update the history.
// eslint-disable-next-line react-hooks/exhaustive-deps

Check warning on line 58 in packages/sanity/src/core/releases/tool/detail/documentTable/useReleaseHistory.ts

View workflow job for this annotation

GitHub Actions / lint

React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior
}, [fetchAndParseAll])

return useMemo(() => {
const collaborators: string[] = []
const documentsHistory = new Map<string, DocumentHistory>()
if (!history.length) {
return {documentsHistory, collaborators, loading: true}
}
history.forEach((item) => {
const documentId = item.documentIDs[0]
let documentHistory = documentsHistory.get(documentId)
if (!collaborators.includes(item.author)) {
collaborators.push(item.author)
}
// eslint-disable-next-line no-negated-condition
if (!documentHistory) {
documentHistory = {
history: [item],
createdBy: item.author,
lastEditedBy: item.author,
editors: [item.author],
}
documentsHistory.set(documentId, documentHistory)
} else {
// @ts-expect-error TransactionLogEventWithEffects has no property 'mutations' but it's returned from the API
const isCreate = item.mutations.some((mutation) => 'create' in mutation)
if (isCreate) documentHistory.createdBy = item.author
if (!documentHistory.editors.includes(item.author)) {
documentHistory.editors.push(item.author)
}
// The last item in the history is the last edited by, transaction log is ordered by timestamp
documentHistory.lastEditedBy = item.author
// always add history item
documentHistory.history.push(item)
}
})

return {documentsHistory, collaborators, loading: false}
}, [history])
}

This file was deleted.

0 comments on commit c8c950c

Please sign in to comment.