Skip to content

Commit

Permalink
feat(core): adopt Actions API (#6257)
Browse files Browse the repository at this point in the history
* test(structure): add document title test id

* test(structure): document panel displays correct title for published document

* feat(sanity): use actions API when publishing documents

* feat(sanity): use Actions API when unpublishing documents (#6094)

* feat(sanity): use Actions API when unpublishing documents

* feat(core): set `skipCrossDatasetReferenceValidation` parameter when unpublishing documents

* feat(sanity): use actions API when deleting documents (#6115)

* feat(sanity): use actions API when deleting documents
* fix(sanity): add skipCrossDatasetReferenceValidation to delete action

---------

Co-authored-by: Bjørge Næss <bjoerge@gmail.com>
  • Loading branch information
juice49 and bjoerge committed Apr 9, 2024
1 parent 346600c commit 4d45224
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 1 deletion.
Expand Up @@ -32,7 +32,10 @@ import {patch} from './operations/patch'
import {publish} from './operations/publish'
import {restore} from './operations/restore'
import {unpublish} from './operations/unpublish'
import {del as serverDel} from './serverOperations/delete'
import {patch as serverPatch} from './serverOperations/patch'
import {publish as serverPublish} from './serverOperations/publish'
import {unpublish as serverUnpublish} from './serverOperations/unpublish'

interface ExecuteArgs {
operationName: keyof OperationsAPI
Expand Down Expand Up @@ -60,7 +63,11 @@ const operationImpls = {
//as we add server operations one by one, we can add them here
const serverOperationImpls = {
...operationImpls,
del: serverDel,
delete: serverDel,
patch: serverPatch,
publish: serverPublish,
unpublish: serverUnpublish,
}

const execute = (
Expand Down
@@ -1,7 +1,10 @@
import {type IdPair} from '../../types'
import {emitOperation} from '../operationEvents'
import {publish} from '../operations/publish'
import {del as serverDel} from '../serverOperations/delete'
import {patch as serverPatch} from '../serverOperations/patch'
import {publish as serverPublish} from '../serverOperations/publish'
import {unpublish as serverUnpublish} from '../serverOperations/unpublish'
import {commit} from './commit'
import {del} from './delete'
import {discardChanges} from './discardChanges'
Expand Down Expand Up @@ -68,7 +71,11 @@ export function createOperationsAPI(args: OperationArgs): OperationsAPI {
if (args.serverActionsEnabled) {
return {
...operationsAPI,
delete: wrap('delete', serverDel, args),
del: wrap('delete', serverDel, args),
patch: wrap('patch', serverPatch, args),
publish: wrap('publish', serverPublish, args),
unpublish: wrap('unpublish', serverUnpublish, args),
}
}
return operationsAPI
Expand Down
@@ -0,0 +1,29 @@
import {type OperationImpl} from '../operations/types'

export const del: OperationImpl<[], 'NOTHING_TO_DELETE'> = {
disabled: ({snapshots}) => (snapshots.draft || snapshots.published ? false : 'NOTHING_TO_DELETE'),
execute: ({client: globalClient, schema, idPair, typeName}) => {
const vXClient = globalClient.withConfig({apiVersion: 'X'})

const {dataset} = globalClient.config()

return vXClient.observable.request({
url: `/data/actions/${dataset}`,
method: 'post',
tag: 'document.delete',
// this disables referential integrity for cross-dataset references. we
// have this set because we warn against deletes in the `ConfirmDeleteDialog`
// UI. This operation is run when "delete anyway" is clicked
query: {skipCrossDatasetReferenceValidation: 'true'},
body: {
actions: [
{
actionType: 'sanity.action.document.delete',
draftId: idPair.draftId,
publishedId: idPair.publishedId,
},
],
},
})
},
}
@@ -0,0 +1,35 @@
import {type OperationImpl} from '../operations/index'
import {isLiveEditEnabled} from '../utils/isLiveEditEnabled'

type DisabledReason = 'LIVE_EDIT_ENABLED' | 'ALREADY_PUBLISHED' | 'NO_CHANGES'

export const publish: OperationImpl<[], DisabledReason> = {
disabled: ({schema, typeName, snapshots}) => {
if (isLiveEditEnabled(schema, typeName)) {
return 'LIVE_EDIT_ENABLED'
}
if (!snapshots.draft) {
return snapshots.published ? 'ALREADY_PUBLISHED' : 'NO_CHANGES'
}
return false
},
execute: ({client: globalClient, idPair}) => {
const vXClient = globalClient.withConfig({apiVersion: 'X'})
const {dataset} = globalClient.config()

return vXClient.observable.request({
url: `/data/actions/${dataset}`,
method: 'post',
tag: 'document.publish',
body: {
actions: [
{
actionType: 'sanity.action.document.publish',
draftId: idPair.draftId,
publishedId: idPair.publishedId,
},
],
},
})
},
}
@@ -0,0 +1,36 @@
import {type OperationImpl} from '../operations/types'
import {isLiveEditEnabled} from '../utils/isLiveEditEnabled'

type DisabledReason = 'LIVE_EDIT_ENABLED' | 'NOT_PUBLISHED'

export const unpublish: OperationImpl<[], DisabledReason> = {
disabled: ({schema, snapshots, typeName}) => {
if (isLiveEditEnabled(schema, typeName)) {
return 'LIVE_EDIT_ENABLED'
}
return snapshots.published ? false : 'NOT_PUBLISHED'
},
execute: ({client: globalClient, idPair}) => {
const vXClient = globalClient.withConfig({apiVersion: 'X'})
const {dataset} = globalClient.config()

return vXClient.observable.request({
url: `/data/actions/${dataset}`,
method: 'post',
// this disables referential integrity for cross-dataset references. we
// have this set because we warn against unpublishes in the `ConfirmDeleteDialog`
// UI. This operation is run when "unpublish anyway" is clicked
query: {skipCrossDatasetReferenceValidation: 'true'},
tag: 'document.unpublish',
body: {
actions: [
{
actionType: 'sanity.action.document.unpublish',
draftId: idPair.draftId,
publishedId: idPair.publishedId,
},
],
},
})
},
}
Expand Up @@ -75,7 +75,7 @@ export const FormHeader = ({documentId, schemaType, title}: DocumentHeaderProps)
</Text>
)}

<Heading as="h2" data-heading muted={!title}>
<Heading as="h2" data-heading muted={!title} data-testid="document-panel-document-title">
{title ?? t('document-view.form-view.form-title-fallback')}
</Heading>
</TitleContainer>
Expand Down
22 changes: 22 additions & 0 deletions test/e2e/tests/document-actions/publish.spec.ts
@@ -0,0 +1,22 @@
import {expect} from '@playwright/test'
import {test} from '@sanity/test'

test(`document panel displays correct title for published document`, async ({
page,
createDraftDocument,
}) => {
const title = 'Test Title'

await createDraftDocument('/test/content/book')
await page.getByTestId('field-title').getByTestId('string-input').fill(title)

// Ensure the correct title is displayed before publishing.
await expect(page.getByTestId('document-panel-document-title')).toHaveText(title)

// Wait for the document to be published.
page.getByTestId('action-Publish').click()
await expect(page.getByText('Published just now')).toBeVisible()

// Ensure the correct title is displayed after publishing.
expect(page.getByTestId('document-panel-document-title')).toHaveText(title)
})

0 comments on commit 4d45224

Please sign in to comment.