@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,840 @@
1
+ import {LexoRank as $jPEKE$LexoRank} from "lexorank";
2
+ import {SortIcon as $jPEKE$SortIcon, GenerateIcon as $jPEKE$GenerateIcon, DragHandleIcon as $jPEKE$DragHandleIcon, ChevronUpIcon as $jPEKE$ChevronUpIcon, ChevronDownIcon as $jPEKE$ChevronDownIcon} from "@sanity/icons";
3
+ import {jsx as $jPEKE$jsx, jsxs as $jPEKE$jsxs, Fragment as $jPEKE$Fragment} from "react/jsx-runtime";
4
+ import $jPEKE$react, {Component as $jPEKE$Component, useEffect as $jPEKE$useEffect, useMemo as $jPEKE$useMemo, useState as $jPEKE$useState, useCallback as $jPEKE$useCallback, useContext as $jPEKE$useContext} from "react";
5
+ import {useToast as $jPEKE$useToast, Flex as $jPEKE$Flex, Spinner as $jPEKE$Spinner, Stack as $jPEKE$Stack, Box as $jPEKE$Box, Card as $jPEKE$Card, Text as $jPEKE$Text, Button as $jPEKE$Button} from "@sanity/ui";
6
+ import {useSchema as $jPEKE$useSchema, useClient as $jPEKE$useClient} from "sanity";
7
+ import {DragDropContext as $jPEKE$DragDropContext, Droppable as $jPEKE$Droppable, Draggable as $jPEKE$Draggable} from "react-beautiful-dnd";
8
+ import {usePaneRouter as $jPEKE$usePaneRouter} from "sanity/desk";
9
+ import {SanityPreview as $jPEKE$SanityPreview} from "sanity/_unstable";
10
+
11
+ const $21d4b1fe36f88c6f$export$64f27603cb09ba16 = `orderRank`;
12
+
13
+
14
+
15
+ function $27620c24e1768bdb$export$2e2bcd8739ae039(lastRankValue = ``) {
16
+ const lastRank = lastRankValue ? (0, $jPEKE$LexoRank).parse(lastRankValue) : (0, $jPEKE$LexoRank).min();
17
+ const nextRank = lastRank.genNext().genNext();
18
+ return nextRank.value;
19
+ }
20
+
21
+
22
+ const $ab48bff482731fc9$var$subscriptions = {};
23
+ function $ab48bff482731fc9$export$59b6ebc56d192aaa(context) {
24
+ ($ab48bff482731fc9$var$subscriptions[$ab48bff482731fc9$var$clientKey(context)] ?? []).forEach((subscriber)=>subscriber(context.client));
25
+ }
26
+ function $ab48bff482731fc9$export$a2a87dc3ab91967(context, callback) {
27
+ const key = $ab48bff482731fc9$var$clientKey(context);
28
+ const existing = $ab48bff482731fc9$var$subscriptions[key] ?? [];
29
+ $ab48bff482731fc9$var$subscriptions[key] = [
30
+ ...existing,
31
+ callback
32
+ ];
33
+ }
34
+ function $ab48bff482731fc9$var$clientKey(context) {
35
+ return `${context.projectId}:${context.dataset}`;
36
+ }
37
+
38
+
39
+ const $0413292d5e32b5d9$export$64a609a9111ff100 = (config)=>{
40
+ if (!config?.type || !config.context) throw new Error(`
41
+ type and context must be provided. context is available when configuring schema.
42
+ Example: orderRankField({type: 'category', context})
43
+ `);
44
+ const { type: type } = config;
45
+ let client;
46
+ (0, $ab48bff482731fc9$export$a2a87dc3ab91967)(config.context, (updatedClient)=>{
47
+ client = updatedClient;
48
+ });
49
+ return {
50
+ title: "Order Rank",
51
+ readOnly: true,
52
+ hidden: true,
53
+ ...config,
54
+ name: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16),
55
+ type: "string",
56
+ initialValue: async ()=>{
57
+ const lastDocOrderRank = await client?.fetch(`*[_type == $type]|order(@[$order] desc)[0][$order]`, {
58
+ type: type,
59
+ order: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)
60
+ });
61
+ return (0, $27620c24e1768bdb$export$2e2bcd8739ae039)(lastDocOrderRank);
62
+ }
63
+ };
64
+ };
65
+
66
+
67
+
68
+ const $e83e0ebbc2cf37df$export$db2ff2f898748a67 = {
69
+ title: "Ordered",
70
+ name: "ordered",
71
+ by: [
72
+ {
73
+ field: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16),
74
+ direction: "asc"
75
+ }
76
+ ]
77
+ };
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+ const $69dfcc58d43c2b6d$export$2a2017d0ec5437fa = (0, $jPEKE$react).createContext({});
103
+
104
+
105
+ function $2e8241e9842bdebe$export$2e2bcd8739ae039({ doc: doc , increment: increment , entities: entities , handleSelect: handleSelect , index: index , isFirst: isFirst , isLast: isLast }) {
106
+ const { showIncrements: showIncrements } = (0, $jPEKE$useContext)((0, $69dfcc58d43c2b6d$export$2a2017d0ec5437fa));
107
+ const schema = (0, $jPEKE$useSchema)();
108
+ return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Flex), {
109
+ align: "center",
110
+ children: [
111
+ /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Box), {
112
+ paddingX: 3,
113
+ style: {
114
+ flexShrink: 0
115
+ },
116
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Text), {
117
+ size: 4,
118
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$DragHandleIcon), {})
119
+ })
120
+ }),
121
+ showIncrements && /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Flex), {
122
+ style: {
123
+ flexShrink: 0
124
+ },
125
+ align: "center",
126
+ gap: 1,
127
+ paddingRight: 1,
128
+ children: [
129
+ /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Button), {
130
+ padding: 2,
131
+ mode: "ghost",
132
+ onClick: ()=>increment(index, index + -1, doc._id, entities),
133
+ disabled: isFirst,
134
+ icon: (0, $jPEKE$ChevronUpIcon)
135
+ }),
136
+ /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Button), {
137
+ padding: 2,
138
+ mode: "ghost",
139
+ disabled: isLast,
140
+ onClick: ()=>increment(index, index + 1, doc._id, entities),
141
+ icon: (0, $jPEKE$ChevronDownIcon)
142
+ })
143
+ ]
144
+ }),
145
+ /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Button), {
146
+ style: {
147
+ width: `100%`
148
+ },
149
+ padding: 2,
150
+ mode: "bleed",
151
+ onClick: (e)=>handleSelect(doc._id, index, e.nativeEvent),
152
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Flex), {
153
+ flex: 1,
154
+ align: "center",
155
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Box), {
156
+ flex: 1,
157
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$SanityPreview), {
158
+ layout: "default",
159
+ value: doc,
160
+ schemaType: schema.get(doc._type)
161
+ })
162
+ })
163
+ })
164
+ })
165
+ ]
166
+ });
167
+ }
168
+
169
+
170
+
171
+
172
+ function $793aacd9a77a8bc3$var$lexicographicalSort(a, b) {
173
+ if (a[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16] < b[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]) return -1;
174
+ if (a[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16] > b[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]) return 1;
175
+ return 0;
176
+ }
177
+ const $793aacd9a77a8bc3$export$1b86f2c90605ffb9 = ({ entities: entities , selectedIds: selectedIds , source: source , destination: destination , debug: debug = false })=>{
178
+ const startIndex = source.index;
179
+ const endIndex = destination.index;
180
+ const isMovingUp = startIndex > endIndex;
181
+ const selectedItems = entities.filter((item)=>selectedIds.includes(item._id));
182
+ const message = [
183
+ `Moved`,
184
+ selectedItems.length === 1 ? `1 Document` : `${selectedItems.length} Documents`,
185
+ isMovingUp ? `up` : `down`,
186
+ `from position`,
187
+ `${startIndex + 1} to ${endIndex + 1}`,
188
+ ].join(" ");
189
+ const { all: all , selected: selected } = entities.reduce((acc, cur, curIndex)=>{
190
+ // Selected items get spread in below, so skip them here
191
+ if (selectedIds.includes(cur._id)) return {
192
+ all: acc.all,
193
+ selected: acc.selected
194
+ };
195
+ // Drop seleced items in
196
+ if (curIndex === endIndex) {
197
+ const prevIndex = curIndex - 1;
198
+ const prevRank = entities[prevIndex]?.[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16] ? (0, $jPEKE$LexoRank).parse(entities[prevIndex]?.[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]) : (0, $jPEKE$LexoRank).min();
199
+ const curRank = (0, $jPEKE$LexoRank).parse(entities[curIndex][0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]);
200
+ const nextIndex = curIndex + 1;
201
+ const nextRank = entities[nextIndex]?.[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16] ? (0, $jPEKE$LexoRank).parse(entities[nextIndex]?.[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]) : (0, $jPEKE$LexoRank).max();
202
+ let betweenRank = isMovingUp ? prevRank.between(curRank) : curRank.between(nextRank);
203
+ // For each selected item, assign a new orderRank between now and next
204
+ for(let selectedIndex = 0; selectedIndex < selectedItems.length; selectedIndex += 1){
205
+ selectedItems[selectedIndex][0, $21d4b1fe36f88c6f$export$64f27603cb09ba16] = betweenRank.value;
206
+ betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank);
207
+ }
208
+ return {
209
+ // The `all` array gets sorted by order field later anyway
210
+ // so that this probably isn't necessary ¯\_(ツ)_/¯
211
+ all: isMovingUp ? [
212
+ ...acc.all,
213
+ ...selectedItems,
214
+ cur
215
+ ] : [
216
+ ...acc.all,
217
+ cur,
218
+ ...selectedItems
219
+ ],
220
+ selected: selectedItems
221
+ };
222
+ }
223
+ return {
224
+ all: [
225
+ ...acc.all,
226
+ cur
227
+ ],
228
+ selected: acc.selected
229
+ };
230
+ }, {
231
+ all: [],
232
+ selected: []
233
+ });
234
+ const patches = selected.map((doc)=>{
235
+ return [
236
+ doc._id,
237
+ {
238
+ set: {
239
+ [(0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)]: doc[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]
240
+ }
241
+ },
242
+ ];
243
+ });
244
+ // Safety-check to make sure everything is in order
245
+ const allSorted = all.sort($793aacd9a77a8bc3$var$lexicographicalSort);
246
+ return {
247
+ newOrder: allSorted,
248
+ patches: patches,
249
+ message: message
250
+ };
251
+ };
252
+
253
+
254
+
255
+
256
+
257
+ function $f49f7a30883dbc1b$export$8d49af9be9632eba() {
258
+ const baseClient = (0, $jPEKE$useClient)();
259
+ return (0, $jPEKE$useMemo)(()=>baseClient.withConfig({
260
+ apiVersion: "2021-09-01"
261
+ }), [
262
+ baseClient
263
+ ]);
264
+ }
265
+
266
+
267
+ const $e1f104d9525f6d72$var$getItemStyle = (draggableStyle, itemIsUpdating)=>({
268
+ userSelect: "none",
269
+ transition: `opacity 500ms ease-in-out`,
270
+ opacity: itemIsUpdating ? 0.2 : 1,
271
+ pointerEvents: itemIsUpdating ? `none` : undefined,
272
+ ...draggableStyle
273
+ });
274
+ const $e1f104d9525f6d72$var$cardTone = (settings)=>{
275
+ const { isDuplicate: isDuplicate , isGhosting: isGhosting , isDragging: isDragging , isSelected: isSelected } = settings;
276
+ if (isGhosting) return `transparent`;
277
+ if (isDragging || isSelected) return `primary`;
278
+ if (isDuplicate) return `caution`;
279
+ return undefined;
280
+ };
281
+ function $e1f104d9525f6d72$export$2e2bcd8739ae039({ data: data , type: type , listIsUpdating: listIsUpdating , setListIsUpdating: setListIsUpdating }) {
282
+ const toast = (0, $jPEKE$useToast)();
283
+ const router = (0, $jPEKE$usePaneRouter)();
284
+ const { navigateIntent: navigateIntent } = router;
285
+ // Maintains local state order before transaction completes
286
+ const [orderedData, setOrderedData] = (0, $jPEKE$useState)(data);
287
+ // Update local state when documents change from an outside source
288
+ (0, $jPEKE$useEffect)(()=>{
289
+ if (!listIsUpdating) setOrderedData(data);
290
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [
291
+ data
292
+ ]);
293
+ const [draggingId, setDraggingId] = (0, $jPEKE$useState)(``);
294
+ const [selectedIds, setSelectedIds] = (0, $jPEKE$useState)([]);
295
+ const clearSelected = (0, $jPEKE$useCallback)(()=>setSelectedIds([]), [
296
+ setSelectedIds
297
+ ]);
298
+ const handleSelect = (0, $jPEKE$useCallback)((clickedId, index, nativeEvent)=>{
299
+ const isSelected = selectedIds.includes(clickedId);
300
+ const selectMultiple = nativeEvent.shiftKey;
301
+ const isUsingWindows = navigator.appVersion.indexOf("Win") !== -1;
302
+ const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey;
303
+ let updatedIds = [];
304
+ // No modifier keys pressed during click:
305
+ // - update selected to just this one
306
+ // - open document
307
+ if (!selectMultiple && !selectAdditional) {
308
+ navigateIntent("edit", {
309
+ id: clickedId,
310
+ type: type
311
+ });
312
+ return setSelectedIds([
313
+ clickedId
314
+ ]);
315
+ }
316
+ // Shift key was held, add id's between last selected and this one
317
+ // ...before adding this one
318
+ if (selectMultiple && !isSelected) {
319
+ const lastSelectedId = selectedIds[selectedIds.length - 1];
320
+ const lastSelectedIndex = orderedData.findIndex((item)=>item._id === lastSelectedId);
321
+ const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex;
322
+ const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex;
323
+ const betweenIds = orderedData.filter((item, itemIndex)=>itemIndex > firstSelected && itemIndex < lastSelected).map((item)=>item._id);
324
+ updatedIds = [
325
+ ...selectedIds,
326
+ ...betweenIds,
327
+ clickedId
328
+ ];
329
+ } else if (isSelected) // Toggle off a single id
330
+ updatedIds = selectedIds.filter((id)=>id !== clickedId);
331
+ else // Toggle on a single id
332
+ updatedIds = [
333
+ ...selectedIds,
334
+ clickedId
335
+ ];
336
+ return setSelectedIds(updatedIds);
337
+ }, [
338
+ setSelectedIds,
339
+ navigateIntent,
340
+ orderedData,
341
+ selectedIds,
342
+ type
343
+ ]);
344
+ const client = (0, $f49f7a30883dbc1b$export$8d49af9be9632eba)();
345
+ const transactPatches = (0, $jPEKE$useCallback)(async (patches, message)=>{
346
+ const transaction = client.transaction();
347
+ patches.forEach(([docId, ops])=>transaction.patch(docId, ops));
348
+ await transaction.commit().then((updated)=>{
349
+ clearSelected();
350
+ setDraggingId(``);
351
+ setListIsUpdating(false);
352
+ toast.push({
353
+ title: `${updated.results.length === 1 ? `1 Document` : `${updated.results.length} Documents`} Reordered`,
354
+ status: `success`,
355
+ description: message
356
+ });
357
+ }).catch(()=>{
358
+ setDraggingId(``);
359
+ setListIsUpdating(false);
360
+ toast.push({
361
+ title: `Reordering failed`,
362
+ status: `error`
363
+ });
364
+ });
365
+ }, [
366
+ client,
367
+ setDraggingId,
368
+ clearSelected,
369
+ setListIsUpdating,
370
+ toast
371
+ ]);
372
+ const handleDragEnd = (0, $jPEKE$useCallback)((result, entities)=>{
373
+ setDraggingId(``);
374
+ const { source: source , destination: destination , draggableId: draggableId } = result ?? {};
375
+ // Don't do anything if nothing changed
376
+ if (source?.index === destination?.index) return;
377
+ // Don't do anything if we don't have the entitites
378
+ if (!entities?.length || !draggableId) return;
379
+ // A document can be dragged without being one-of-many-selected
380
+ const effectedIds = selectedIds?.length ? selectedIds : [
381
+ draggableId
382
+ ];
383
+ // Don't do anything if we don't have ids to effect
384
+ if (!effectedIds?.length) return;
385
+ // Update state to update styles + prevent data refetching
386
+ setListIsUpdating(true);
387
+ setSelectedIds(effectedIds);
388
+ const { newOrder: newOrder , patches: patches , message: message } = (0, $793aacd9a77a8bc3$export$1b86f2c90605ffb9)({
389
+ entities: entities,
390
+ selectedIds: effectedIds,
391
+ source: source,
392
+ destination: destination
393
+ });
394
+ // Update local state
395
+ if (newOrder?.length) setOrderedData(newOrder);
396
+ // Transact new order patches
397
+ if (patches?.length) transactPatches(patches, message);
398
+ }, [
399
+ selectedIds,
400
+ setDraggingId,
401
+ setSelectedIds,
402
+ transactPatches,
403
+ setListIsUpdating
404
+ ]);
405
+ const handleDragStart = (0, $jPEKE$useCallback)((start)=>{
406
+ const id = start.draggableId;
407
+ const selected = selectedIds.includes(id);
408
+ // if dragging an item that is not selected - unselect all items
409
+ if (!selected) clearSelected();
410
+ setDraggingId(id);
411
+ }, [
412
+ selectedIds,
413
+ clearSelected,
414
+ setDraggingId
415
+ ]);
416
+ // Move one document up or down one place, by fake invoking the drag function
417
+ const incrementIndex = (0, $jPEKE$useCallback)((shiftFrom, shiftTo, id, entities)=>{
418
+ const result = {
419
+ draggableId: id,
420
+ source: {
421
+ index: shiftFrom
422
+ },
423
+ destination: {
424
+ index: shiftTo
425
+ }
426
+ };
427
+ return handleDragEnd(result, entities);
428
+ }, [
429
+ handleDragEnd
430
+ ]);
431
+ const onWindowKeyDown = (0, $jPEKE$useCallback)((event)=>{
432
+ if (event.key === "Escape") clearSelected();
433
+ }, [
434
+ clearSelected
435
+ ]);
436
+ (0, $jPEKE$useEffect)(()=>{
437
+ window.addEventListener("keydown", onWindowKeyDown);
438
+ return ()=>{
439
+ window.removeEventListener("keydown", onWindowKeyDown);
440
+ };
441
+ }, [
442
+ onWindowKeyDown
443
+ ]);
444
+ // Find all items with duplicate order field
445
+ const duplicateOrders = (0, $jPEKE$useMemo)(()=>{
446
+ if (!orderedData.length) return [];
447
+ const orderField = orderedData.map((item)=>item[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]);
448
+ return orderField.filter((item, index)=>orderField.indexOf(item) !== index);
449
+ }, [
450
+ orderedData
451
+ ]);
452
+ const onDragEnd = (0, $jPEKE$useCallback)((result)=>handleDragEnd(result, orderedData), [
453
+ orderedData,
454
+ handleDragEnd
455
+ ]);
456
+ return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$DragDropContext), {
457
+ onDragStart: handleDragStart,
458
+ onDragEnd: onDragEnd,
459
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Droppable), {
460
+ droppableId: "documentSortZone",
461
+ children: (provided)=>/*#__PURE__*/ (0, $jPEKE$jsxs)("div", {
462
+ ...provided.droppableProps,
463
+ ref: provided.innerRef,
464
+ children: [
465
+ orderedData.map((item, index)=>/*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Draggable), {
466
+ draggableId: item._id,
467
+ index: index,
468
+ children: (innerProvided, innerSnapshot)=>{
469
+ const isSelected = selectedIds.includes(item._id);
470
+ const isDragging = innerSnapshot.isDragging;
471
+ const isGhosting = Boolean(!isDragging && draggingId && isSelected);
472
+ const isUpdating = listIsUpdating && isSelected;
473
+ const isDisabled = Boolean(!item[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]);
474
+ const isDuplicate = duplicateOrders.includes(item[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]);
475
+ const tone = $e1f104d9525f6d72$var$cardTone({
476
+ isDuplicate: isDuplicate,
477
+ isGhosting: isGhosting,
478
+ isDragging: isDragging,
479
+ isSelected: isSelected
480
+ });
481
+ return /*#__PURE__*/ (0, $jPEKE$jsx)("div", {
482
+ ref: innerProvided.innerRef,
483
+ ...innerProvided.draggableProps,
484
+ ...innerProvided.dragHandleProps,
485
+ style: isDisabled ? {
486
+ opacity: 0.2,
487
+ pointerEvents: `none`
488
+ } : $e1f104d9525f6d72$var$getItemStyle(innerProvided.draggableProps.style, isUpdating),
489
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Box), {
490
+ paddingBottom: 1,
491
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Card), {
492
+ tone: tone,
493
+ shadow: isDragging ? 2 : undefined,
494
+ radius: 2,
495
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $2e8241e9842bdebe$export$2e2bcd8739ae039), {
496
+ doc: item,
497
+ entities: orderedData,
498
+ handleSelect: handleSelect,
499
+ increment: incrementIndex,
500
+ index: index,
501
+ isFirst: index === 0,
502
+ isLast: index === orderedData.length - 1
503
+ })
504
+ })
505
+ })
506
+ });
507
+ }
508
+ }, `${item._id}-${item[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]}`)),
509
+ provided.placeholder
510
+ ]
511
+ })
512
+ })
513
+ });
514
+ }
515
+
516
+
517
+
518
+
519
+
520
+
521
+ function $60d135b0057fb272$export$2e2bcd8739ae039({ children: children }) {
522
+ return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Box), {
523
+ padding: 3,
524
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Card), {
525
+ padding: 4,
526
+ radius: 2,
527
+ shadow: 1,
528
+ tone: "caution",
529
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Text), {
530
+ children: children
531
+ })
532
+ })
533
+ });
534
+ }
535
+
536
+
537
+
538
+ const $5e43324e27157fbc$var$DEFAULT_PARAMS = {};
539
+ function $5e43324e27157fbc$export$2e2bcd8739ae039({ type: type , filter: filter , params: params = $5e43324e27157fbc$var$DEFAULT_PARAMS }) {
540
+ const [isLoading, setIsLoading] = (0, $jPEKE$useState)(true);
541
+ const [listIsUpdating, setListIsUpdating] = (0, $jPEKE$useState)(false);
542
+ const [data, setData] = (0, $jPEKE$useState)([]);
543
+ const client = (0, $f49f7a30883dbc1b$export$8d49af9be9632eba)();
544
+ (0, $jPEKE$useEffect)(()=>{
545
+ const query = `*[_type == $type ${filter ? `&& ${filter}` : ""}]|order(@[$order] asc){
546
+ _id, _type, ${(0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)}
547
+ }`;
548
+ const queryParams = Object.assign(params, {
549
+ type: type,
550
+ order: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)
551
+ });
552
+ let subscription;
553
+ // eslint-disable-next-line require-await
554
+ const fetchData = async ()=>{
555
+ client.fetch(query, queryParams).then((documents)=>{
556
+ // Remove published document from list if draft also exists
557
+ const filteredDocuments = documents.reduce((acc, cur)=>{
558
+ if (!cur._id.startsWith(`drafts.`)) {
559
+ // eslint-disable-next-line max-nested-callbacks
560
+ const alsoHasDraft = documents.some((doc)=>doc._id === `drafts.${cur._id}`);
561
+ return alsoHasDraft ? acc : [
562
+ ...acc,
563
+ cur
564
+ ];
565
+ }
566
+ return [
567
+ ...acc,
568
+ cur
569
+ ];
570
+ }, []);
571
+ setData(filteredDocuments);
572
+ if (isLoading) setIsLoading(false);
573
+ });
574
+ };
575
+ const prepareData = async ()=>{
576
+ setIsLoading(true);
577
+ await fetchData();
578
+ if (!subscription) subscription = client.listen(query, queryParams).subscribe(()=>fetchData());
579
+ };
580
+ // Get data but only if a document isn't being patched or we don't yet have data
581
+ if (!listIsUpdating && !data.length) prepareData();
582
+ return ()=>subscription?.unsubscribe();
583
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [
584
+ type
585
+ ]);
586
+ const unorderedDataCount = (0, $jPEKE$useMemo)(()=>data.length ? data.filter((doc)=>!doc[0, $21d4b1fe36f88c6f$export$64f27603cb09ba16]).length : 0, [
587
+ data
588
+ ]);
589
+ if (isLoading) return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Flex), {
590
+ style: {
591
+ width: `100%`,
592
+ height: `100%`
593
+ },
594
+ align: "center",
595
+ justify: "center",
596
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Spinner), {})
597
+ });
598
+ return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Stack), {
599
+ space: 1,
600
+ style: {
601
+ overflow: `scroll`,
602
+ height: `100%`
603
+ },
604
+ children: [
605
+ unorderedDataCount > 0 && /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $60d135b0057fb272$export$2e2bcd8739ae039), {
606
+ children: [
607
+ unorderedDataCount,
608
+ "/",
609
+ data.length,
610
+ " Documents have no Order. Select",
611
+ " ",
612
+ /*#__PURE__*/ (0, $jPEKE$jsx)("strong", {
613
+ children: "Reset Order"
614
+ }),
615
+ " from the Menu above to fix."
616
+ ]
617
+ }),
618
+ /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Box), {
619
+ padding: 1,
620
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $e1f104d9525f6d72$export$2e2bcd8739ae039), {
621
+ data: data,
622
+ type: type,
623
+ listIsUpdating: listIsUpdating,
624
+ setListIsUpdating: setListIsUpdating
625
+ })
626
+ })
627
+ ]
628
+ });
629
+ }
630
+
631
+
632
+
633
+
634
+
635
+ function $c3ce662734af156c$export$2e2bcd8739ae039({ type: type , showIncrements: showIncrements , resetOrderTransaction: resetOrderTransaction , filter: filter , params: params }) {
636
+ const toast = (0, $jPEKE$useToast)();
637
+ const schema = (0, $jPEKE$useSchema)();
638
+ (0, $jPEKE$useEffect)(()=>{
639
+ if (resetOrderTransaction?.title && resetOrderTransaction?.status) toast.push(resetOrderTransaction);
640
+ }, [
641
+ resetOrderTransaction,
642
+ toast
643
+ ]);
644
+ const schemaIsInvalid = (0, $jPEKE$useMemo)(()=>{
645
+ // Option not passed
646
+ if (!type) return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Fragment), {
647
+ children: [
648
+ "No ",
649
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
650
+ children: "type"
651
+ }),
652
+ " was configured"
653
+ ]
654
+ });
655
+ const typeSchema = schema.get(type);
656
+ // Schema not found
657
+ if (!typeSchema) return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Fragment), {
658
+ children: [
659
+ "Schema ",
660
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
661
+ children: type
662
+ }),
663
+ " not found"
664
+ ]
665
+ });
666
+ // Schema lacks an order field
667
+ if (!("fields" in typeSchema) || !typeSchema.fields.some((field)=>field?.name === (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16))) return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Fragment), {
668
+ children: [
669
+ "Schema ",
670
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
671
+ children: type
672
+ }),
673
+ " must have an ",
674
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
675
+ children: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)
676
+ }),
677
+ " field of type",
678
+ " ",
679
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
680
+ children: "string"
681
+ })
682
+ ]
683
+ });
684
+ // Schema's order field is not a string
685
+ if ("fields" in typeSchema && typeSchema.fields.some((field)=>field?.name === (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16) && field?.type?.name !== "string")) return /*#__PURE__*/ (0, $jPEKE$jsxs)((0, $jPEKE$Fragment), {
686
+ children: [
687
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
688
+ children: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)
689
+ }),
690
+ " field on Schema ",
691
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
692
+ children: type
693
+ }),
694
+ " must be",
695
+ " ",
696
+ /*#__PURE__*/ (0, $jPEKE$jsx)("code", {
697
+ children: "string"
698
+ }),
699
+ " type"
700
+ ]
701
+ });
702
+ return "";
703
+ }, [
704
+ type,
705
+ schema
706
+ ]);
707
+ if (schemaIsInvalid) return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $60d135b0057fb272$export$2e2bcd8739ae039), {
708
+ children: schemaIsInvalid
709
+ });
710
+ return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $69dfcc58d43c2b6d$export$2a2017d0ec5437fa).Provider, {
711
+ value: {
712
+ showIncrements: showIncrements
713
+ },
714
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $5e43324e27157fbc$export$2e2bcd8739ae039), {
715
+ type: type,
716
+ filter: filter,
717
+ params: params
718
+ })
719
+ });
720
+ }
721
+
722
+
723
+
724
+
725
+ async function $813ed27cf8814dcd$export$ee841d674ca80db0(type = ``, client) {
726
+ const query = `*[_type == $type]|order(@[$order] asc)._id`;
727
+ const queryParams = {
728
+ type: type,
729
+ order: (0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)
730
+ };
731
+ const documents = await client.fetch(query, queryParams);
732
+ if (!documents.length) return null;
733
+ const transaction = client.transaction();
734
+ let aLexoRank = (0, $jPEKE$LexoRank).min();
735
+ for(let index = 0; index < documents.length; index += 1){
736
+ // Generate next rank before even the first document so there's room to move!
737
+ aLexoRank = aLexoRank.genNext().genNext();
738
+ transaction.patch(documents[index], {
739
+ set: {
740
+ [(0, $21d4b1fe36f88c6f$export$64f27603cb09ba16)]: aLexoRank.value
741
+ }
742
+ });
743
+ }
744
+ return transaction.commit().then((update)=>update).catch((err)=>err);
745
+ }
746
+
747
+
748
+ class $c149fdd435bcc1b3$export$2e2bcd8739ae039 extends (0, $jPEKE$Component) {
749
+ constructor(props){
750
+ super(props);
751
+ this.state = {
752
+ showIncrements: false,
753
+ resetOrderTransaction: {}
754
+ };
755
+ }
756
+ actionHandlers = {
757
+ showIncrements: ()=>{
758
+ this.setState((state)=>({
759
+ showIncrements: !state.showIncrements
760
+ }));
761
+ },
762
+ resetOrder: async ()=>{
763
+ this.setState(()=>({
764
+ resetOrderTransaction: {
765
+ status: `info`,
766
+ title: `Reordering started...`,
767
+ closable: true
768
+ }
769
+ }));
770
+ const update = await (0, $813ed27cf8814dcd$export$ee841d674ca80db0)(this.props.options.type, this.props.options.client);
771
+ const reorderWasSuccessful = update?.results?.length;
772
+ this.setState(()=>({
773
+ resetOrderTransaction: {
774
+ status: reorderWasSuccessful ? `success` : `info`,
775
+ title: reorderWasSuccessful ? `Reordered ${update.results.length === 1 ? `Document` : `Documents`}` : `Reordering failed`,
776
+ closable: true
777
+ }
778
+ }));
779
+ }
780
+ };
781
+ render() {
782
+ const type = this?.props?.options?.type;
783
+ if (!type) return null;
784
+ return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $c3ce662734af156c$export$2e2bcd8739ae039), {
785
+ filter: this?.props?.options?.filter,
786
+ params: this?.props?.options?.params,
787
+ type: type,
788
+ showIncrements: this.state.showIncrements,
789
+ resetOrderTransaction: this.state.resetOrderTransaction
790
+ });
791
+ }
792
+ }
793
+
794
+
795
+
796
+ function $24abac83e7f53d60$export$3b014deba4b8ca00(config) {
797
+ if (!config?.type || !config.context || !config.S) throw new Error(`
798
+ type, context and S (StructureBuilder) must be provided.
799
+ context and S are available when configuring structure.
800
+ Example: orderableDocumentListDeskItem({type: 'category'})
801
+ `);
802
+ const { type: type , filter: filter , params: params , title: title , icon: icon , id: id , context: context , S: S } = config;
803
+ const { schema: schema , client: client } = context;
804
+ // workaround so schemas can get access to client in callbacks
805
+ (0, $ab48bff482731fc9$export$59b6ebc56d192aaa)(context);
806
+ const listTitle = title ?? `Orderable ${type}`;
807
+ const listId = id ?? `orderable-${type}`;
808
+ const listIcon = icon ?? (0, $jPEKE$SortIcon);
809
+ const typeTitle = schema.get(type)?.title ?? type;
810
+ return S.listItem().title(listTitle).id(listId).icon(listIcon).child(Object.assign(S.documentTypeList(type).serialize(), {
811
+ // Prevents the component from re-rendering when switching documents
812
+ __preserveInstance: true,
813
+ // Prevents the component from NOT re-rendering when switching listItems
814
+ key: listId,
815
+ type: "component",
816
+ component: (0, $c149fdd435bcc1b3$export$2e2bcd8739ae039),
817
+ options: {
818
+ type: type,
819
+ filter: filter,
820
+ params: params,
821
+ client: client
822
+ },
823
+ menuItems: [
824
+ S.menuItem().title(`Create new ${typeTitle}`).intent({
825
+ type: "create",
826
+ params: {
827
+ type: type
828
+ }
829
+ }).serialize(),
830
+ S.menuItem().title(`Reset Order`).icon((0, $jPEKE$GenerateIcon)).action(`resetOrder`).serialize(),
831
+ S.menuItem().title(`Show Increments`).icon((0, $jPEKE$SortIcon)).action(`showIncrements`).serialize(),
832
+ ]
833
+ })).serialize();
834
+ }
835
+
836
+
837
+
838
+
839
+ export {$0413292d5e32b5d9$export$64a609a9111ff100 as orderRankField, $e83e0ebbc2cf37df$export$db2ff2f898748a67 as orderRankOrdering, $24abac83e7f53d60$export$3b014deba4b8ca00 as orderableDocumentListDeskItem};
840
+ //# sourceMappingURL=index.modern.js.map