Skip to content

Commit

Permalink
[desk-tool] Fix lint errors and increase readability in actions
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent aec5299 commit acc28f4
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 131 deletions.
36 changes: 21 additions & 15 deletions packages/@sanity/desk-tool/src/actions/DeleteAction.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import {useDocumentOperation} from '@sanity/react-hooks'
import ConfirmDelete from '../components/ConfirmDelete'
import TrashIcon from 'part:@sanity/base/trash-icon'
import React, {useCallback} from 'react'
import ConfirmDelete from '../components/ConfirmDelete'

const DISABLED_REASON_TITLE = {
NOTHING_TO_DELETE: "This document doesn't yet exist or is already deleted"
Expand All @@ -12,15 +12,29 @@ export function DeleteAction({id, type, draft, published, onComplete}) {
const [isDeleting, setIsDeleting] = React.useState(false)
const [isConfirmDialogOpen, setConfirmDialogOpen] = React.useState(false)

const handleCancel = useCallback(() => {
setConfirmDialogOpen(false)
onComplete()
}, [onComplete])

const handleConfirm = useCallback(() => {
setIsDeleting(true)
setConfirmDialogOpen(false)
deleteOp.execute()
onComplete()
}, [deleteOp, onComplete])

const handle = useCallback(() => {
setConfirmDialogOpen(true)
}, [])

return {
icon: TrashIcon,
disabled: Boolean(deleteOp.disabled),
title: (deleteOp.disabled && DISABLED_REASON_TITLE[deleteOp.disabled]) || '',
label: isDeleting ? 'Deleting…' : 'Delete',
shortcut: 'Ctrl+Alt+D',
onHandle: () => {
setConfirmDialogOpen(true)
},
onHandle: handle,
dialog: isConfirmDialogOpen && {
type: 'legacy',
onClose: onComplete,
Expand All @@ -29,16 +43,8 @@ export function DeleteAction({id, type, draft, published, onComplete}) {
<ConfirmDelete
draft={draft}
published={published}
onCancel={() => {
setConfirmDialogOpen(false)
onComplete()
}}
onConfirm={async () => {
setIsDeleting(true)
setConfirmDialogOpen(false)
deleteOp.execute()
onComplete()
}}
onCancel={handleCancel}
onConfirm={handleConfirm}
/>
)
}
Expand Down
38 changes: 24 additions & 14 deletions packages/@sanity/desk-tool/src/actions/DiscardChangesAction.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {useDocumentOperation} from '@sanity/react-hooks'
import ResetIcon from 'part:@sanity/base/reset-icon'
import React, {useCallback, useMemo} from 'react'

const DISABLED_REASON_TITLE = {
NO_CHANGES: 'This document has no unpublished changes',
Expand All @@ -11,6 +11,27 @@ export function DiscardChangesAction({id, type, published, liveEdit, onComplete}
const {discardChanges}: any = useDocumentOperation(id, type)
const [isConfirmDialogOpen, setConfirmDialogOpen] = React.useState(false)

const handleConfirm = useCallback(() => {
discardChanges.execute()
onComplete()
}, [discardChanges, onComplete])

const handle = useCallback(() => {
setConfirmDialogOpen(true)
}, [])

const dialog = useMemo(
() =>
isConfirmDialogOpen && {
type: 'confirm',
color: 'danger',
onCancel: onComplete,
onConfirm: handleConfirm,
message: <>Are you sure you want to discard all changes since last published?</>
},
[handleConfirm, isConfirmDialogOpen, onComplete]
)

if (!published || liveEdit) {
return null
}
Expand All @@ -20,18 +41,7 @@ export function DiscardChangesAction({id, type, published, liveEdit, onComplete}
disabled: Boolean(discardChanges.disabled),
title: (discardChanges.disabled && DISABLED_REASON_TITLE[discardChanges.disabled]) || '',
label: 'Discard changes',
onHandle: () => {
setConfirmDialogOpen(true)
},
dialog: isConfirmDialogOpen && {
type: 'confirm',
color: 'danger',
onCancel: onComplete,
onConfirm: () => {
discardChanges.execute()
onComplete()
},
message: <>Are you sure you want to discard all changes since last published?</>
}
onHandle: handle,
dialog
}
}
21 changes: 12 additions & 9 deletions packages/@sanity/desk-tool/src/actions/DuplicateAction.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react'
import uuid from '@sanity/uuid'
import {useDocumentOperation} from '@sanity/react-hooks'
import ContentCopyIcon from 'part:@sanity/base/content-copy-icon'
import {useRouter} from 'part:@sanity/base/router'
import uuid from '@sanity/uuid'
import React, {useCallback} from 'react'

const DISABLED_REASON_TITLE = {
NOTHING_TO_DUPLICATE: "This document doesn't yet exist so there's nothing to duplicate"
Expand All @@ -14,17 +14,20 @@ export function DuplicateAction({id, type, onComplete}) {

const [isDuplicating, setDuplicating] = React.useState(false)

const handle = useCallback(() => {
const dupeId = uuid()

setDuplicating(true)
duplicate.execute(dupeId)
router.navigateIntent('edit', {id: dupeId, type})
onComplete()
}, [duplicate, onComplete, router, type])

return {
icon: ContentCopyIcon,
disabled: Boolean(isDuplicating || duplicate.disabled),
label: isDuplicating ? 'Duplicating…' : 'Duplicate',
title: (duplicate.disabled && DISABLED_REASON_TITLE[duplicate.disabled]) || '',
onHandle: () => {
setDuplicating(true)
const dupeId = uuid()
duplicate.execute(dupeId)
router.navigateIntent('edit', {id: dupeId, type})
onComplete()
}
onHandle: handle
}
}
60 changes: 37 additions & 23 deletions packages/@sanity/desk-tool/src/actions/HistoryRestoreAction.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,53 @@
import React from 'react'
import {useDocumentOperation} from '@sanity/react-hooks'
import {useRouter} from 'part:@sanity/base/router'
import HistoryIcon from 'part:@sanity/base/history-icon'
import React, {useCallback, useMemo} from 'react'

export function HistoryRestoreAction({id, type, revision, onComplete}) {
const {restore}: any = useDocumentOperation(id, type)
const router = useRouter()
const [isConfirmDialogOpen, setConfirmDialogOpen] = React.useState(false)
const [error, setError] = React.useState<Error | null>(null)

const handleConfirm = useCallback(() => {
restore.execute(revision)
router.navigateIntent('edit', {id, type})
onComplete()
}, [revision, restore, router, onComplete, id, type])

const handle = useCallback(() => {
setConfirmDialogOpen(true)
}, [])

const dialog = useMemo(() => {
if (!error && isConfirmDialogOpen) {
return {
type: 'confirm',
color: 'danger',
onCancel: onComplete,
onConfirm: handleConfirm,
message: <>Are you sure you want to restore this document?</>
}
}

if (!error) {
return null
}

return {
type: 'error',
onClose: () => setError(null),
title: 'An error occured',
content: error.message
}
}, [error, handleConfirm, isConfirmDialogOpen, onComplete])

return {
label: 'Restore',
color: 'primary',
onHandle: () => {
setConfirmDialogOpen(true)
},
onHandle: handle,
title: 'Restore to this version',
icon: HistoryIcon,
dialog:
(!error &&
isConfirmDialogOpen && {
type: 'confirm',
color: 'danger',
onCancel: onComplete,
onConfirm: () => {
restore.execute(revision)
router.navigateIntent('edit', {id, type})
onComplete()
},
message: <>Are you sure you want to restore this document?</>
}) ||
(error && {
type: 'error',
onClose: () => setError(null),
title: 'An error occured',
content: error.message
})
dialog
}
}
56 changes: 31 additions & 25 deletions packages/@sanity/desk-tool/src/actions/PublishAction.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import {useSyncState, useDocumentOperation, useValidationStatus} from '@sanity/react-hooks'
import CheckmarkIcon from 'part:@sanity/base/check-icon'
import PublishIcon from 'part:@sanity/base/publish-icon'
import React, {useCallback, useEffect, useState} from 'react'
import TimeAgo from '../components/TimeAgo'
import {useDocumentHistory} from '../panes/documentPane/documentHistory'

Expand All @@ -25,18 +25,7 @@ function getDisabledReason(reason, publishedAt) {
// eslint-disable-next-line complexity
export function PublishAction(props) {
const {id, type, liveEdit, draft, published} = props

if (liveEdit) {
return {
label: 'Publish',
title:
'Live Edit is enabled for this content type and publishing happens automatically as you make changes',
disabled: true
}
}

const [publishState, setPublishState] = React.useState<'publishing' | 'published' | null>(null)

const [publishState, setPublishState] = useState<'publishing' | 'published' | null>(null)
const {publish}: any = useDocumentOperation(id, type)
const validationStatus = useValidationStatus(id, type)
const syncState = useSyncState(id)
Expand All @@ -45,30 +34,36 @@ export function PublishAction(props) {
const hasValidationErrors = validationStatus.markers.some(marker => marker.level === 'error')

// we use this to "schedule" publish after pending tasks (e.g. validation and sync) has completed
const [publishScheduled, setPublishScheduled] = React.useState<boolean>(false)
const [publishScheduled, setPublishScheduled] = useState<boolean>(false)

const doPublish = React.useCallback(() => {
const doPublish = useCallback(() => {
publish.execute()
setPublishState('publishing')
}, [publish, historyController])
}, [publish])

const isNeitherSyncingNorValidating = !syncState.isSyncing && !validationStatus.isValidating

React.useEffect(() => {
if (publishScheduled && !syncState.isSyncing && !validationStatus.isValidating) {
useEffect(() => {
if (publishScheduled && isNeitherSyncingNorValidating) {
if (!hasValidationErrors) {
doPublish()
}

setPublishScheduled(false)
}
}, [!syncState.isSyncing && !validationStatus.isValidating])
}, [isNeitherSyncingNorValidating, doPublish, hasValidationErrors, publishScheduled])

// eslint-disable-next-line no-nested-ternary
const title = publish.disabled
? getDisabledReason(publish.disabled, (published || {})._updatedAt) || ''
: hasValidationErrors
? 'There are validation errors that need to be fixed before this document can be published'
: ''

React.useEffect(() => {
const didPublish = publishState === 'publishing' && !draft
const hasDraft = Boolean(draft)

useEffect(() => {
const didPublish = publishState === 'publishing' && !hasDraft
if (didPublish) {
if (historyController.changesPanelActive()) {
// Re-open the panel
Expand All @@ -81,7 +76,7 @@ export function PublishAction(props) {
setPublishState(nextState)
}, delay)
return () => clearTimeout(timer)
}, [publishState, Boolean(draft)])
}, [publishState, hasDraft, historyController, historyOpen])

const disabled = Boolean(
publishScheduled ||
Expand All @@ -91,17 +86,27 @@ export function PublishAction(props) {
publish.disabled
)

const onHandle = React.useCallback(() => {
const handle = useCallback(() => {
if (syncState.isSyncing || validationStatus.isValidating) {
setPublishScheduled(true)
} else {
doPublish()
}
}, [syncState.isSyncing, validationStatus.isValidating])
}, [syncState.isSyncing, validationStatus.isValidating, doPublish])

if (liveEdit) {
return {
label: 'Publish',
title:
'Live Edit is enabled for this content type and publishing happens automatically as you make changes',
disabled: true
}
}

return {
disabled,
label:
// eslint-disable-next-line no-nested-ternary
publishState === 'published'
? 'Published'
: publishScheduled || publishState === 'publishing'
Expand All @@ -110,12 +115,13 @@ export function PublishAction(props) {
// @todo: Implement loading state, to show a `<Button loading />` state
// loading: publishScheduled || publishState === 'publishing',
icon: publishState === 'published' ? CheckmarkIcon : PublishIcon,
// eslint-disable-next-line no-nested-ternary
title: publishScheduled
? 'Waiting for tasks to finish before publishing'
: publishState === 'published' || publishState === 'publishing'
? null
: title,
shortcut: disabled || publishScheduled ? null : 'Ctrl+Alt+P',
onHandle: onHandle
onHandle: handle
}
}
11 changes: 7 additions & 4 deletions packages/@sanity/desk-tool/src/actions/SaveAction.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {useDocumentOperation} from '@sanity/react-hooks'
import {useCallback} from 'react'

export function SaveAction({id, type, onComplete}) {
const {commit}: any = useDocumentOperation(id, type)

const handle = useCallback(async () => {
await commit.execute()
onComplete()
}, [commit, onComplete])

return {
disabled: Boolean(commit.disabled),
label: 'Save',
onHandle: async () => {
await commit.execute()
onComplete()
}
onHandle: handle
}
}

0 comments on commit acc28f4

Please sign in to comment.