|
| 1 | +import {type SanityDocument} from '@sanity/client' |
| 2 | +import {ErrorOutlineIcon} from '@sanity/icons' |
| 3 | +import {useTelemetry} from '@sanity/telemetry/react' |
| 4 | +import {Flex, Text} from '@sanity/ui' |
| 5 | +import {useCallback, useEffect, useState} from 'react' |
| 6 | +import { |
| 7 | + isDraftId, |
| 8 | + type ObjectSchemaType, |
| 9 | + Translate, |
| 10 | + useDocumentOperation, |
| 11 | + useTranslation, |
| 12 | +} from 'sanity' |
| 13 | + |
| 14 | +import {Button} from '../../../../../ui-components' |
| 15 | +import {structureLocaleNamespace} from '../../../../i18n' |
| 16 | +import {ResolvedLiveEdit} from './__telemetry__/DraftLiveEditBanner.telemetry' |
| 17 | +import {Banner} from './Banner' |
| 18 | + |
| 19 | +interface DraftLiveEditBannerProps { |
| 20 | + displayed: Partial<SanityDocument> | null |
| 21 | + documentId: string |
| 22 | + schemaType: ObjectSchemaType |
| 23 | +} |
| 24 | + |
| 25 | +export function DraftLiveEditBanner({ |
| 26 | + displayed, |
| 27 | + documentId, |
| 28 | + schemaType, |
| 29 | +}: DraftLiveEditBannerProps): JSX.Element | null { |
| 30 | + const {t} = useTranslation(structureLocaleNamespace) |
| 31 | + const [isPublishing, setPublishing] = useState(false) |
| 32 | + const [isDiscarding, setDiscarding] = useState(false) |
| 33 | + const telemetry = useTelemetry() |
| 34 | + |
| 35 | + const {publish, discardChanges} = useDocumentOperation(documentId, displayed?._type || '') |
| 36 | + |
| 37 | + const handlePublish = useCallback(() => { |
| 38 | + publish.execute() |
| 39 | + setPublishing(true) |
| 40 | + telemetry.log(ResolvedLiveEdit, {liveEditResolveType: 'publish'}) |
| 41 | + }, [publish, telemetry]) |
| 42 | + |
| 43 | + const handleDiscard = useCallback(() => { |
| 44 | + discardChanges.execute() |
| 45 | + setDiscarding(true) |
| 46 | + telemetry.log(ResolvedLiveEdit, {liveEditResolveType: 'discard'}) |
| 47 | + }, [discardChanges, telemetry]) |
| 48 | + |
| 49 | + useEffect(() => { |
| 50 | + return () => { |
| 51 | + setPublishing(false) |
| 52 | + setDiscarding(false) |
| 53 | + } |
| 54 | + }) |
| 55 | + |
| 56 | + if (displayed && displayed._id && !isDraftId(displayed._id)) { |
| 57 | + return null |
| 58 | + } |
| 59 | + |
| 60 | + return ( |
| 61 | + <Banner |
| 62 | + content={ |
| 63 | + <Flex align="center" justify="space-between" gap={1}> |
| 64 | + <Text size={1} weight="medium"> |
| 65 | + <Translate |
| 66 | + t={t} |
| 67 | + i18nKey={'banners.live-edit-draft-banner.text'} |
| 68 | + values={{schemaType: schemaType.title}} |
| 69 | + /> |
| 70 | + </Text> |
| 71 | + <Button |
| 72 | + onClick={handlePublish} |
| 73 | + text={t('action.publish.live-edit.label')} |
| 74 | + tooltipProps={{content: t('banners.live-edit-draft-banner.publish.tooltip')}} |
| 75 | + loading={isPublishing} |
| 76 | + /> |
| 77 | + |
| 78 | + <Button |
| 79 | + onClick={handleDiscard} |
| 80 | + text={t('banners.live-edit-draft-banner.discard.tooltip')} |
| 81 | + tooltipProps={{content: t('banners.live-edit-draft-banner.discard.tooltip')}} |
| 82 | + loading={isDiscarding} |
| 83 | + /> |
| 84 | + </Flex> |
| 85 | + } |
| 86 | + data-testid="live-edit-type-banner" |
| 87 | + icon={ErrorOutlineIcon} |
| 88 | + /> |
| 89 | + ) |
| 90 | +} |
0 commit comments