@sanity/orderable-document-list 0.0.10 → 1.0.0-v3-studio.2

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