@sanity/orderable-document-list 0.0.8 → 1.0.0-v3-studio.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +142 -48
  3. package/lib/index.d.ts +38 -0
  4. package/lib/index.d.ts.map +1 -0
  5. package/lib/index.js +849 -30
  6. package/lib/index.js.map +1 -1
  7. package/lib/index.modern.js +840 -0
  8. package/lib/index.modern.js.map +1 -0
  9. package/package.json +56 -22
  10. package/src/{Document.js → Document.tsx} +30 -27
  11. package/src/{DocumentListQuery.js → DocumentListQuery.tsx} +29 -18
  12. package/src/{DocumentListWrapper.js → DocumentListWrapper.tsx} +29 -21
  13. package/src/DraggableList.tsx +304 -0
  14. package/src/{Feedback.js → Feedback.tsx} +2 -7
  15. package/src/OrderableContext.ts +7 -0
  16. package/src/{OrderableDocumentList.js → OrderableDocumentList.tsx} +25 -10
  17. package/src/desk-structure/globalClientWorkaround.ts +33 -0
  18. package/src/desk-structure/{orderableDocumentListDeskItem.js → orderableDocumentListDeskItem.ts} +27 -11
  19. package/src/fields/orderRankField.ts +45 -0
  20. package/src/fields/{orderRankOrdering.js → orderRankOrdering.ts} +0 -0
  21. package/src/helpers/client.ts +13 -0
  22. package/src/helpers/constants.ts +1 -0
  23. package/src/helpers/{initialRank.js → initialRank.ts} +2 -2
  24. package/src/helpers/{reorderDocuments.js → reorderDocuments.ts} +33 -44
  25. package/src/helpers/{resetOrder.js → resetOrder.ts} +3 -8
  26. package/src/index.ts +9 -0
  27. package/.babelrc +0 -3
  28. package/.eslintignore +0 -1
  29. package/.eslintrc.js +0 -50
  30. package/lib/Document.js +0 -101
  31. package/lib/Document.js.map +0 -1
  32. package/lib/DocumentListQuery.js +0 -155
  33. package/lib/DocumentListQuery.js.map +0 -1
  34. package/lib/DocumentListWrapper.js +0 -97
  35. package/lib/DocumentListWrapper.js.map +0 -1
  36. package/lib/DraggableList.js +0 -314
  37. package/lib/DraggableList.js.map +0 -1
  38. package/lib/Feedback.js +0 -31
  39. package/lib/Feedback.js.map +0 -1
  40. package/lib/OrderableContext.js +0 -15
  41. package/lib/OrderableContext.js.map +0 -1
  42. package/lib/OrderableDocumentList.js +0 -99
  43. package/lib/OrderableDocumentList.js.map +0 -1
  44. package/lib/desk-structure/orderableDocumentListDeskItem.js +0 -52
  45. package/lib/desk-structure/orderableDocumentListDeskItem.js.map +0 -1
  46. package/lib/fields/orderRankField.js +0 -64
  47. package/lib/fields/orderRankField.js.map +0 -1
  48. package/lib/fields/orderRankOrdering.js +0 -19
  49. package/lib/fields/orderRankOrdering.js.map +0 -1
  50. package/lib/helpers/constants.js +0 -9
  51. package/lib/helpers/constants.js.map +0 -1
  52. package/lib/helpers/initialRank.js +0 -18
  53. package/lib/helpers/initialRank.js.map +0 -1
  54. package/lib/helpers/reorderDocuments.js +0 -133
  55. package/lib/helpers/reorderDocuments.js.map +0 -1
  56. package/lib/helpers/resetOrder.js +0 -62
  57. package/lib/helpers/resetOrder.js.map +0 -1
  58. package/sanity.json +0 -7
  59. package/src/DraggableList.js +0 -276
  60. package/src/OrderableContext.js +0 -3
  61. package/src/fields/orderRankField.js +0 -35
  62. package/src/helpers/constants.js +0 -1
  63. package/src/index.js +0 -5
@@ -0,0 +1,304 @@
1
+ import React, {useEffect, useState, useMemo, useCallback, CSSProperties} from 'react'
2
+ import {DragDropContext, Draggable, Droppable, type DropResult} from 'react-beautiful-dnd'
3
+ import {Box, Card, useToast} from '@sanity/ui'
4
+ import {usePaneRouter} from 'sanity/desk'
5
+ import type {SanityDocument, PatchOperations} from 'sanity'
6
+ import Document from './Document'
7
+ import {reorderDocuments} from './helpers/reorderDocuments'
8
+ import {ORDER_FIELD_NAME} from './helpers/constants'
9
+ import {useSanityClient} from './helpers/client'
10
+
11
+ const getItemStyle = (
12
+ draggableStyle: CSSProperties | undefined,
13
+ itemIsUpdating: boolean
14
+ ): CSSProperties => ({
15
+ userSelect: 'none',
16
+ transition: `opacity 500ms ease-in-out`,
17
+ opacity: itemIsUpdating ? 0.2 : 1,
18
+ pointerEvents: itemIsUpdating ? `none` : undefined,
19
+ ...draggableStyle,
20
+ })
21
+
22
+ const cardTone = (settings: ListSetting) => {
23
+ const {isDuplicate, isGhosting, isDragging, isSelected} = settings
24
+
25
+ if (isGhosting) return `transparent`
26
+ if (isDragging || isSelected) return `primary`
27
+ if (isDuplicate) return `caution`
28
+
29
+ return undefined
30
+ }
31
+
32
+ interface ListSetting {
33
+ isDuplicate: boolean
34
+ isGhosting: boolean
35
+ isDragging: boolean
36
+ isSelected: boolean
37
+ }
38
+
39
+ export interface DraggableListProps {
40
+ data: SanityDocument[]
41
+ type: string
42
+ listIsUpdating: boolean
43
+ setListIsUpdating: (val: boolean) => void
44
+ }
45
+
46
+ export default function DraggableList({
47
+ data,
48
+ type,
49
+ listIsUpdating,
50
+ setListIsUpdating,
51
+ }: DraggableListProps) {
52
+ const toast = useToast()
53
+ const router = usePaneRouter()
54
+ const {navigateIntent} = router
55
+
56
+ // Maintains local state order before transaction completes
57
+ const [orderedData, setOrderedData] = useState<SanityDocument[]>(data)
58
+
59
+ // Update local state when documents change from an outside source
60
+ useEffect(() => {
61
+ if (!listIsUpdating) setOrderedData(data)
62
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */
63
+ }, [data])
64
+
65
+ const [draggingId, setDraggingId] = useState(``)
66
+ const [selectedIds, setSelectedIds] = useState<string[]>([])
67
+
68
+ const clearSelected = useCallback(() => setSelectedIds([]), [setSelectedIds])
69
+
70
+ const handleSelect = useCallback(
71
+ (clickedId: string, index: number, nativeEvent: MouseEvent) => {
72
+ const isSelected = selectedIds.includes(clickedId)
73
+ const selectMultiple = nativeEvent.shiftKey
74
+ const isUsingWindows = navigator.appVersion.indexOf('Win') !== -1
75
+ const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey
76
+
77
+ let updatedIds = []
78
+
79
+ // No modifier keys pressed during click:
80
+ // - update selected to just this one
81
+ // - open document
82
+ if (!selectMultiple && !selectAdditional) {
83
+ navigateIntent('edit', {id: clickedId, type})
84
+ return setSelectedIds([clickedId])
85
+ }
86
+
87
+ // Shift key was held, add id's between last selected and this one
88
+ // ...before adding this one
89
+ if (selectMultiple && !isSelected) {
90
+ const lastSelectedId = selectedIds[selectedIds.length - 1]
91
+ const lastSelectedIndex = orderedData.findIndex((item) => item._id === lastSelectedId)
92
+
93
+ const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex
94
+ const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex
95
+
96
+ const betweenIds = orderedData
97
+ .filter((item, itemIndex) => itemIndex > firstSelected && itemIndex < lastSelected)
98
+ .map((item) => item._id)
99
+
100
+ updatedIds = [...selectedIds, ...betweenIds, clickedId]
101
+ } else if (isSelected) {
102
+ // Toggle off a single id
103
+ updatedIds = selectedIds.filter((id) => id !== clickedId)
104
+ } else {
105
+ // Toggle on a single id
106
+ updatedIds = [...selectedIds, clickedId]
107
+ }
108
+
109
+ return setSelectedIds(updatedIds)
110
+ },
111
+ [setSelectedIds, navigateIntent, orderedData, selectedIds, type]
112
+ )
113
+
114
+ const client = useSanityClient()
115
+
116
+ const transactPatches = useCallback(
117
+ async (patches: [string, PatchOperations][], message: string) => {
118
+ const transaction = client.transaction()
119
+
120
+ patches.forEach(([docId, ops]) => transaction.patch(docId, ops))
121
+
122
+ await transaction
123
+ .commit()
124
+ .then((updated) => {
125
+ clearSelected()
126
+ setDraggingId(``)
127
+ setListIsUpdating(false)
128
+ toast.push({
129
+ title: `${
130
+ updated.results.length === 1 ? `1 Document` : `${updated.results.length} Documents`
131
+ } Reordered`,
132
+ status: `success`,
133
+ description: message,
134
+ })
135
+ })
136
+ .catch(() => {
137
+ setDraggingId(``)
138
+ setListIsUpdating(false)
139
+ toast.push({
140
+ title: `Reordering failed`,
141
+ status: `error`,
142
+ })
143
+ })
144
+ },
145
+ [client, setDraggingId, clearSelected, setListIsUpdating, toast]
146
+ )
147
+
148
+ const handleDragEnd = useCallback(
149
+ (result: DropResult | undefined, entities: SanityDocument[]) => {
150
+ setDraggingId(``)
151
+
152
+ const {source, destination, draggableId} = result ?? {}
153
+
154
+ // Don't do anything if nothing changed
155
+ if (source?.index === destination?.index) return
156
+
157
+ // Don't do anything if we don't have the entitites
158
+ if (!entities?.length || !draggableId) return
159
+
160
+ // A document can be dragged without being one-of-many-selected
161
+ const effectedIds = selectedIds?.length ? selectedIds : [draggableId]
162
+
163
+ // Don't do anything if we don't have ids to effect
164
+ if (!effectedIds?.length) return
165
+
166
+ // Update state to update styles + prevent data refetching
167
+ setListIsUpdating(true)
168
+ setSelectedIds(effectedIds)
169
+
170
+ const {newOrder, patches, message} = reorderDocuments({
171
+ entities,
172
+ selectedIds: effectedIds,
173
+ source,
174
+ destination,
175
+ })
176
+
177
+ // Update local state
178
+ if (newOrder?.length) {
179
+ setOrderedData(newOrder as any)
180
+ }
181
+
182
+ // Transact new order patches
183
+ if (patches?.length) {
184
+ transactPatches(patches, message)
185
+ }
186
+ },
187
+ [selectedIds, setDraggingId, setSelectedIds, transactPatches, setListIsUpdating]
188
+ )
189
+
190
+ const handleDragStart = useCallback(
191
+ (start: {draggableId: string}) => {
192
+ const id = start.draggableId
193
+ const selected = selectedIds.includes(id)
194
+
195
+ // if dragging an item that is not selected - unselect all items
196
+ if (!selected) clearSelected()
197
+
198
+ setDraggingId(id)
199
+ },
200
+ [selectedIds, clearSelected, setDraggingId]
201
+ )
202
+
203
+ // Move one document up or down one place, by fake invoking the drag function
204
+ const incrementIndex = useCallback(
205
+ (shiftFrom: number, shiftTo: number, id: string, entities: SanityDocument[]) => {
206
+ const result = {
207
+ draggableId: id,
208
+ source: {index: shiftFrom},
209
+ destination: {index: shiftTo},
210
+ }
211
+
212
+ return handleDragEnd(result as DropResult, entities)
213
+ },
214
+ [handleDragEnd]
215
+ )
216
+
217
+ const onWindowKeyDown = useCallback(
218
+ (event: KeyboardEvent) => {
219
+ if (event.key === 'Escape') {
220
+ clearSelected()
221
+ }
222
+ },
223
+ [clearSelected]
224
+ )
225
+
226
+ useEffect(() => {
227
+ window.addEventListener('keydown', onWindowKeyDown)
228
+
229
+ return () => {
230
+ window.removeEventListener('keydown', onWindowKeyDown)
231
+ }
232
+ }, [onWindowKeyDown])
233
+
234
+ // Find all items with duplicate order field
235
+ const duplicateOrders = useMemo(() => {
236
+ if (!orderedData.length) return []
237
+
238
+ const orderField = orderedData.map((item) => item[ORDER_FIELD_NAME])
239
+
240
+ return orderField.filter((item, index) => orderField.indexOf(item) !== index)
241
+ }, [orderedData])
242
+
243
+ const onDragEnd = useCallback(
244
+ (result: DropResult) => handleDragEnd(result, orderedData),
245
+ [orderedData, handleDragEnd]
246
+ )
247
+
248
+ return (
249
+ <DragDropContext onDragStart={handleDragStart} onDragEnd={onDragEnd}>
250
+ <Droppable droppableId="documentSortZone">
251
+ {(provided) => (
252
+ <div {...provided.droppableProps} ref={provided.innerRef}>
253
+ {orderedData.map((item, index) => (
254
+ <Draggable
255
+ key={`${item._id}-${item[ORDER_FIELD_NAME]}`}
256
+ draggableId={item._id}
257
+ index={index}
258
+ // onClick={(event) => handleDraggableClick(event, provided, snapshot)}
259
+ >
260
+ {(innerProvided, innerSnapshot) => {
261
+ const isSelected = selectedIds.includes(item._id)
262
+ const isDragging = innerSnapshot.isDragging
263
+ const isGhosting = Boolean(!isDragging && draggingId && isSelected)
264
+ const isUpdating = listIsUpdating && isSelected
265
+ const isDisabled = Boolean(!item[ORDER_FIELD_NAME])
266
+ const isDuplicate = duplicateOrders.includes(item[ORDER_FIELD_NAME])
267
+ const tone = cardTone({isDuplicate, isGhosting, isDragging, isSelected})
268
+
269
+ return (
270
+ <div
271
+ ref={innerProvided.innerRef}
272
+ {...innerProvided.draggableProps}
273
+ {...innerProvided.dragHandleProps}
274
+ style={
275
+ isDisabled
276
+ ? {opacity: 0.2, pointerEvents: `none`}
277
+ : getItemStyle(innerProvided.draggableProps.style, isUpdating)
278
+ }
279
+ >
280
+ <Box paddingBottom={1}>
281
+ <Card tone={tone} shadow={isDragging ? 2 : undefined} radius={2}>
282
+ <Document
283
+ doc={item}
284
+ entities={orderedData}
285
+ handleSelect={handleSelect}
286
+ increment={incrementIndex}
287
+ index={index}
288
+ isFirst={index === 0}
289
+ isLast={index === orderedData.length - 1}
290
+ />
291
+ </Card>
292
+ </Box>
293
+ </div>
294
+ )
295
+ }}
296
+ </Draggable>
297
+ ))}
298
+ {provided.placeholder}
299
+ </div>
300
+ )}
301
+ </Droppable>
302
+ </DragDropContext>
303
+ )
304
+ }
@@ -1,8 +1,7 @@
1
- import PropTypes from 'prop-types'
2
- import React from 'react'
1
+ import React, {PropsWithChildren} from 'react'
3
2
  import {Box, Card, Text} from '@sanity/ui'
4
3
 
5
- export default function Feedback({children}) {
4
+ export default function Feedback({children}: PropsWithChildren<{}>) {
6
5
  return (
7
6
  <Box padding={3}>
8
7
  <Card padding={4} radius={2} shadow={1} tone="caution">
@@ -11,7 +10,3 @@ export default function Feedback({children}) {
11
10
  </Box>
12
11
  )
13
12
  }
14
-
15
- Feedback.propTypes = {
16
- children: PropTypes.node.isRequired,
17
- }
@@ -0,0 +1,7 @@
1
+ import React from 'react'
2
+
3
+ export interface OrderableContextValue {
4
+ showIncrements?: boolean
5
+ }
6
+
7
+ export const OrderableContext = React.createContext<OrderableContextValue>({})
@@ -1,18 +1,27 @@
1
- import PropTypes from 'prop-types'
2
1
  import React, {Component} from 'react'
3
2
 
3
+ import {SanityClient} from '@sanity/client'
4
+ import type {ToastParams} from '@sanity/ui'
4
5
  import DocumentListWrapper from './DocumentListWrapper'
5
6
  import {resetOrder} from './helpers/resetOrder'
6
7
 
7
- // Must use a Class Component here so the actionHandlers can be called
8
- export default class OrderableDocumentList extends Component {
9
- static propTypes = {
10
- options: PropTypes.shape({
11
- type: PropTypes.string,
12
- }).isRequired,
8
+ export interface OrderableDocumentListProps {
9
+ options: {
10
+ type: string
11
+ client: SanityClient,
12
+ filter?: string,
13
+ params?: Record<string, unknown>
13
14
  }
15
+ }
16
+
17
+ interface State {
18
+ showIncrements: boolean
19
+ resetOrderTransaction: ToastParams
20
+ }
14
21
 
15
- constructor(props) {
22
+ // Must use a Class Component here so the actionHandlers can be called
23
+ export default class OrderableDocumentList extends Component<OrderableDocumentListProps, State> {
24
+ constructor(props: OrderableDocumentListProps) {
16
25
  super(props)
17
26
  this.state = {
18
27
  showIncrements: false,
@@ -36,7 +45,7 @@ export default class OrderableDocumentList extends Component {
36
45
  },
37
46
  }))
38
47
 
39
- const update = await resetOrder(this.props.options.type)
48
+ const update = await resetOrder(this.props.options.type, this.props.options.client)
40
49
 
41
50
  const reorderWasSuccessful = update?.results?.length
42
51
 
@@ -53,9 +62,15 @@ export default class OrderableDocumentList extends Component {
53
62
  }
54
63
 
55
64
  render() {
65
+ const type = this?.props?.options?.type
66
+ if (!type) {
67
+ return null
68
+ }
56
69
  return (
57
70
  <DocumentListWrapper
58
- type={this?.props?.options?.type}
71
+ filter={this?.props?.options?.filter}
72
+ params={this?.props?.options?.params}
73
+ type={type}
59
74
  showIncrements={this.state.showIncrements}
60
75
  resetOrderTransaction={this.state.resetOrderTransaction}
61
76
  />
@@ -0,0 +1,33 @@
1
+ import {SanityClient} from '@sanity/client'
2
+ import type {ConfigContext} from 'sanity'
3
+ import {SchemaContext} from '../fields/orderRankField'
4
+
5
+ type ClientSubscription = (client: SanityClient) => void
6
+ type ClientKey = `${string}:${string}`
7
+ const subscriptions: Record<ClientKey, ClientSubscription[]> = {}
8
+
9
+ /**
10
+ * @internal
11
+ *
12
+ * v3 does not expose client in the schema API, which means no client for the initial value code.
13
+ * This is a workaround for that; we update the global client from a place we _do_ have access to the client,
14
+ * the use the global in schema-callbacks.
15
+ *
16
+ * Note: The code assumes sanityClientChanged is called AFTER all subscribeSanityClient calls are done.
17
+ */
18
+ export function sanityClientChanged(context: ConfigContext) {
19
+ ;(subscriptions[clientKey(context)] ?? []).forEach((subscriber) => subscriber(context.client))
20
+ }
21
+
22
+ /**
23
+ * @internal
24
+ */
25
+ export function subscribeSanityClient(context: SchemaContext, callback: ClientSubscription) {
26
+ const key = clientKey(context)
27
+ const existing = subscriptions[key] ?? []
28
+ subscriptions[key] = [...existing, callback]
29
+ }
30
+
31
+ function clientKey(context: SchemaContext): ClientKey {
32
+ return `${context.projectId}:${context.dataset}`
33
+ }
@@ -1,26 +1,42 @@
1
- import S from '@sanity/desk-tool/structure-builder'
2
- import {SortIcon, GenerateIcon} from '@sanity/icons'
3
- import schema from 'part:@sanity/base/schema'
1
+ import {GenerateIcon, SortIcon} from '@sanity/icons'
2
+ import type {ConfigContext} from 'sanity'
4
3
 
4
+ import {ComponentType} from 'react'
5
+ import {StructureBuilder} from 'sanity/desk'
5
6
  import OrderableDocumentList from '../OrderableDocumentList'
7
+ import {sanityClientChanged} from './globalClientWorkaround'
6
8
 
7
- export function orderableDocumentListDeskItem(config = {}) {
8
- if (!config?.type) {
9
+ export interface OrderableListConfig {
10
+ type: string
11
+ id?: string
12
+ title?: string
13
+ icon?: ComponentType
14
+ params?: Record<string, unknown>
15
+ filter?: string
16
+ context: ConfigContext
17
+ S: StructureBuilder
18
+ }
19
+
20
+ export function orderableDocumentListDeskItem(config: OrderableListConfig) {
21
+ if (!config?.type || !config.context || !config.S) {
9
22
  throw new Error(`
10
- "type" not defined in orderableDocumentListDeskItem parameters.
11
- \n\n
23
+ type, context and S (StructureBuilder) must be provided.
24
+ context and S are available when configuring structure.
12
25
  Example: orderableDocumentListDeskItem({type: 'category'})
13
26
  `)
14
27
  }
15
28
 
16
- const {type, title, icon} = config
29
+ const {type, filter, params, title, icon, id, context, S} = config
30
+ const {schema, client} = context
31
+ // workaround so schemas can get access to client in callbacks
32
+ sanityClientChanged(context)
17
33
 
18
34
  const listTitle = title ?? `Orderable ${type}`
19
- const listId = `orderable-${type}`
35
+ const listId = id ?? `orderable-${type}`
20
36
  const listIcon = icon ?? SortIcon
21
37
  const typeTitle = schema.get(type)?.title ?? type
22
38
 
23
- return S.listItem(type)
39
+ return S.listItem()
24
40
  .title(listTitle)
25
41
  .id(listId)
26
42
  .icon(listIcon)
@@ -33,7 +49,7 @@ export function orderableDocumentListDeskItem(config = {}) {
33
49
 
34
50
  type: 'component',
35
51
  component: OrderableDocumentList,
36
- options: {type},
52
+ options: {type, filter, params, client},
37
53
  menuItems: [
38
54
  S.menuItem()
39
55
  .title(`Create new ${typeTitle}`)
@@ -0,0 +1,45 @@
1
+ import {ConfigContext} from 'sanity'
2
+ import type {SanityClient} from '@sanity/client'
3
+ import {ORDER_FIELD_NAME} from '../helpers/constants'
4
+ import initialRank from '../helpers/initialRank'
5
+ import {subscribeSanityClient} from '../desk-structure/globalClientWorkaround'
6
+
7
+ export type SchemaContext = Omit<ConfigContext, 'schema' | 'currentUser' | 'client'>
8
+
9
+ export interface RankFieldConfig {
10
+ type: string
11
+ context: SchemaContext
12
+ }
13
+
14
+ export const orderRankField = (config: RankFieldConfig) => {
15
+ if (!config?.type || !config.context) {
16
+ throw new Error(
17
+ `
18
+ type and context must be provided. context is available when configuring schema.
19
+ Example: orderRankField({type: 'category', context})
20
+ `
21
+ )
22
+ }
23
+
24
+ const {type} = config
25
+
26
+ let client: SanityClient | undefined
27
+ subscribeSanityClient(config.context, (updatedClient) => {
28
+ client = updatedClient
29
+ })
30
+ return {
31
+ title: 'Order Rank',
32
+ readOnly: true,
33
+ hidden: true,
34
+ ...config,
35
+ name: ORDER_FIELD_NAME,
36
+ type: 'string',
37
+ initialValue: async () => {
38
+ const lastDocOrderRank = await client?.fetch(
39
+ `*[_type == $type]|order(@[$order] desc)[0][$order]`,
40
+ {type, order: ORDER_FIELD_NAME}
41
+ )
42
+ return initialRank(lastDocOrderRank)
43
+ },
44
+ }
45
+ }
@@ -0,0 +1,13 @@
1
+ import {useClient} from 'sanity'
2
+ import {useMemo} from 'react'
3
+
4
+ export function useSanityClient() {
5
+ const baseClient = useClient()
6
+ return useMemo(
7
+ () =>
8
+ baseClient.withConfig({
9
+ apiVersion: '2021-09-01',
10
+ }),
11
+ [baseClient]
12
+ )
13
+ }
@@ -0,0 +1 @@
1
+ export const ORDER_FIELD_NAME = `orderRank` as const
@@ -2,9 +2,9 @@ import {LexoRank} from 'lexorank'
2
2
 
3
3
  // Use in initial value field by passing in the rank value of the last document
4
4
  // If not value passed, generate a sensibly low rank
5
- export default function initialRank(lastRankValue = ``) {
5
+ export default function initialRank(lastRankValue = ``): string {
6
6
  const lastRank = lastRankValue ? LexoRank.parse(lastRankValue) : LexoRank.min()
7
7
  const nextRank = lastRank.genNext().genNext()
8
8
 
9
- return nextRank.value
9
+ return (nextRank as any).value
10
10
  }