Open tomsseisums opened 3 years ago
+1 for this. In a similar-ish use case I've created a custom action to generate page slugs based on document data. I'm also using the intl-input plugin handle i18n data.
While they both work well on their own any custom publish action knocks out the intl-input publish actions code which a deal breaker for my app.
Expanding @tomsseisums great idea for a pre-publish action, some functionality to run multiple actions before publishing the doc would be a great help and prevent clashes between different plugins.
+1 on adding a prePublish
prop to PublishAction
! This would unlock some really powerful functionality to introduce time-saving features for editors. I am building a course platform in which Courses
have many referenced Lessons
, and each Lesson
document has a computed field which uses groq to pull the "parent" course into a read-only field. Right now I have a custom document action labeled Compile Lessons
which patches the referenced lessons to update that field, but I'd love to do it all in one go on document publish, including the nice UX affordances of the official PublishAction
.
A hook would be cool but if I could do something as simple as this, that would be great too:
// Default document actions
import defaultResolve, {
PublishAction,
} from 'part:@sanity/base/document-actions';
// Function which takes a document and patches all referenced lessons
import patchUpstreamLessons from './patchUpstreamLessons';
export default function resolveDocumentActions(props) {
return [
// Start with Sanity's default actions
...defaultResolve(props)
// Filter out actions by document type
.filter((action) => {
/// ...
return true;
})
.map((action) => {
// Override the PublishAction on courses to add a prePublish callback
if (props.type === 'course' && action === PublishAction) {
return <PublishAction prePublishAction={patchUpstreamLessons} />;
}
return action;
}),
// Add our own custom actions
shopifyLink,
];
}
+1 for this. I've ran in to same issues and thought why is it too complex, I was trying to auto-update slug and I have to redo a whole big document and that makes the UI buggy and I don't know how to fix those.
FWIW I think this opens up really interesting design opportunities for the Sanity team. Mainly I am thinking about computed field values across referenced documents, but being able to push to an external API, compute a field value on publish, etc sounds like the beginning of really cool workflow design capabilities.
Is your feature request related to a problem? Please describe. Somewhat related to this: https://github.com/sanity-io/sanity/issues/1932
For such a simple and, I think, frequent task of "updating a value on publish", the effort currently necessary to achieve it is crazy.
The "Update a value then publish", besides lacking as per #1932, also skips a lot of design nuances that have went into core Publish Action.
For a scenario, where all we actually want is to auto-update a value, our option now is to reimplement the whole implementation. That opens our extensions up to maintenance issues, as an update to Sanity core could change something that our extensions are not aware of.
All in all, I think the example displays a major oversight on your API design.
Describe the solution you'd like A simple addition of extension points would really provide for a much better DX!
One solution would be to provide an optional prop, i.e.
prePublish
, to Publish Action. That is then called beforepublish.execute
here: https://github.com/sanity-io/sanity/blob/2513e0eb112a5994feaba4dc6ac5322f2e865c25/packages/%40sanity/desk-tool/src/actions/PublishAction.tsx#L39-L42Like:
Providing us with a really easy to use extension point:
And add other frequent use & happy-path extension points for other Actions that could be extended.
This seems like a really elegant extension to your already curious use of Hooks for Document Actions.
One more thing that comes to mind is then to somehow cache studio hooks per component, because this usage will result in two
useDocumentOperation
calls and I don't know the performance implications of these yet.Describe alternatives you've considered Other option would be to refactor native actions to export factories, then, your default action could derive from it:
And our extensions too:
But this quickly becomes cumbersome, because the extension points have to provide dependencies. And in that scenario it becomes a game of prediction about what the extension developer would really need... As can be seen in the example, for instance, to get
patch
I don't have the option anymore to use studio hooks. (And let's not get started onprops.draft
orprops.published
which for illustration purposes already would become a hassle)Additional context I have already extended PublishAction as it is now, using the same idea. But the hoops I had to jump to provide a slightly tweaked
onHandle
! I ended up introducing a maaaaasssive boilerplate and code duplication (of core action) with it:Otherwise, I think the core idea, as it already is for Document Actions, is an ingenious use of React Hooks. 🤯 Did you find this pattern in the wild or came up with it for yourselves?