Skip to content

Commit 02800b0

Browse files
authored
chore: export fractional indexing utilities (#15286)
Exports the fractional indexing utilities and also reorders the docs so that we mostly link to our docs on the topic and from there only link out once to the article.
1 parent 18ca83b commit 02800b0

File tree

5 files changed

+64
-30
lines changed

5 files changed

+64
-30
lines changed

docs/configuration/collections.mdx

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,33 @@ export const Posts: CollectionConfig = {
6060

6161
The following options are available:
6262

63-
| Option | Description |
64-
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65-
| `admin` | The configuration options for the Admin Panel. [More details](#admin-options). |
66-
| `access` | Provide Access Control functions to define exactly who should be able to do what with Documents in this Collection. [More details](../access-control/collections). |
67-
| `auth` | Specify options if you would like this Collection to feature authentication. [More details](../authentication/overview). |
68-
| `custom` | Extension point for adding custom data (e.g. for plugins) |
69-
| `disableDuplicate` | When true, do not show the "Duplicate" button while editing documents within this Collection and prevent `duplicate` from all APIs. |
70-
| `defaultSort` | Pass a top-level field to sort by default in the Collection List View. Prefix the name of the field with a minus symbol ("-") to sort in descending order. Multiple fields can be specified by using a string array. |
71-
| `dbName` | Custom table or Collection name depending on the Database Adapter. Auto-generated from slug if not defined. |
72-
| `endpoints` | Add custom routes to the REST API. Set to `false` to disable routes. [More details](../rest-api/overview#custom-endpoints). |
73-
| `fields` \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [More details](../fields/overview). |
74-
| `graphQL` | Manage GraphQL-related properties for this collection. [More](#graphql) |
75-
| `hooks` | Entry point for Hooks. [More details](../hooks/overview#collection-hooks). |
76-
| `orderable` | If true, enables custom ordering for the collection, and documents can be reordered via drag and drop. Uses [fractional indexing](https://observablehq.com/@dgreensp/implementing-fractional-indexing) for efficient reordering. |
77-
| `labels` | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
78-
| `enableQueryPresets` | Enable query presets for this Collection. [More details](../query-presets/overview). |
79-
| `lockDocuments` | Enables or disables document locking. By default, document locking is enabled. Set to an object to configure, or set to `false` to disable locking. [More details](../admin/locked-documents). |
80-
| `slug` \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
81-
| `timestamps` | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
82-
| `trash` | A boolean to enable soft deletes for this collection. Defaults to `false`. [More details](../trash/overview). |
83-
| `typescript` | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
84-
| `upload` | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](../upload/overview) documentation. |
85-
| `versions` | Set to true to enable default options, or configure with object properties. [More details](../versions/overview#collection-config). |
86-
| `defaultPopulate` | Specify which fields to select when this Collection is populated from another document. [More Details](../queries/select#defaultpopulate-collection-config-property). |
87-
| `indexes` | Define compound indexes for this collection. This can be used to either speed up querying/sorting by 2 or more fields at the same time or to ensure uniqueness between several fields. |
88-
| `forceSelect` | Specify which fields should be selected always, regardless of the `select` query which can be useful that the field exists for access control / hooks. [More details](../queries/select). |
89-
| `disableBulkEdit` | Disable the bulk edit operation for the collection in the admin panel and the REST API |
63+
| Option | Description |
64+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65+
| `admin` | The configuration options for the Admin Panel. [More details](#admin-options). |
66+
| `access` | Provide Access Control functions to define exactly who should be able to do what with Documents in this Collection. [More details](../access-control/collections). |
67+
| `auth` | Specify options if you would like this Collection to feature authentication. [More details](../authentication/overview). |
68+
| `custom` | Extension point for adding custom data (e.g. for plugins) |
69+
| `disableDuplicate` | When true, do not show the "Duplicate" button while editing documents within this Collection and prevent `duplicate` from all APIs. |
70+
| `defaultSort` | Pass a top-level field to sort by default in the Collection List View. Prefix the name of the field with a minus symbol ("-") to sort in descending order. Multiple fields can be specified by using a string array. |
71+
| `dbName` | Custom table or Collection name depending on the Database Adapter. Auto-generated from slug if not defined. |
72+
| `endpoints` | Add custom routes to the REST API. Set to `false` to disable routes. [More details](../rest-api/overview#custom-endpoints). |
73+
| `fields` \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [More details](../fields/overview). |
74+
| `graphQL` | Manage GraphQL-related properties for this collection. [More](#graphql) |
75+
| `hooks` | Entry point for Hooks. [More details](../hooks/overview#collection-hooks). |
76+
| `orderable` | If true, enables custom ordering for the collection, and documents can be reordered via drag and drop. Uses [orderable](#orderable) for efficient reordering. |
77+
| `labels` | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
78+
| `enableQueryPresets` | Enable query presets for this Collection. [More details](../query-presets/overview). |
79+
| `lockDocuments` | Enables or disables document locking. By default, document locking is enabled. Set to an object to configure, or set to `false` to disable locking. [More details](../admin/locked-documents). |
80+
| `slug` \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
81+
| `timestamps` | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
82+
| `trash` | A boolean to enable soft deletes for this collection. Defaults to `false`. [More details](../trash/overview). |
83+
| `typescript` | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
84+
| `upload` | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](../upload/overview) documentation. |
85+
| `versions` | Set to true to enable default options, or configure with object properties. [More details](../versions/overview#collection-config). |
86+
| `defaultPopulate` | Specify which fields to select when this Collection is populated from another document. [More Details](../queries/select#defaultpopulate-collection-config-property). |
87+
| `indexes` | Define compound indexes for this collection. This can be used to either speed up querying/sorting by 2 or more fields at the same time or to ensure uniqueness between several fields. |
88+
| `forceSelect` | Specify which fields should be selected always, regardless of the `select` query which can be useful that the field exists for access control / hooks. [More details](../queries/select). |
89+
| `disableBulkEdit` | Disable the bulk edit operation for the collection in the admin panel and the REST API |
9090

9191
_\* An asterisk denotes that a property is required._
9292

@@ -102,6 +102,34 @@ Fields define the schema of the Documents within a Collection. To learn more, go
102102

103103
[Collection Hooks](../hooks/collections) allow you to tie into the lifecycle of your Documents so you can execute your own logic during specific events. To learn more, go to the [Hooks](../hooks/overview) documentation.
104104

105+
### Orderable
106+
107+
When `orderable` is enabled, Payload uses [fractional indexing](https://observablehq.com/@dgreensp/implementing-fractional-indexing) to efficiently manage document order. When enabled on collections, this allows you to manually drag and drop documents in the Admin Panel to reorder them, as well as programmatically set the order of documents via the Local API, REST API, or GraphQL API.
108+
109+
Orderable can also be added to [joins fields](../fields/join).
110+
111+
#### Fractional indexing
112+
113+
If you need to generate order keys programmatically (e.g., when creating documents via the Local API with a specific order), you can import the utilities directly:
114+
115+
```ts
116+
import { generateKeyBetween, generateNKeysBetween } from 'payload/shared'
117+
118+
// Generate a key between two existing keys (or null for start/end)
119+
const newKey = generateKeyBetween('a0', 'a1')
120+
121+
// Generate a key at the start (before 'a0')
122+
const startKey = generateKeyBetween(null, 'a0')
123+
124+
// Generate a key at the end (after 'a1')
125+
const endKey = generateKeyBetween('a1', null)
126+
127+
// Generate multiple keys between two existing keys
128+
const keys = generateNKeysBetween('a0', 'a1', 5)
129+
```
130+
131+
These utilities are useful when you need fine-grained control over document ordering, such as inserting documents at specific positions or batch-creating documents with predetermined order.
132+
105133
## Admin Options
106134

107135
The behavior of Collections within the [Admin Panel](../admin/overview) can be fully customized to fit the needs of your application. This includes grouping or hiding their navigation links, adding [Custom Components](../custom-components/overview), selecting which fields to display in the List View, and more.

docs/fields/join.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ powerful Admin UI.
138138
| **`name`** \* | To be used as the property name when retrieved from the database. [More details](./overview#field-names). |
139139
| **`collection`** \* | The `slug`s having the relationship field or an array of collection slugs. |
140140
| **`on`** \* | The name of the relationship or upload field that relates to the collection document. Use dot notation for nested paths, like 'myGroup.relationName'. If `collection` is an array, this field must exist for all specified collections |
141-
| **`orderable`** | If true, enables custom ordering and joined documents can be reordered via drag and drop. Uses [fractional indexing](https://observablehq.com/@dgreensp/implementing-fractional-indexing) for efficient reordering. |
141+
| **`orderable`** | If true, enables custom ordering and joined documents can be reordered via drag and drop. Uses [fractional indexing](../configuration/collections#fractional-indexing) for efficient reordering. |
142142
| **`where`** | A `Where` query to hide related documents from appearing. Will be merged with any `where` specified in the request. |
143143
| **`maxDepth`** | Default is 1, Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached. [Max Depth](../queries/depth#max-depth). |
144144
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |

packages/payload/src/collections/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ export type CollectionConfig<TSlug extends CollectionSlug = any> = {
640640
* If true, enables custom ordering for the collection, and documents in the listView can be reordered via drag and drop.
641641
* New documents are inserted at the end of the list according to this parameter.
642642
*
643-
* Under the hood, a field with {@link https://observablehq.com/@dgreensp/implementing-fractional-indexing|fractional indexing} is used to optimize inserts and reorderings.
643+
* Under the hood, a field with {@link https://payloadcms.com/docs/configuration/collections#fractional-indexing|fractional indexing} is used to optimize inserts and reorderings.
644644
*
645645
* @default false
646646
*

packages/payload/src/exports/shared.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ export {
55
getCookieExpiration,
66
parseCookies,
77
} from '../auth/cookies.js'
8+
89
export { getLoginOptions } from '../auth/getLoginOptions.js'
910
export { addSessionToUser, removeExpiredSessions } from '../auth/sessions.js'
1011
export { getFromImportMap } from '../bin/generateImportMap/utilities/getFromImportMap.js'
1112
export { parsePayloadComponent } from '../bin/generateImportMap/utilities/parsePayloadComponent.js'
1213
export { defaults as collectionDefaults } from '../collections/config/defaults.js'
14+
export {
15+
BASE_36_DIGITS,
16+
generateKeyBetween,
17+
generateNKeysBetween,
18+
} from '../config/orderable/fractional-indexing.js'
1319

1420
export { serverProps } from '../config/types.js'
1521

packages/payload/src/fields/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@ export type JoinField = {
17181718
* If true, enables custom ordering for the collection with the relationship, and joined documents can be reordered via drag and drop.
17191719
* New documents are inserted at the end of the list according to this parameter.
17201720
*
1721-
* Under the hood, a field with {@link https://observablehq.com/@dgreensp/implementing-fractional-indexing|fractional indexing} is used to optimize inserts and reorderings.
1721+
* Under the hood, a field with {@link https://payloadcms.com/docs/configuration/collections#fractional-indexing|fractional indexing} is used to optimize inserts and reorderings.
17221722
*
17231723
* @default false
17241724
*

0 commit comments

Comments
 (0)