@sanity/orderable-document-list 1.5.1 → 2.0.0
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.
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +669 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -83
- package/README.md +0 -218
- package/lib/index.cjs +0 -581
- package/lib/index.cjs.map +0 -1
- package/lib/index.d.cts +0 -65
- package/lib/index.d.ts +0 -65
- package/lib/index.js +0 -589
- package/lib/index.js.map +0 -1
- package/sanity.json +0 -8
- package/src/Document.tsx +0 -138
- package/src/DocumentListQuery.tsx +0 -95
- package/src/DocumentListWrapper.tsx +0 -112
- package/src/DraggableList.tsx +0 -316
- package/src/OrderableContext.ts +0 -7
- package/src/OrderableDocumentList.tsx +0 -81
- package/src/desk-structure/orderableDocumentListDeskItem.ts +0 -84
- package/src/fields/orderRankField.ts +0 -43
- package/src/fields/orderRankOrdering.ts +0 -8
- package/src/helpers/__tests__/getFilteredDeduppedDocs.test.ts +0 -327
- package/src/helpers/__tests__/initialRank.test.ts +0 -20
- package/src/helpers/__tests__/parseOrderRank.test.ts +0 -39
- package/src/helpers/__tests__/reorderDocuments.test.ts +0 -45
- package/src/helpers/client.ts +0 -8
- package/src/helpers/constants.ts +0 -4
- package/src/helpers/getFilteredDedupedDocs.ts +0 -103
- package/src/helpers/initialRank.ts +0 -16
- package/src/helpers/parseOrderRank.ts +0 -21
- package/src/helpers/query.ts +0 -50
- package/src/helpers/reorderDocuments.ts +0 -133
- package/src/helpers/resetOrder.ts +0 -48
- package/src/index.ts +0 -7
- package/src/types.ts +0 -10
- package/v2-incompatible.js +0 -11
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {LexoRank} from 'lexorank'
|
|
2
|
-
import type {PatchOperations} from 'sanity'
|
|
3
|
-
|
|
4
|
-
import type {SanityDocumentWithOrder} from '../types'
|
|
5
|
-
import {ORDER_FIELD_NAME} from './constants'
|
|
6
|
-
import {parseOrderRank} from './parseOrderRank'
|
|
7
|
-
|
|
8
|
-
export interface MaifestArgs {
|
|
9
|
-
entities: SanityDocumentWithOrder[]
|
|
10
|
-
selectedItems: SanityDocumentWithOrder[]
|
|
11
|
-
isMovingUp: boolean
|
|
12
|
-
curIndex: number
|
|
13
|
-
nextIndex: number
|
|
14
|
-
prevIndex: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ReorderArgs {
|
|
18
|
-
entities: SanityDocumentWithOrder[]
|
|
19
|
-
selectedIds: string[]
|
|
20
|
-
source: any
|
|
21
|
-
destination: any
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ReorderReturn {
|
|
25
|
-
newOrder: SanityDocumentWithOrder[]
|
|
26
|
-
patches: [string, PatchOperations][]
|
|
27
|
-
message: any
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function lexicographicalSort(a: SanityDocumentWithOrder, b: SanityDocumentWithOrder) {
|
|
31
|
-
if (!a[ORDER_FIELD_NAME] || !b[ORDER_FIELD_NAME]) {
|
|
32
|
-
return 0
|
|
33
|
-
} else if (a[ORDER_FIELD_NAME] < b[ORDER_FIELD_NAME]) {
|
|
34
|
-
return -1
|
|
35
|
-
} else if (a[ORDER_FIELD_NAME] > b[ORDER_FIELD_NAME]) {
|
|
36
|
-
return 1
|
|
37
|
-
}
|
|
38
|
-
return 0
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const reorderDocuments = ({
|
|
42
|
-
entities,
|
|
43
|
-
selectedIds,
|
|
44
|
-
source,
|
|
45
|
-
destination,
|
|
46
|
-
}: ReorderArgs): ReorderReturn => {
|
|
47
|
-
const startIndex = source.index
|
|
48
|
-
const endIndex = destination.index
|
|
49
|
-
const isMovingUp = startIndex > endIndex
|
|
50
|
-
const selectedItems = entities.filter((item) => selectedIds.includes(item._id))
|
|
51
|
-
const message = [
|
|
52
|
-
'Moved',
|
|
53
|
-
selectedItems.length === 1 ? '1 document' : `${selectedItems.length} documents`,
|
|
54
|
-
isMovingUp ? 'up' : 'down',
|
|
55
|
-
'from position',
|
|
56
|
-
`${startIndex + 1} to ${endIndex + 1}`,
|
|
57
|
-
].join(' ')
|
|
58
|
-
|
|
59
|
-
const {all, selected} = entities.reduce<{
|
|
60
|
-
all: SanityDocumentWithOrder[]
|
|
61
|
-
selected: SanityDocumentWithOrder[]
|
|
62
|
-
}>(
|
|
63
|
-
(acc, cur, curIndex) => {
|
|
64
|
-
// Selected items get spread in below, so skip them here
|
|
65
|
-
if (selectedIds.includes(cur._id)) {
|
|
66
|
-
return {all: acc.all, selected: acc.selected}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Drop selected items in
|
|
70
|
-
if (curIndex === endIndex) {
|
|
71
|
-
const prevIndex = curIndex - 1
|
|
72
|
-
const prevRank = parseOrderRank(entities[prevIndex]?.[ORDER_FIELD_NAME], LexoRank.min())
|
|
73
|
-
|
|
74
|
-
const curRank = parseOrderRank(entities[curIndex][ORDER_FIELD_NAME], LexoRank.min())
|
|
75
|
-
|
|
76
|
-
const nextIndex = curIndex + 1
|
|
77
|
-
const nextRank = parseOrderRank(entities[nextIndex]?.[ORDER_FIELD_NAME], LexoRank.max())
|
|
78
|
-
|
|
79
|
-
let betweenRank = isMovingUp ? prevRank.between(curRank) : curRank.between(nextRank)
|
|
80
|
-
|
|
81
|
-
// For each selected item, assign a new orderRank between now and next
|
|
82
|
-
for (let selectedIndex = 0; selectedIndex < selectedItems.length; selectedIndex += 1) {
|
|
83
|
-
selectedItems[selectedIndex][ORDER_FIELD_NAME] = betweenRank.toString()
|
|
84
|
-
betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
// The `all` array gets sorted by order field later anyway
|
|
89
|
-
// so that this probably isn't necessary ¯\_(ツ)_/¯
|
|
90
|
-
all: isMovingUp
|
|
91
|
-
? [...acc.all, ...selectedItems, cur]
|
|
92
|
-
: [...acc.all, cur, ...selectedItems],
|
|
93
|
-
selected: selectedItems,
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return {all: [...acc.all, cur], selected: acc.selected}
|
|
98
|
-
},
|
|
99
|
-
{all: [], selected: []},
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
const patches = selected.flatMap((doc) => {
|
|
103
|
-
const docPatches: [string, PatchOperations][] = [
|
|
104
|
-
[
|
|
105
|
-
doc._id,
|
|
106
|
-
{
|
|
107
|
-
set: {
|
|
108
|
-
[ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME],
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
]
|
|
113
|
-
|
|
114
|
-
// If it's a draft, we need to patch the published document as well
|
|
115
|
-
if (doc._id.startsWith('drafts.') && doc.hasPublished) {
|
|
116
|
-
docPatches.push([
|
|
117
|
-
doc._id.replace('drafts.', ''),
|
|
118
|
-
{
|
|
119
|
-
set: {
|
|
120
|
-
[ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME],
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
])
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return docPatches
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
// Safety-check to make sure everything is in order
|
|
130
|
-
const allSorted = all.sort(lexicographicalSort)
|
|
131
|
-
|
|
132
|
-
return {newOrder: allSorted, patches, message}
|
|
133
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {LexoRank} from 'lexorank'
|
|
2
|
-
import type {MultipleMutationResult, SanityClient} from '@sanity/client'
|
|
3
|
-
import {ORDER_FIELD_NAME} from './constants'
|
|
4
|
-
import {DocumentListQueryProps, getDocumentQuery} from './query'
|
|
5
|
-
|
|
6
|
-
export interface ResetOrderParams extends DocumentListQueryProps {
|
|
7
|
-
client: SanityClient
|
|
8
|
-
currentVersion?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Function to wipe and re-do ordering with LexoRank
|
|
12
|
-
// Will at least attempt to start with the current order
|
|
13
|
-
export async function resetOrder(params: ResetOrderParams): Promise<MultipleMutationResult | null> {
|
|
14
|
-
const {client, currentVersion, ...queryProps} = params
|
|
15
|
-
const {query, queryParams} = getDocumentQuery({...queryProps, currentVersion})
|
|
16
|
-
|
|
17
|
-
const documents = await client.fetch<
|
|
18
|
-
Array<{
|
|
19
|
-
_id: string
|
|
20
|
-
_type: string
|
|
21
|
-
[ORDER_FIELD_NAME]: string
|
|
22
|
-
}>
|
|
23
|
-
>(query, queryParams, {
|
|
24
|
-
tag: 'orderable-document-list.reset-order',
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
if (documents.length === 0) {
|
|
28
|
-
return null
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let aLexoRank = LexoRank.min()
|
|
32
|
-
|
|
33
|
-
const transaction = documents
|
|
34
|
-
.map((doc) => doc._id)
|
|
35
|
-
.reduce((trx, documentId) => {
|
|
36
|
-
// Generate next rank before even the first document so there's room to move!
|
|
37
|
-
aLexoRank = aLexoRank.genNext().genNext()
|
|
38
|
-
|
|
39
|
-
return trx.patch(documentId, {
|
|
40
|
-
set: {[ORDER_FIELD_NAME]: aLexoRank.toString()},
|
|
41
|
-
})
|
|
42
|
-
}, client.transaction())
|
|
43
|
-
|
|
44
|
-
return transaction.commit({
|
|
45
|
-
visibility: 'async',
|
|
46
|
-
tag: 'orderable-document-list.reset-order',
|
|
47
|
-
})
|
|
48
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export {orderRankField, type RankFieldConfig} from './fields/orderRankField'
|
|
2
|
-
export {orderRankOrdering} from './fields/orderRankOrdering'
|
|
3
|
-
export {
|
|
4
|
-
orderableDocumentListDeskItem,
|
|
5
|
-
type OrderableListConfig,
|
|
6
|
-
} from './desk-structure/orderableDocumentListDeskItem'
|
|
7
|
-
export {OrderableDocumentList} from './OrderableDocumentList'
|
package/src/types.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type {SanityDocument} from 'sanity'
|
|
2
|
-
|
|
3
|
-
import {ORDER_FIELD_NAME} from './helpers/constants'
|
|
4
|
-
|
|
5
|
-
export interface SanityDocumentWithOrder extends SanityDocument {
|
|
6
|
-
[ORDER_FIELD_NAME]?: string
|
|
7
|
-
hasPublished?: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type NewItemPosition = 'after' | 'before'
|
package/v2-incompatible.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const {showIncompatiblePluginDialog} = require('@sanity/incompatible-plugin')
|
|
2
|
-
const {name, version, sanityExchangeUrl} = require('./package.json')
|
|
3
|
-
|
|
4
|
-
export default showIncompatiblePluginDialog({
|
|
5
|
-
name: name,
|
|
6
|
-
versions: {
|
|
7
|
-
v3: version,
|
|
8
|
-
v2: undefined,
|
|
9
|
-
},
|
|
10
|
-
sanityExchangeUrl,
|
|
11
|
-
})
|