@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,327 +0,0 @@
|
|
|
1
|
-
import {describe, it, expect} from 'vitest'
|
|
2
|
-
import {type SanityDocumentWithOrder} from '../../types'
|
|
3
|
-
import {getFilteredDedupedDocs} from '../getFilteredDedupedDocs'
|
|
4
|
-
|
|
5
|
-
describe('getFilteredDedupedDocs', () => {
|
|
6
|
-
const mockDocumentsFromVersionPerspective: SanityDocumentWithOrder[] = [
|
|
7
|
-
{
|
|
8
|
-
_id: 'drafts.document-1',
|
|
9
|
-
_type: 'orderableCategory',
|
|
10
|
-
orderRank: '0|10000o:',
|
|
11
|
-
_createdAt: new Date().toISOString(),
|
|
12
|
-
_updatedAt: new Date().toISOString(),
|
|
13
|
-
_rev: '123',
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
_id: 'versions.rmWGG9z1W.document-2',
|
|
17
|
-
_type: 'orderableCategory',
|
|
18
|
-
orderRank: '0|100014:',
|
|
19
|
-
_createdAt: new Date().toISOString(),
|
|
20
|
-
_updatedAt: new Date().toISOString(),
|
|
21
|
-
_rev: '123',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
_id: 'drafts.document-3',
|
|
25
|
-
_type: 'orderableCategory',
|
|
26
|
-
orderRank: '0|10001k:',
|
|
27
|
-
_createdAt: new Date().toISOString(),
|
|
28
|
-
_updatedAt: new Date().toISOString(),
|
|
29
|
-
_rev: '123',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
_id: 'document-4',
|
|
33
|
-
_type: 'orderableCategory',
|
|
34
|
-
orderRank: '0|100020:',
|
|
35
|
-
_createdAt: new Date().toISOString(),
|
|
36
|
-
_updatedAt: new Date().toISOString(),
|
|
37
|
-
_rev: '123',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
_id: 'versions.rmWGG9z1W.document-6',
|
|
41
|
-
_type: 'orderableCategory',
|
|
42
|
-
orderRank: '0|10002w:',
|
|
43
|
-
_createdAt: new Date().toISOString(),
|
|
44
|
-
_updatedAt: new Date().toISOString(),
|
|
45
|
-
_rev: '123',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
_id: 'document-5',
|
|
49
|
-
_type: 'orderableCategory',
|
|
50
|
-
orderRank: '0|100034:',
|
|
51
|
-
_createdAt: new Date().toISOString(),
|
|
52
|
-
_updatedAt: new Date().toISOString(),
|
|
53
|
-
_rev: '123',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
_id: 'drafts.document-5',
|
|
57
|
-
_type: 'orderableCategory',
|
|
58
|
-
orderRank: '0|100034:',
|
|
59
|
-
_createdAt: new Date().toISOString(),
|
|
60
|
-
_updatedAt: new Date().toISOString(),
|
|
61
|
-
_rev: '123',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
_id: 'document-9',
|
|
65
|
-
_type: 'orderableCategory',
|
|
66
|
-
orderRank: '0|10003c:',
|
|
67
|
-
_createdAt: new Date().toISOString(),
|
|
68
|
-
_updatedAt: new Date().toISOString(),
|
|
69
|
-
_rev: '123',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
_id: 'drafts.document-8',
|
|
73
|
-
_type: 'orderableCategory',
|
|
74
|
-
orderRank: '0|10003s:',
|
|
75
|
-
_createdAt: new Date().toISOString(),
|
|
76
|
-
_updatedAt: new Date().toISOString(),
|
|
77
|
-
_rev: '123',
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
_id: 'versions.rmWGG9z1W.document-3',
|
|
81
|
-
_type: 'orderableCategory',
|
|
82
|
-
orderRank: '0|100048:',
|
|
83
|
-
_createdAt: new Date().toISOString(),
|
|
84
|
-
_updatedAt: new Date().toISOString(),
|
|
85
|
-
_rev: '123',
|
|
86
|
-
},
|
|
87
|
-
]
|
|
88
|
-
|
|
89
|
-
const mockDocumentsInDraftsPerspective: SanityDocumentWithOrder[] = [
|
|
90
|
-
{
|
|
91
|
-
_id: 'drafts.document-1',
|
|
92
|
-
_type: 'orderableCategory',
|
|
93
|
-
orderRank: '0|10000o:',
|
|
94
|
-
_createdAt: new Date().toISOString(),
|
|
95
|
-
_updatedAt: new Date().toISOString(),
|
|
96
|
-
_rev: '123',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
_id: 'drafts.document-3',
|
|
100
|
-
_type: 'orderableCategory',
|
|
101
|
-
orderRank: '0|10001k:',
|
|
102
|
-
_createdAt: new Date().toISOString(),
|
|
103
|
-
_updatedAt: new Date().toISOString(),
|
|
104
|
-
_rev: '123',
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
_id: 'document-4',
|
|
108
|
-
_type: 'orderableCategory',
|
|
109
|
-
orderRank: '0|100020:',
|
|
110
|
-
_createdAt: new Date().toISOString(),
|
|
111
|
-
_updatedAt: new Date().toISOString(),
|
|
112
|
-
_rev: '123',
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
_id: 'document-5',
|
|
116
|
-
_type: 'orderableCategory',
|
|
117
|
-
orderRank: '0|100034:',
|
|
118
|
-
_createdAt: new Date().toISOString(),
|
|
119
|
-
_updatedAt: new Date().toISOString(),
|
|
120
|
-
_rev: '123',
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
_id: 'drafts.document-5',
|
|
124
|
-
_type: 'orderableCategory',
|
|
125
|
-
orderRank: '0|100034:',
|
|
126
|
-
_createdAt: new Date().toISOString(),
|
|
127
|
-
_updatedAt: new Date().toISOString(),
|
|
128
|
-
_rev: '123',
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
_id: 'document-7',
|
|
132
|
-
_type: 'orderableCategory',
|
|
133
|
-
orderRank: '0|10003c:',
|
|
134
|
-
_createdAt: new Date().toISOString(),
|
|
135
|
-
_updatedAt: new Date().toISOString(),
|
|
136
|
-
_rev: '123',
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
_id: 'drafts.document-8',
|
|
140
|
-
_type: 'orderableCategory',
|
|
141
|
-
orderRank: '0|10003s:',
|
|
142
|
-
_createdAt: new Date().toISOString(),
|
|
143
|
-
_updatedAt: new Date().toISOString(),
|
|
144
|
-
_rev: '123',
|
|
145
|
-
},
|
|
146
|
-
]
|
|
147
|
-
|
|
148
|
-
const mockDocumentsPublishedPerspective: SanityDocumentWithOrder[] = [
|
|
149
|
-
{
|
|
150
|
-
_id: '123',
|
|
151
|
-
_type: 'orderableCategory',
|
|
152
|
-
orderRank: '0|100035:',
|
|
153
|
-
_createdAt: new Date().toISOString(),
|
|
154
|
-
_updatedAt: new Date().toISOString(),
|
|
155
|
-
_rev: '123',
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
_id: '456',
|
|
159
|
-
_type: 'orderableCategory',
|
|
160
|
-
orderRank: '0|100036:',
|
|
161
|
-
_createdAt: new Date().toISOString(),
|
|
162
|
-
_updatedAt: new Date().toISOString(),
|
|
163
|
-
_rev: '123',
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
_id: '789',
|
|
167
|
-
_type: 'orderableCategory',
|
|
168
|
-
orderRank: '0|10003h:',
|
|
169
|
-
_createdAt: new Date().toISOString(),
|
|
170
|
-
_updatedAt: new Date().toISOString(),
|
|
171
|
-
_rev: '123',
|
|
172
|
-
},
|
|
173
|
-
]
|
|
174
|
-
|
|
175
|
-
it('should filter and deduplicate documents in draft perspective', () => {
|
|
176
|
-
const result = getFilteredDedupedDocs(
|
|
177
|
-
mockDocumentsInDraftsPerspective as SanityDocumentWithOrder[],
|
|
178
|
-
'drafts',
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
// Should only include drafts and published (if it doesn't have a published)
|
|
182
|
-
expect(result).toHaveLength(6)
|
|
183
|
-
expect(result.map((doc) => doc._id)).toEqual([
|
|
184
|
-
'drafts.document-1',
|
|
185
|
-
'drafts.document-3',
|
|
186
|
-
'document-4',
|
|
187
|
-
'drafts.document-5',
|
|
188
|
-
'document-7',
|
|
189
|
-
'drafts.document-8',
|
|
190
|
-
])
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
it('should prioritize drafts over published in draft perspective', () => {
|
|
194
|
-
const documentsWithDuplicates = [
|
|
195
|
-
{
|
|
196
|
-
_id: 'drafts.123',
|
|
197
|
-
_type: 'test',
|
|
198
|
-
orderRank: 'a',
|
|
199
|
-
_createdAt: new Date().toISOString(),
|
|
200
|
-
_updatedAt: new Date().toISOString(),
|
|
201
|
-
_rev: '123',
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
_id: '123',
|
|
205
|
-
_type: 'test',
|
|
206
|
-
orderRank: 'b',
|
|
207
|
-
_createdAt: new Date().toISOString(),
|
|
208
|
-
_updatedAt: new Date().toISOString(),
|
|
209
|
-
_rev: '123',
|
|
210
|
-
},
|
|
211
|
-
]
|
|
212
|
-
|
|
213
|
-
const result = getFilteredDedupedDocs(documentsWithDuplicates, 'drafts')
|
|
214
|
-
|
|
215
|
-
// Should only show the draft version
|
|
216
|
-
expect(result).toHaveLength(1)
|
|
217
|
-
expect(result[0]._id).toBe('drafts.123')
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
it('should filter and deduplicate documents in published perspective', () => {
|
|
221
|
-
const result = getFilteredDedupedDocs(mockDocumentsPublishedPerspective, 'published')
|
|
222
|
-
|
|
223
|
-
// Should only include published documents
|
|
224
|
-
expect(result).toHaveLength(3)
|
|
225
|
-
expect(result.map((doc) => doc._id)).toEqual(['123', '456', '789'])
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
it('should filter and deduplicate documents in version perspective', () => {
|
|
229
|
-
const result = getFilteredDedupedDocs(
|
|
230
|
-
mockDocumentsFromVersionPerspective as SanityDocumentWithOrder[],
|
|
231
|
-
'rmWGG9z1W',
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
// Should include versions for the specific release, drafts, and published
|
|
235
|
-
expect(result).toHaveLength(8)
|
|
236
|
-
expect(result.map((doc) => doc._id)).toEqual([
|
|
237
|
-
'drafts.document-1',
|
|
238
|
-
'versions.rmWGG9z1W.document-2',
|
|
239
|
-
'document-4',
|
|
240
|
-
'versions.rmWGG9z1W.document-6',
|
|
241
|
-
'drafts.document-5',
|
|
242
|
-
'document-9',
|
|
243
|
-
'drafts.document-8',
|
|
244
|
-
'versions.rmWGG9z1W.document-3',
|
|
245
|
-
])
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
it('should prioritize versions over drafts in version perspective', () => {
|
|
249
|
-
const documentsWithVersionAndDraft: SanityDocumentWithOrder[] = [
|
|
250
|
-
{
|
|
251
|
-
_id: 'drafts.document-1',
|
|
252
|
-
_type: 'orderableCategory',
|
|
253
|
-
orderRank: '0|10001k:',
|
|
254
|
-
_createdAt: new Date().toISOString(),
|
|
255
|
-
_updatedAt: new Date().toISOString(),
|
|
256
|
-
_rev: '123',
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
_id: 'versions.rEZnogJnx.document-1',
|
|
260
|
-
_type: 'orderableCategory',
|
|
261
|
-
orderRank: '0|10000o:',
|
|
262
|
-
_createdAt: new Date().toISOString(),
|
|
263
|
-
_updatedAt: new Date().toISOString(),
|
|
264
|
-
_rev: '123',
|
|
265
|
-
},
|
|
266
|
-
]
|
|
267
|
-
|
|
268
|
-
const result = getFilteredDedupedDocs(documentsWithVersionAndDraft, 'rEZnogJnx')
|
|
269
|
-
|
|
270
|
-
// Should prioritize the version over the draft
|
|
271
|
-
expect(result).toHaveLength(1)
|
|
272
|
-
expect(result.map((doc) => doc._id)).toEqual(['versions.rEZnogJnx.document-1'])
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
it('should show draft of other versions when the selected version doesnt exist for the document', () => {
|
|
276
|
-
const result = getFilteredDedupedDocs(
|
|
277
|
-
[
|
|
278
|
-
{
|
|
279
|
-
_id: 'drafts.123',
|
|
280
|
-
_type: 'test',
|
|
281
|
-
orderRank: 'a',
|
|
282
|
-
_createdAt: new Date().toISOString(),
|
|
283
|
-
_updatedAt: new Date().toISOString(),
|
|
284
|
-
_rev: '123',
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
_id: 'versions.rEZnogJnx.123',
|
|
288
|
-
_type: 'test',
|
|
289
|
-
orderRank: 'b',
|
|
290
|
-
_createdAt: new Date().toISOString(),
|
|
291
|
-
_updatedAt: new Date().toISOString(),
|
|
292
|
-
_rev: '123',
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
_id: 'versions.other-version.456',
|
|
296
|
-
_type: 'test',
|
|
297
|
-
orderRank: 'b',
|
|
298
|
-
_createdAt: new Date().toISOString(),
|
|
299
|
-
_updatedAt: new Date().toISOString(),
|
|
300
|
-
_rev: '123',
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
_id: '789',
|
|
304
|
-
_type: 'test',
|
|
305
|
-
orderRank: 'b',
|
|
306
|
-
_createdAt: new Date().toISOString(),
|
|
307
|
-
_updatedAt: new Date().toISOString(),
|
|
308
|
-
_rev: '123',
|
|
309
|
-
},
|
|
310
|
-
],
|
|
311
|
-
'other-version',
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
// Should show the draft of the other version
|
|
315
|
-
expect(result).toHaveLength(3)
|
|
316
|
-
expect(result.map((doc) => doc._id)).toEqual([
|
|
317
|
-
'drafts.123',
|
|
318
|
-
'versions.other-version.456',
|
|
319
|
-
'789',
|
|
320
|
-
])
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
it('should handle empty input', () => {
|
|
324
|
-
const result = getFilteredDedupedDocs([], 'drafts')
|
|
325
|
-
expect(result).toEqual([])
|
|
326
|
-
})
|
|
327
|
-
})
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
import {LexoRank} from 'lexorank'
|
|
3
|
-
|
|
4
|
-
import {initialRank} from '../initialRank'
|
|
5
|
-
|
|
6
|
-
describe('initialRank', () => {
|
|
7
|
-
it('handles invalid/non-string compareRankValue without throwing', () => {
|
|
8
|
-
const action = () => initialRank(1 as unknown as string)
|
|
9
|
-
expect(action).not.toThrow()
|
|
10
|
-
|
|
11
|
-
const rank = action()
|
|
12
|
-
expect(typeof rank).toBe('string')
|
|
13
|
-
expect(() => LexoRank.parse(rank)).not.toThrow()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('falls back to LexoRank.min when parse fails', () => {
|
|
17
|
-
const rank = initialRank('not-a-rank', 'after')
|
|
18
|
-
expect(() => LexoRank.parse(rank)).not.toThrow()
|
|
19
|
-
})
|
|
20
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
import {LexoRank} from 'lexorank'
|
|
3
|
-
|
|
4
|
-
import {parseOrderRank} from '../parseOrderRank'
|
|
5
|
-
|
|
6
|
-
describe('parseOrderRank', () => {
|
|
7
|
-
it('parses valid lexorank strings', () => {
|
|
8
|
-
const valid = '0|10000o:'
|
|
9
|
-
const result = parseOrderRank(valid, LexoRank.min())
|
|
10
|
-
|
|
11
|
-
expect(result).toEqual(LexoRank.parse(valid))
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('returns fallback for non-string values', () => {
|
|
15
|
-
const fallback = LexoRank.max()
|
|
16
|
-
|
|
17
|
-
expect(parseOrderRank(1, fallback)).toBe(fallback)
|
|
18
|
-
expect(parseOrderRank(null, fallback)).toBe(fallback)
|
|
19
|
-
expect(parseOrderRank(undefined, fallback)).toBe(fallback)
|
|
20
|
-
expect(parseOrderRank({}, fallback)).toBe(fallback)
|
|
21
|
-
expect(parseOrderRank([], fallback)).toBe(fallback)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('returns fallback for invalid lexorank strings', () => {
|
|
25
|
-
const fallback = LexoRank.min()
|
|
26
|
-
|
|
27
|
-
expect(parseOrderRank('not-a-rank', fallback)).toBe(fallback)
|
|
28
|
-
expect(parseOrderRank('invalid', fallback)).toBe(fallback)
|
|
29
|
-
expect(parseOrderRank('', fallback)).toBe(fallback)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('respects different fallback values', () => {
|
|
33
|
-
const minFallback = LexoRank.min()
|
|
34
|
-
const maxFallback = LexoRank.max()
|
|
35
|
-
|
|
36
|
-
expect(parseOrderRank('invalid', minFallback)).toBe(minFallback)
|
|
37
|
-
expect(parseOrderRank('invalid', maxFallback)).toBe(maxFallback)
|
|
38
|
-
})
|
|
39
|
-
})
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
import {LexoRank} from 'lexorank'
|
|
3
|
-
|
|
4
|
-
import {SanityDocumentWithOrder} from '../../types'
|
|
5
|
-
import {ORDER_FIELD_NAME} from '../constants'
|
|
6
|
-
import {reorderDocuments} from '../reorderDocuments'
|
|
7
|
-
|
|
8
|
-
describe('reorderDocuments', () => {
|
|
9
|
-
it('handles non-string orderRank values without throwing', () => {
|
|
10
|
-
const entities: SanityDocumentWithOrder[] = [
|
|
11
|
-
{
|
|
12
|
-
_id: 'a',
|
|
13
|
-
_type: 'orderableCategory',
|
|
14
|
-
orderRank: '0|00000a:',
|
|
15
|
-
_createdAt: new Date().toISOString(),
|
|
16
|
-
_updatedAt: new Date().toISOString(),
|
|
17
|
-
_rev: '1',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
_id: 'b',
|
|
21
|
-
_type: 'orderableCategory',
|
|
22
|
-
orderRank: 1 as unknown as any,
|
|
23
|
-
_createdAt: new Date().toISOString(),
|
|
24
|
-
_updatedAt: new Date().toISOString(),
|
|
25
|
-
_rev: '1',
|
|
26
|
-
},
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
const action = () =>
|
|
30
|
-
reorderDocuments({
|
|
31
|
-
entities: [...entities],
|
|
32
|
-
selectedIds: ['b'],
|
|
33
|
-
source: {index: 1},
|
|
34
|
-
destination: {index: 0},
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
expect(action).not.toThrow()
|
|
38
|
-
|
|
39
|
-
const result = action()
|
|
40
|
-
const updatedRank = result.patches.find(([id]) => id === 'b')?.[1].set?.[ORDER_FIELD_NAME]
|
|
41
|
-
|
|
42
|
-
expect(typeof updatedRank).toBe('string')
|
|
43
|
-
expect(() => LexoRank.parse(updatedRank as string)).not.toThrow()
|
|
44
|
-
})
|
|
45
|
-
})
|
package/src/helpers/client.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import {type SanityClient, useClient, usePerspective} from 'sanity'
|
|
2
|
-
import {API_VERSION} from './constants'
|
|
3
|
-
|
|
4
|
-
export function useSanityClient(): SanityClient {
|
|
5
|
-
const {perspectiveStack} = usePerspective()
|
|
6
|
-
|
|
7
|
-
return useClient({apiVersion: API_VERSION}).withConfig({perspective: perspectiveStack})
|
|
8
|
-
}
|
package/src/helpers/constants.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {getPublishedId, getVersionFromId, isDraftId, isPublishedId, isVersionId} from 'sanity'
|
|
2
|
-
import {type SanityDocumentWithOrder} from '../types'
|
|
3
|
-
|
|
4
|
-
const isVersionForCurrentPerspective = (
|
|
5
|
-
document: SanityDocumentWithOrder,
|
|
6
|
-
perspectiveName: string,
|
|
7
|
-
publishedId: string,
|
|
8
|
-
) => {
|
|
9
|
-
return (
|
|
10
|
-
document._id &&
|
|
11
|
-
isVersionId(document._id) &&
|
|
12
|
-
getVersionFromId(document._id) === perspectiveName &&
|
|
13
|
-
getPublishedId(document._id) === publishedId
|
|
14
|
-
)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// this removes dedupped docs from the list and makes sure that it keeps the right docs
|
|
18
|
-
// in the list while preserving the order established by the orderRank field
|
|
19
|
-
export const getFilteredDedupedDocs = (
|
|
20
|
-
documents: SanityDocumentWithOrder[],
|
|
21
|
-
perspectiveName?: string,
|
|
22
|
-
): SanityDocumentWithOrder[] => {
|
|
23
|
-
// Flatten the documents array in case it's nested (like in test data)
|
|
24
|
-
const flatDocuments = documents.flat()
|
|
25
|
-
|
|
26
|
-
return flatDocuments.reduce<SanityDocumentWithOrder[]>((acc, cur) => {
|
|
27
|
-
if (!cur._id) {
|
|
28
|
-
return acc
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Handle version-only documents
|
|
32
|
-
if (isVersionId(cur._id)) {
|
|
33
|
-
const versionFromId = getVersionFromId(cur._id)
|
|
34
|
-
const isCorrectVersion = versionFromId === perspectiveName
|
|
35
|
-
|
|
36
|
-
// Only include versions that match the current perspective
|
|
37
|
-
if (
|
|
38
|
-
perspectiveName &&
|
|
39
|
-
perspectiveName !== 'drafts' &&
|
|
40
|
-
perspectiveName !== 'published' &&
|
|
41
|
-
isCorrectVersion
|
|
42
|
-
) {
|
|
43
|
-
return [...acc, cur]
|
|
44
|
-
}
|
|
45
|
-
return acc
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Handle published perspective - only include published documents
|
|
49
|
-
if (perspectiveName === 'published') {
|
|
50
|
-
if (isPublishedId(cur._id)) {
|
|
51
|
-
return [...acc, cur]
|
|
52
|
-
}
|
|
53
|
-
return acc
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// in situations where the document is not a draft, we need to check if
|
|
57
|
-
// the version should override a published document or a draft
|
|
58
|
-
if (!isDraftId(cur._id)) {
|
|
59
|
-
const publishedId = getPublishedId(cur._id)
|
|
60
|
-
|
|
61
|
-
const countNrPublished = JSON.stringify(flatDocuments).match(`/${publishedId}/g`)
|
|
62
|
-
|
|
63
|
-
// Check if there's a version that matches the perspectiveName
|
|
64
|
-
const hasMatchingVersion =
|
|
65
|
-
perspectiveName && perspectiveName !== 'drafts' && perspectiveName !== 'published'
|
|
66
|
-
? flatDocuments.some((doc) =>
|
|
67
|
-
isVersionForCurrentPerspective(doc, perspectiveName, publishedId),
|
|
68
|
-
)
|
|
69
|
-
: false
|
|
70
|
-
|
|
71
|
-
// Check if there's a draft
|
|
72
|
-
const hasDraft = flatDocuments.some((doc) => doc._id === `drafts.${cur._id}`)
|
|
73
|
-
|
|
74
|
-
// Priority: version > draft > published
|
|
75
|
-
// If there's a matching version, skip published
|
|
76
|
-
if (hasMatchingVersion) {
|
|
77
|
-
return acc
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
81
|
-
const alsoHasDraft = hasDraft || countNrPublished
|
|
82
|
-
return alsoHasDraft ? acc : [...acc, cur]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// For drafts, check if there's a version for this document in version perspective
|
|
86
|
-
if (perspectiveName && perspectiveName !== 'drafts' && perspectiveName !== 'published') {
|
|
87
|
-
const baseId = getPublishedId(cur._id)
|
|
88
|
-
const hasVersion = flatDocuments.some((doc) =>
|
|
89
|
-
isVersionForCurrentPerspective(doc, perspectiveName, baseId),
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
// If there's a version for this document, skip the draft
|
|
93
|
-
if (hasVersion) {
|
|
94
|
-
return acc
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Check if the draft has a published version
|
|
99
|
-
cur.hasPublished = flatDocuments.some((doc) => doc._id === cur._id.replace(`drafts.`, ``))
|
|
100
|
-
|
|
101
|
-
return [...acc, cur]
|
|
102
|
-
}, [])
|
|
103
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {LexoRank} from 'lexorank'
|
|
2
|
-
import {NewItemPosition} from '../types'
|
|
3
|
-
import {parseOrderRank} from './parseOrderRank'
|
|
4
|
-
|
|
5
|
-
// Use in initial value field by passing in the rank value of the last document
|
|
6
|
-
// If not value passed, generate a sensibly low rank
|
|
7
|
-
export function initialRank(
|
|
8
|
-
compareRankValue = ``,
|
|
9
|
-
newItemPosition: NewItemPosition = 'after',
|
|
10
|
-
): string {
|
|
11
|
-
const compareRank = parseOrderRank(compareRankValue, LexoRank.min())
|
|
12
|
-
const rank =
|
|
13
|
-
newItemPosition === 'before' ? compareRank.genPrev().genPrev() : compareRank.genNext().genNext()
|
|
14
|
-
|
|
15
|
-
return rank.toString()
|
|
16
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import {LexoRank} from 'lexorank'
|
|
2
|
-
|
|
3
|
-
// Safely parse a LexoRank string; fall back if invalid
|
|
4
|
-
export function parseOrderRank(value: unknown, fallback: LexoRank): LexoRank {
|
|
5
|
-
if (typeof value !== 'string') {
|
|
6
|
-
console.warn('[orderable-document-list] Invalid orderRank value (expected string):', value)
|
|
7
|
-
return fallback
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
return LexoRank.parse(value)
|
|
12
|
-
} catch (err) {
|
|
13
|
-
console.warn(
|
|
14
|
-
'[orderable-document-list] Failed to parse orderRank value:',
|
|
15
|
-
value,
|
|
16
|
-
'Error:',
|
|
17
|
-
err instanceof Error ? err.message : String(err),
|
|
18
|
-
)
|
|
19
|
-
return fallback
|
|
20
|
-
}
|
|
21
|
-
}
|
package/src/helpers/query.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import {ORDER_FIELD_NAME} from './constants'
|
|
2
|
-
|
|
3
|
-
export interface DocumentListQueryProps {
|
|
4
|
-
type: string
|
|
5
|
-
filter?: string
|
|
6
|
-
params?: Record<string, unknown>
|
|
7
|
-
currentVersion?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface DocumentListQueryResult {
|
|
11
|
-
query: string
|
|
12
|
-
queryParams: Record<string, string | number | boolean | string[]>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const DEFAULT_PARAMS = {}
|
|
16
|
-
|
|
17
|
-
export function getDocumentQuery({
|
|
18
|
-
type,
|
|
19
|
-
filter,
|
|
20
|
-
params = DEFAULT_PARAMS,
|
|
21
|
-
currentVersion,
|
|
22
|
-
}: DocumentListQueryProps): DocumentListQueryResult {
|
|
23
|
-
let perspectiveFilter = null
|
|
24
|
-
if (currentVersion === 'published') {
|
|
25
|
-
perspectiveFilter = '!(_id in path("drafts.**")) && !(_id in path("versions.**"))'
|
|
26
|
-
} else if (currentVersion === 'drafts') {
|
|
27
|
-
// Show drafts, and published when no draft exists
|
|
28
|
-
perspectiveFilter = `
|
|
29
|
-
(_id in path("drafts.**") || (!(_id in path("drafts.**")) && !(_id in path("versions.**"))))
|
|
30
|
-
`
|
|
31
|
-
} else {
|
|
32
|
-
// Default behavior: prioritize drafts over published when both exist
|
|
33
|
-
// the priority should be a version
|
|
34
|
-
perspectiveFilter = `(sanity::partOfRelease($currentVersion) || (!(_id in path("drafts.**")) && !(_id in path("versions.**"))) || (_id in path("drafts.**")))`
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const querySelect = `*[_type == $type ${perspectiveFilter ? `&& ${perspectiveFilter}` : ''}${filter ? `&& ${filter}` : ''}]`
|
|
38
|
-
const queryOrder = `|order(@[$order] asc)`
|
|
39
|
-
const queryFields = `{_id, _type, ${ORDER_FIELD_NAME}}`
|
|
40
|
-
|
|
41
|
-
const query = `${querySelect}${queryOrder}${queryFields}`
|
|
42
|
-
const queryParams = {
|
|
43
|
-
...params,
|
|
44
|
-
type,
|
|
45
|
-
order: ORDER_FIELD_NAME,
|
|
46
|
-
...(currentVersion && {currentVersion}),
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return {query, queryParams}
|
|
50
|
-
}
|