Skip to content

Commit e728372

Browse files
committed
feat(sanity): add release error details to ReleaseDashboardDetails
1 parent a346f6d commit e728372

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

packages/sanity/src/core/releases/i18n/resources.ts

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ const releasesLocaleStrings = {
141141
/** Label when a release has been deleted by a different user */
142142
'deleted-release': "The '<strong>{{title}}</strong>' release has been deleted",
143143

144+
/** Title text displayed for technical error details */
145+
'error-details-title': 'Error details',
144146
/** Title text when error during release update */
145147
'failed-edit-title': 'Failed to save changes',
146148
/** Title text displayed for releases that failed to publish */

packages/sanity/src/core/releases/tool/detail/ReleaseDashboardDetails.tsx

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
import {PinFilledIcon, PinIcon} from '@sanity/icons'
1+
import {ErrorOutlineIcon, PinFilledIcon, PinIcon} from '@sanity/icons'
22
import {
33
Box,
44
// Custom button with full radius used here
55
// eslint-disable-next-line no-restricted-imports
66
Button,
7+
Card,
78
Container,
89
Flex,
910
Stack,
11+
Text,
1012
} from '@sanity/ui'
1113
import {useCallback} from 'react'
1214

15+
import {ToneIcon} from '../../../../ui-components/toneIcon/ToneIcon'
16+
import {TextWithTone} from '../../../components/textWithTone/TextWithTone'
17+
import {Details} from '../../../form/components/Details'
1318
import {useTranslation} from '../../../i18n'
1419
import {usePerspective} from '../../../perspective/usePerspective'
1520
import {useSetPerspective} from '../../../perspective/useSetPerspective'
@@ -28,6 +33,7 @@ export function ReleaseDashboardDetails({release}: {release: ReleaseDocument}) {
2833
const {selectedReleaseId} = usePerspective()
2934
const setPerspective = useSetPerspective()
3035
const isSelected = releaseId === selectedReleaseId
36+
const shouldDisplayError = release.state === 'active' && typeof release.error !== 'undefined'
3137

3238
const handlePinRelease = useCallback(() => {
3339
if (isSelected) {
@@ -40,7 +46,7 @@ export function ReleaseDashboardDetails({release}: {release: ReleaseDocument}) {
4046
return (
4147
<Container width={3}>
4248
<Stack padding={3} paddingY={[4, 4, 5, 6]} space={[3, 3, 4, 5]}>
43-
<Flex gap={1}>
49+
<Flex gap={1} align="center">
4450
<Button
4551
disabled={state === 'archived' || state === 'published'}
4652
icon={isSelected ? PinFilledIcon : PinIcon}
@@ -54,11 +60,37 @@ export function ReleaseDashboardDetails({release}: {release: ReleaseDocument}) {
5460
tone={getReleaseTone(release)}
5561
/>
5662
<ReleaseTypePicker release={release} />
63+
{shouldDisplayError && (
64+
<Flex gap={2} padding={2} data-testid="release-error-details">
65+
<Text size={1}>
66+
<ToneIcon icon={ErrorOutlineIcon} tone="critical" />
67+
</Text>
68+
<TextWithTone size={1} tone="critical">
69+
{tRelease('failed-publish-title')}
70+
</TextWithTone>
71+
</Flex>
72+
)}
5773
</Flex>
58-
5974
<Box padding={2}>
6075
<ReleaseDetailsEditor release={release} />
6176
</Box>
77+
{shouldDisplayError && (
78+
<Card padding={4} radius={4} tone="critical">
79+
<Flex gap={3}>
80+
<Text size={1}>
81+
<ErrorOutlineIcon />
82+
</Text>
83+
<Stack space={4}>
84+
<Text>{tRelease('failed-publish-title')}</Text>
85+
<Details title={tRelease('error-details-title')}>
86+
<Text>
87+
<code>{release.error?.message}</code>
88+
</Text>
89+
</Details>
90+
</Stack>
91+
</Flex>
92+
</Card>
93+
)}
6294
</Stack>
6395
</Container>
6496
)

packages/sanity/src/core/releases/tool/detail/__tests__/ReleaseDetail.test.tsx

+26-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import {beforeEach, describe, expect, it, vi} from 'vitest'
44

55
import {mockUseRouterReturn} from '../../../../../../test/mocks/useRouter.mock'
66
import {createTestProvider} from '../../../../../../test/testUtils/TestProvider'
7-
import {activeASAPRelease, publishedASAPRelease} from '../../../__fixtures__/release.fixture'
7+
import {
8+
activeASAPRelease,
9+
activeUndecidedErrorRelease,
10+
publishedASAPRelease,
11+
} from '../../../__fixtures__/release.fixture'
812
import {releasesUsEnglishLocaleBundle} from '../../../i18n'
913
import {
1014
mockUseActiveReleases,
@@ -326,4 +330,25 @@ describe('after releases have loaded', () => {
326330
screen.getByText(activeASAPRelease.metadata.title)
327331
})
328332
})
333+
334+
describe('with release in error state', () => {
335+
beforeEach(async () => {
336+
mockUseActiveReleases.mockReset()
337+
338+
mockUseActiveReleases.mockReturnValue({
339+
...useActiveReleasesMockReturn,
340+
data: [activeUndecidedErrorRelease],
341+
})
342+
343+
mockUseRouterReturn.state = {
344+
releaseId: getReleaseIdFromReleaseDocumentId(activeUndecidedErrorRelease._id),
345+
}
346+
347+
await renderTest()
348+
})
349+
350+
it('should show error message', () => {
351+
screen.getByTestId('release-error-details')
352+
})
353+
})
329354
})

0 commit comments

Comments
 (0)