docs: completes version docs
This commit is contained in:
@@ -32,7 +32,7 @@ export default {
|
||||
|
||||
### Read
|
||||
|
||||
Returns a boolean result to allow or deny a user's ability to read the Global.
|
||||
Returns a boolean result or optionally a [query constraint](/docs/queries/overview) which limits who can read this global based on its current properties.
|
||||
|
||||
**Available argument properties:**
|
||||
|
||||
@@ -42,7 +42,7 @@ Returns a boolean result to allow or deny a user's ability to read the Global.
|
||||
|
||||
### Update
|
||||
|
||||
Returns a boolean result to allow or deny a user's ability to update the Global.
|
||||
Returns a boolean result or optionally a [query constraint](/docs/queries/overview) which limits who can update this global based on its current properties.
|
||||
|
||||
**Available argument properties:**
|
||||
|
||||
|
||||
@@ -6,12 +6,66 @@ desc: Using Payload's Draft functionality, you can configure your collections an
|
||||
keywords: version history, revisions, audit log, draft, publish, autosave, Content Management System, cms, headless, javascript, node, react, expresss
|
||||
---
|
||||
|
||||
Using Payload's Draft functionality, you can configure your collections and globals to autosave changes as drafts, and publish only you're ready. The Admin UI will automatically adapt to autosaving progress at an interval that you define, and will store all autosaved changes as a new Draft version. Never lose your work - and publish changes to the live document only when you're ready.
|
||||
Extending on Payload's [Draft](/docs/versions/drafts) functionality, you can configure your collections and globals to autosave changes as drafts, and publish only you're ready. The Admin UI will automatically adapt to autosaving progress at an interval that you define, and will store all autosaved changes as a new Draft version. Never lose your work - and publish changes to the live document only when you're ready.
|
||||
|
||||
<Banner type="warning">
|
||||
Autosave relies on Versions and Drafts being enabled in order to function.
|
||||
</Banner>
|
||||
|
||||
### TODO:
|
||||

|
||||
*If Autosave is enabled, drafts will be created automatically as the document is modified and the Admin UI adds an indicator describing when the document was last saved to the top right of the sidebar.*
|
||||
|
||||
Options and descriptions
|
||||
### Options
|
||||
|
||||
Collections and Globals both support the same options for configuring autosave. You can either set `versions.drafts.autosave` to `true`, or pass an object to configure autosave properties.
|
||||
|
||||
| Drafts Autosave Options | Description |
|
||||
| ---------------------------- | -------------|
|
||||
| `interval` | Define an `interval` in milliseconds to automatically save progress while documents are edited. Document updates are "debounced" at this interval. Defaults to `2000`. |
|
||||
|
||||
**Example config with versions, drafts, and autosave enabled:**
|
||||
|
||||
```js
|
||||
const Pages = {
|
||||
slug: 'pages',
|
||||
access: {
|
||||
read: ({ req }) => {
|
||||
// If there is a user logged in,
|
||||
// let them retrieve all documents
|
||||
if (req.user) return true;
|
||||
|
||||
// If there is no user,
|
||||
// restrict the documents that are returned
|
||||
// to only those where `_status` is equal to `published`
|
||||
return {
|
||||
_status: {
|
||||
equals: 'published',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
versions: {
|
||||
drafts: {
|
||||
autosave: true,
|
||||
|
||||
// Alternatively, you can specify an `interval`:
|
||||
// autosave: {
|
||||
// interval: 1500,
|
||||
// },
|
||||
}
|
||||
},
|
||||
//.. the rest of the Pages config here
|
||||
}
|
||||
```
|
||||
|
||||
### Autosave API
|
||||
|
||||
When `autosave` is enabled, all `update` operations within Payload expose a new argument called `autosave`. When set to `true`, Payload will treat the incoming draft update as an `autosave`. This is primarily used by the Admin UI, but there may be some cases where you are building an app for your users and wish to implement `autosave` in your own app. To do so, use the `autosave` argument in your `update` operations.
|
||||
|
||||
#### How autosaves are stored
|
||||
|
||||
If we created a new version for each autosave, you'd quickly find a ton of autosaves that clutter up your `_versions` collection within the database. That would be messy quick because `autosave` is typically set to save a document every ~2000ms or so.
|
||||
|
||||
<Banner type="success">
|
||||
Instead of creating a new version each time a document is autosaved, Payload smartly only creates <strong>one</strong> autosave version, and then updates that specific version with each autosave performed. This makes sure that your versions remain nice and tidy.
|
||||
</Banner>
|
||||
|
||||
@@ -12,13 +12,149 @@ Payload's Draft functionality builds on top of the Versions functionality to all
|
||||
Drafts rely on Versions being enabled in order to function.
|
||||
</Banner>
|
||||
|
||||
All Payload APIs will also expose [a new option](/docs/overview/versions/drafts#api) called `draft` which allows you to control if your document update(s) should be considered as draft or written straight to the published document.
|
||||
When you enable versions _and_ drafts, the Admin UI will update itself to include both "Save Draft" and "Publish Changes" buttons instead of a single "Save" button.
|
||||
By enabling Versions with Drafts, your collections and globals can maintain _newer_, and _unpublished_ versions of your documents. It's perfect for cases where you might want to work on a document, update it and save your progress, but not necessarily make it publicly published right away. Drafts are extremely helpful when building preview implementations.
|
||||
|
||||
### TODO:
|
||||

|
||||
*If Drafts are enabled, the typical Save button is replaced with new actions which allow you to either save a draft, or publish your changes.*
|
||||
|
||||
### Options
|
||||
|
||||
Collections and Globals both support the same options for configuring drafts. You can either set `versions.drafts` to `true`, or pass an object to configure draft properties.
|
||||
|
||||
| Draft Option | Description |
|
||||
| ---------------------------- | -------------|
|
||||
| `autosave` | Enable `autosave` to automatically save progress while documents are edited. To enable, set to `true` or pass an object with [options](/docs/versions/autosave). |
|
||||
|
||||
### Database changes
|
||||
|
||||
By enabling drafts on a collection or a global, Payload will <strong>automatically inject a new field into your schema</strong> called `_status`. The `_status` field is used internally by Payload to store if a document is set to `draft` or `published`.
|
||||
|
||||
**Admin UI status indication**
|
||||
|
||||
Within the Admin UI, if drafts are enabled, a document can be shown with one of three "statuses":
|
||||
|
||||
1. <strong>Draft</strong> - if a document has never been published, and only draft versions of the document are present
|
||||
1. <strong>Published</strong> - if a document is published and there are no newer drafts available
|
||||
1. <strong>Changed</strong> - if a document has been published, but there are newer drafts available and not yet published
|
||||
|
||||
### Draft API
|
||||
|
||||
<Banner type="success">
|
||||
If drafts are enabled on your collection or global, important and powerful changes are made to your REST, GraphQL, and Local APIs that allow you to specify if you are interacting with drafts or with live documents.
|
||||
</Banner>
|
||||
|
||||
##### Updating or creating drafts
|
||||
|
||||
If you enable drafts on a collection or global, the `create` and `update` operations for REST, GraphQL, and Local APIs expose a new option called `draft` which allows you to specify if you are creating or updating a <strong>draft</strong>, or if you're just sending your changes straight to the published document. For example, if you pass the query parameter `?draft=true` to a REST `create` or `update` operation, your action will be treated as if you are creating a `draft` and not a published document. By default, the `draft` argument is set to `false`.
|
||||
|
||||
**Required fields**
|
||||
|
||||
If `draft` is enabled while creating or updating a document, all fields are considered as not required, so that you can save drafts that are incomplete.
|
||||
|
||||
##### Reading drafts vs. published documents
|
||||
|
||||
In addition to the `draft` argument within `create` and `update` operations, a `draft` argument is also exposed for `find` and `findByID` operations.
|
||||
|
||||
If `draft` is set to `true` while reading a document, <strong>Payload will automatically replace returned document(s) with their newest drafts</strong> if any newer drafts are available.
|
||||
|
||||
<strong>For example, let's take the following scenario:</strong>
|
||||
|
||||
1. You create a new collection document and publish it right away
|
||||
1. You then make some updates, and save the updates as a draft
|
||||
1. You then make some further updates, and save more updates as another draft
|
||||
|
||||
Here, you will have a published document that resides in your main collection, and then you'll have two _newer_ drafts that reside in the `_[collectionSlug]_versions` database collection.
|
||||
|
||||
If you simply fetch your created document using a `find` or `findByID` operation, your published document will be returned and the drafts will be ignored.
|
||||
|
||||
But, if you specify `draft` as `true`, Payload will automatically replace your published document's content with content coming from the most recently saved `version`. In this case, as we have created _two_ versions in the above scenario, Payload will send back data from the newest (second) draft and your document will appear as the most recently drafted version instead of the published version.
|
||||
|
||||
### Controlling who can see Collection drafts
|
||||
|
||||
<Banner type="warning">
|
||||
If you're using the <strong>drafts</strong> feature, it's important for you to consider who can view your drafts, and who can view only published documents. Luckily, Payload makes this extremely simple and puts the power completely in your hands.
|
||||
</Banner>
|
||||
|
||||
##### Restricting draft access
|
||||
|
||||
You can use the `read` [Access Control](/docs/access-control/collections#read) method to restrict who is able to view drafts of your documents by simply returning a [query constraint](/docs/queries/overview) which restricts the documents that any given user is able to retrieve.
|
||||
|
||||
Here is an example that utilizes the `_status` field to require a user to be logged in to retrieve drafts:
|
||||
|
||||
```js
|
||||
const Pages = {
|
||||
slug: 'pages',
|
||||
access: {
|
||||
read: ({ req }) => {
|
||||
// If there is a user logged in,
|
||||
// let them retrieve all documents
|
||||
if (req.user) return true;
|
||||
|
||||
// If there is no user,
|
||||
// restrict the documents that are returned
|
||||
// to only those where `_status` is equal to `published`
|
||||
return {
|
||||
_status: {
|
||||
equals: 'published',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
versions: {
|
||||
drafts: true
|
||||
},
|
||||
//.. the rest of the Pages config here
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note regarding adding versions to an existing collection</strong><br/>
|
||||
If you already have a collection with documents, and you <em>opt in</em> to draft functionality after you have already created existing documents, all of your old documents <em>will not have a _status field</em> until you resave them. For this reason, if you are <em>adding</em> versions into an existing collection, you might want to write your access control function to allow for users to read both documents where <strong>_status is equal to "published"</strong> as well as where <strong>_status does not exist</strong>.
|
||||
</Banner>
|
||||
|
||||
Here is an example for how to write an access control function that grants access to both documents where `_status` is equal to "published" and where `_status` does not exist:
|
||||
|
||||
```js
|
||||
const Pages = {
|
||||
slug: 'pages',
|
||||
access: {
|
||||
read: ({ req }) => {
|
||||
// If there is a user logged in,
|
||||
// let them retrieve all documents
|
||||
if (req.user) return true;
|
||||
|
||||
// If there is no user,
|
||||
// restrict the documents that are returned
|
||||
// to only those where `_status` is equal to `published`
|
||||
// or where `_status` does not exist
|
||||
return {
|
||||
or: [
|
||||
{
|
||||
_status: {
|
||||
equals: 'published',
|
||||
},
|
||||
},
|
||||
{
|
||||
_status: {
|
||||
exists: false,
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
},
|
||||
versions: {
|
||||
drafts: true
|
||||
},
|
||||
//.. the rest of the Pages config here
|
||||
}
|
||||
```
|
||||
|
||||
### Unpublishing drafts
|
||||
|
||||
If a document is published, the Payload Admin UI will be updated to show an "unpublish" button at the top of the sidebar, which will "unpublish" the currently published document. Consider this as a way to "revert" a document back to a draft state. On the API side, this is done by simply setting `_status: 'draft'` on any document.
|
||||
|
||||
### Reverting to published
|
||||
|
||||
If a document is published, and you have made further changes which are saved as a draft, Payload will show a "revert to published" button at the top of the sidebar which will allow you to reject your draft changes and "revert" back to the published state of the document. Your drafts will still be saved, but a new version will be created that will reflect the last published state of the document.
|
||||
|
||||
- Options
|
||||
- need header for `#api`
|
||||
- access control example to describe how to limit people from viewing drafts
|
||||
- talk about ?draft=true, how you can deliberately ask for newer drafts for docs and they will be sent back accordingly automatically
|
||||
- talk about how Global `read` access control accepts an additional argument for `draft` which is a boolean and you can use it to prevent / allow reading globals if they are drafts
|
||||
|
||||
@@ -7,7 +7,7 @@ keywords: version history, revisions, audit log, draft, publish, autosave, Conte
|
||||
---
|
||||
|
||||
<Banner>
|
||||
Payload's powerful Versions functionality allows you to keep a running history of changes over time. Versions are available as of Payload <strong>0.15.0</strong>.
|
||||
Payload's powerful Versions functionality allows you to keep a running history of changes over time. Versions are available as of <strong>payload@0.14.23-beta.0</strong>.
|
||||
</Banner>
|
||||
|
||||
When enabled, Payload will automatically scaffold a new Collection in your database to store versions of your document(s) over time, and the Admin UI will be extended with additional views that allow you to browse document versions, view diffs in order to see exactly what has changed in your documents (and when they changed), and restore documents back to prior versions easily.
|
||||
@@ -42,14 +42,11 @@ For example, a use case for "versions enabled, drafts disabled" could be on a co
|
||||
|
||||
If you have versions _and_ drafts enabled, you are able to control which documents are published, and which are considered draft. That lets you write [access control](/docs/access-control/overview) to control who can see published documents, and who can see draft documents. It also lets you save versions (drafts) that are _newer_ than your most recently published document, which is helpful if you want to draft changes and maybe even preview them before you publish the changes. Read more about Drafts [here](/docs/versions/drafts).
|
||||
|
||||

|
||||
*If Drafts are enabled, a new button appears while editing documents*
|
||||
|
||||
##### Versions, drafts, and autosave enabled
|
||||
|
||||
When you have versions, drafts, _and_ `autosave` enabled, the Admin UI will automatically save changes that you make to a new `draft` version as you edit a document, which makes sure that you never lose your changes ever again. Autosave will not affect your published post at all—instead, it'll just save your changes and let you publish them whenever you or your editors are ready to do so. Read more about Autosave [here](/docs/versions/autosave).
|
||||
|
||||
#### Collection Config
|
||||
#### Collection config
|
||||
|
||||
Configuring Versions is done by adding the `versions` key to your Collection configs. Set it to `true` to enable default Versions settings, or customize versions options by setting the property equal to an object containing the following available options:
|
||||
|
||||
@@ -57,19 +54,46 @@ Configuring Versions is done by adding the `versions` key to your Collection con
|
||||
| ---------------------------- | -------------|
|
||||
| `maxPerDoc` | Use this setting to control how many versions to keep on a document by document basis. Must be an integer. |
|
||||
| `retainDeleted` | Boolean to determine if, when a document is deleted, you'd like to retain versions of that document, or go through and automatically delete all versions that are associated with the deleted document. |
|
||||
| `drafts ` | Enable [Drafts](/docs/versions/drafts) mode for this collection. |
|
||||
| `drafts ` | Enable [Drafts](/docs/versions/drafts) mode for this collection. To enable, set to `true` or pass an object with `draft` [options](/docs/versions/drafts#options). |
|
||||
|
||||
|
||||
#### Global Config
|
||||
#### Global config
|
||||
|
||||
Global versions work similarly to Collection versions but have a slightly different set of config properties supported.
|
||||
|
||||
| Option | Description |
|
||||
| --------- | -------------|
|
||||
| `max` | Use this setting to control how many versions to keep on a global by global basis. Must be an integer. |
|
||||
| `drafts` | Enable [Drafts](/docs/versions/drafts) mode for this global. |
|
||||
| `drafts` | Enable [Drafts](/docs/versions/drafts) mode for this global. To enable, set to `true` or pass an object with `draft` [options](/docs/versions/drafts#options) |
|
||||
|
||||
### Version Operations
|
||||
|
||||
#### Database impact
|
||||
|
||||
By enabling `versions`, a new MongoDB collection will be made to store versions for your collection or global. The collection will be named based off the `slug` of the collection or global and will follow this pattern (where `slug` is replaced with the `slug` of your collection or global):
|
||||
|
||||
```
|
||||
_slug_versions
|
||||
```
|
||||
|
||||
Each document in this new `versions` collection will store a set of meta properties about the version as well as a _full_ copy of the document. For example, a version's data might look like this for a Collection document:
|
||||
|
||||
```js
|
||||
{
|
||||
"_id": "61cf752c19cdf1b1af7b61f1", // a unique ID of this version
|
||||
"parent": "61ce1354091d5b3ffc20ea6e", // the ID of the parent document
|
||||
"autosave": false, // used to denote if this version was created via autosave
|
||||
"version": {
|
||||
// your document's data goes here
|
||||
// all fields are set to not required and this property can be partially complete
|
||||
},
|
||||
"createdAt": "2021-12-31T21:25:00.992+00:00",
|
||||
"updatedAt": "2021-12-31T21:25:00.992+00:00"
|
||||
}
|
||||
```
|
||||
|
||||
Global versions are stored the same as the collection version shown above, except they do not feature the `parent` property, as each Global receives its own `versions` collection. That means we know that all versions in that collection correspond to that specific global.
|
||||
|
||||
### Version operations
|
||||
|
||||
Versions expose new operations for both collections and globals. They allow you to find and query versions, find a single version by ID, and publish (or restore) a version by ID. Both Collections and Globals support the same new operations. They are used primarily by the admin UI, but if you are writing custom logic in your app and would like to utilize them, they're available for you to use as well via REST, GraphQL, and Local APIs.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user