@sanity/orderable-document-list 1.2.2 → 1.3.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/LICENSE +1 -1
- package/lib/index.cjs +499 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +36 -0
- package/lib/index.d.ts +5 -13
- package/lib/index.js +428 -712
- package/lib/index.js.map +1 -1
- package/package.json +41 -40
- package/src/Document.tsx +4 -4
- package/src/DocumentListQuery.tsx +7 -9
- package/src/DocumentListWrapper.tsx +4 -5
- package/src/DraggableList.tsx +41 -44
- package/src/OrderableContext.ts +2 -2
- package/src/OrderableDocumentList.tsx +3 -3
- package/src/desk-structure/orderableDocumentListDeskItem.ts +5 -5
- package/src/fields/orderRankField.ts +10 -9
- package/src/fields/orderRankOrdering.ts +1 -1
- package/src/helpers/client.ts +2 -2
- package/src/helpers/initialRank.ts +2 -2
- package/src/helpers/reorderDocuments.ts +8 -8
- package/src/helpers/resetOrder.ts +17 -12
- package/lib/index.esm.js +0 -778
- package/lib/index.esm.js.map +0 -1
package/lib/index.esm.js
DELETED
|
@@ -1,778 +0,0 @@
|
|
|
1
|
-
import { defineField, useSchema, PreviewCard, Preview, useClient } from 'sanity';
|
|
2
|
-
import { LexoRank } from 'lexorank';
|
|
3
|
-
import { DragHandleIcon, ChevronUpIcon, ChevronDownIcon, GenerateIcon, SortIcon } from '@sanity/icons';
|
|
4
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
-
import React, { useContext, useMemo, useState, useEffect, useCallback, Component } from 'react';
|
|
6
|
-
import { Flex, Box, Text, Button, Card, AvatarCounter, useToast, Spinner, Container, Stack } from '@sanity/ui';
|
|
7
|
-
import { useListeningQuery, Feedback } from 'sanity-plugin-utils';
|
|
8
|
-
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
|
|
9
|
-
import { usePaneRouter } from 'sanity/structure';
|
|
10
|
-
const ORDER_FIELD_NAME = "orderRank";
|
|
11
|
-
const API_VERSION = "2021-09-01";
|
|
12
|
-
function initialRank() {
|
|
13
|
-
let compareRankValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
14
|
-
let newItemPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "after";
|
|
15
|
-
const compareRank = compareRankValue ? LexoRank.parse(compareRankValue) : LexoRank.min();
|
|
16
|
-
const rank = newItemPosition === "before" ? compareRank.genPrev().genPrev() : compareRank.genNext().genNext();
|
|
17
|
-
return rank.toString();
|
|
18
|
-
}
|
|
19
|
-
const orderRankField = config => {
|
|
20
|
-
if (!(config == null ? void 0 : config.type)) {
|
|
21
|
-
throw new Error("\n type must be provided.\n Example: orderRankField({type: 'category'})\n ");
|
|
22
|
-
}
|
|
23
|
-
const {
|
|
24
|
-
type,
|
|
25
|
-
newItemPosition = "after"
|
|
26
|
-
} = config;
|
|
27
|
-
return defineField({
|
|
28
|
-
title: "Order Rank",
|
|
29
|
-
readOnly: true,
|
|
30
|
-
hidden: true,
|
|
31
|
-
...config,
|
|
32
|
-
name: ORDER_FIELD_NAME,
|
|
33
|
-
type: "string",
|
|
34
|
-
initialValue: async (p, _ref) => {
|
|
35
|
-
let {
|
|
36
|
-
getClient
|
|
37
|
-
} = _ref;
|
|
38
|
-
const direction = newItemPosition === "before" ? "asc" : "desc";
|
|
39
|
-
const lastDocOrderRank = await getClient({
|
|
40
|
-
apiVersion: API_VERSION
|
|
41
|
-
}).fetch("*[_type == $type]|order(@[$order] ".concat(direction, ")[0][$order]"), {
|
|
42
|
-
type,
|
|
43
|
-
order: ORDER_FIELD_NAME
|
|
44
|
-
});
|
|
45
|
-
return initialRank(lastDocOrderRank, newItemPosition);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
const orderRankOrdering = {
|
|
50
|
-
title: "Ordered",
|
|
51
|
-
name: "ordered",
|
|
52
|
-
by: [{
|
|
53
|
-
field: ORDER_FIELD_NAME,
|
|
54
|
-
direction: "asc"
|
|
55
|
-
}]
|
|
56
|
-
};
|
|
57
|
-
const OrderableContext = React.createContext({});
|
|
58
|
-
function Document(_ref2) {
|
|
59
|
-
let {
|
|
60
|
-
doc,
|
|
61
|
-
increment,
|
|
62
|
-
entities,
|
|
63
|
-
index,
|
|
64
|
-
isFirst,
|
|
65
|
-
isLast,
|
|
66
|
-
dragBadge
|
|
67
|
-
} = _ref2;
|
|
68
|
-
var _a, _b;
|
|
69
|
-
const {
|
|
70
|
-
showIncrements
|
|
71
|
-
} = useContext(OrderableContext);
|
|
72
|
-
const schema = useSchema();
|
|
73
|
-
const router = usePaneRouter();
|
|
74
|
-
const {
|
|
75
|
-
ChildLink,
|
|
76
|
-
groupIndex,
|
|
77
|
-
routerPanesState
|
|
78
|
-
} = router;
|
|
79
|
-
const currentDoc = ((_b = (_a = routerPanesState[groupIndex + 1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.id) || false;
|
|
80
|
-
const pressed = currentDoc === doc._id || currentDoc === doc._id.replace("drafts.", "");
|
|
81
|
-
const selected = pressed && routerPanesState.length === groupIndex + 2;
|
|
82
|
-
const Link = useMemo(() => function LinkComponent(linkProps) {
|
|
83
|
-
return /* @__PURE__ */jsx(ChildLink, {
|
|
84
|
-
...linkProps,
|
|
85
|
-
childId: doc._id
|
|
86
|
-
});
|
|
87
|
-
}, [ChildLink, doc._id]);
|
|
88
|
-
return /* @__PURE__ */jsx(PreviewCard, {
|
|
89
|
-
__unstable_focusRing: true,
|
|
90
|
-
as: Link,
|
|
91
|
-
"data-as": "a",
|
|
92
|
-
"data-ui": "PaneItem",
|
|
93
|
-
radius: 2,
|
|
94
|
-
pressed,
|
|
95
|
-
selected,
|
|
96
|
-
sizing: "border",
|
|
97
|
-
tabIndex: -1,
|
|
98
|
-
tone: "inherit",
|
|
99
|
-
width: "100%",
|
|
100
|
-
flex: 1,
|
|
101
|
-
children: /* @__PURE__ */jsxs(Flex, {
|
|
102
|
-
align: "center",
|
|
103
|
-
children: [/* @__PURE__ */jsx(Box, {
|
|
104
|
-
paddingX: 2,
|
|
105
|
-
style: {
|
|
106
|
-
flexShrink: 0
|
|
107
|
-
},
|
|
108
|
-
children: /* @__PURE__ */jsx(Text, {
|
|
109
|
-
size: 2,
|
|
110
|
-
children: /* @__PURE__ */jsx(DragHandleIcon, {
|
|
111
|
-
cursor: "grab"
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
}), showIncrements && /* @__PURE__ */jsxs(Flex, {
|
|
115
|
-
style: {
|
|
116
|
-
flexShrink: 0
|
|
117
|
-
},
|
|
118
|
-
align: "center",
|
|
119
|
-
gap: 1,
|
|
120
|
-
paddingRight: 1,
|
|
121
|
-
children: [/* @__PURE__ */jsx(Button, {
|
|
122
|
-
padding: 2,
|
|
123
|
-
mode: "ghost",
|
|
124
|
-
onClick: () => increment(index, index + -1, doc._id, entities),
|
|
125
|
-
disabled: isFirst,
|
|
126
|
-
icon: ChevronUpIcon
|
|
127
|
-
}), /* @__PURE__ */jsx(Button, {
|
|
128
|
-
padding: 2,
|
|
129
|
-
mode: "ghost",
|
|
130
|
-
disabled: isLast,
|
|
131
|
-
onClick: () => increment(index, index + 1, doc._id, entities),
|
|
132
|
-
icon: ChevronDownIcon
|
|
133
|
-
})]
|
|
134
|
-
}), /* @__PURE__ */jsx(Box, {
|
|
135
|
-
style: {
|
|
136
|
-
width: "100%"
|
|
137
|
-
},
|
|
138
|
-
children: /* @__PURE__ */jsx(Flex, {
|
|
139
|
-
flex: 1,
|
|
140
|
-
align: "center",
|
|
141
|
-
children: /* @__PURE__ */jsx(Preview, {
|
|
142
|
-
layout: "default",
|
|
143
|
-
value: doc,
|
|
144
|
-
schemaType: schema.get(doc._type)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
}), dragBadge && /* @__PURE__ */jsx(Card, {
|
|
148
|
-
tone: "default",
|
|
149
|
-
marginRight: 4,
|
|
150
|
-
radius: 5,
|
|
151
|
-
children: /* @__PURE__ */jsx(AvatarCounter, {
|
|
152
|
-
count: dragBadge
|
|
153
|
-
})
|
|
154
|
-
})]
|
|
155
|
-
})
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
function lexicographicalSort(a, b) {
|
|
159
|
-
if (!a[ORDER_FIELD_NAME] || !b[ORDER_FIELD_NAME]) {
|
|
160
|
-
return 0;
|
|
161
|
-
} else if (a[ORDER_FIELD_NAME] < b[ORDER_FIELD_NAME]) {
|
|
162
|
-
return -1;
|
|
163
|
-
} else if (a[ORDER_FIELD_NAME] > b[ORDER_FIELD_NAME]) {
|
|
164
|
-
return 1;
|
|
165
|
-
}
|
|
166
|
-
return 0;
|
|
167
|
-
}
|
|
168
|
-
const reorderDocuments = _ref3 => {
|
|
169
|
-
let {
|
|
170
|
-
entities,
|
|
171
|
-
selectedIds,
|
|
172
|
-
source,
|
|
173
|
-
destination
|
|
174
|
-
} = _ref3;
|
|
175
|
-
const startIndex = source.index;
|
|
176
|
-
const endIndex = destination.index;
|
|
177
|
-
const isMovingUp = startIndex > endIndex;
|
|
178
|
-
const selectedItems = entities.filter(item => selectedIds.includes(item._id));
|
|
179
|
-
const message = ["Moved", selectedItems.length === 1 ? "1 document" : "".concat(selectedItems.length, " documents"), isMovingUp ? "up" : "down", "from position", "".concat(startIndex + 1, " to ").concat(endIndex + 1)].join(" ");
|
|
180
|
-
const {
|
|
181
|
-
all,
|
|
182
|
-
selected
|
|
183
|
-
} = entities.reduce((acc, cur, curIndex) => {
|
|
184
|
-
var _a, _b, _c, _d;
|
|
185
|
-
if (selectedIds.includes(cur._id)) {
|
|
186
|
-
return {
|
|
187
|
-
all: acc.all,
|
|
188
|
-
selected: acc.selected
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
if (curIndex === endIndex) {
|
|
192
|
-
const prevIndex = curIndex - 1;
|
|
193
|
-
const prevRank = ((_a = entities[prevIndex]) == null ? void 0 : _a[ORDER_FIELD_NAME]) ? LexoRank.parse((_b = entities[prevIndex]) == null ? void 0 : _b[ORDER_FIELD_NAME]) : LexoRank.min();
|
|
194
|
-
const curRank = LexoRank.parse(entities[curIndex][ORDER_FIELD_NAME]);
|
|
195
|
-
const nextIndex = curIndex + 1;
|
|
196
|
-
const nextRank = ((_c = entities[nextIndex]) == null ? void 0 : _c[ORDER_FIELD_NAME]) ? LexoRank.parse((_d = entities[nextIndex]) == null ? void 0 : _d[ORDER_FIELD_NAME]) : LexoRank.max();
|
|
197
|
-
let betweenRank = isMovingUp ? prevRank.between(curRank) : curRank.between(nextRank);
|
|
198
|
-
for (let selectedIndex = 0; selectedIndex < selectedItems.length; selectedIndex += 1) {
|
|
199
|
-
selectedItems[selectedIndex][ORDER_FIELD_NAME] = betweenRank.toString();
|
|
200
|
-
betweenRank = isMovingUp ? betweenRank.between(curRank) : betweenRank.between(nextRank);
|
|
201
|
-
}
|
|
202
|
-
return {
|
|
203
|
-
// The `all` array gets sorted by order field later anyway
|
|
204
|
-
// so that this probably isn't necessary ¯\_(ツ)_/¯
|
|
205
|
-
all: isMovingUp ? [...acc.all, ...selectedItems, cur] : [...acc.all, cur, ...selectedItems],
|
|
206
|
-
selected: selectedItems
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
return {
|
|
210
|
-
all: [...acc.all, cur],
|
|
211
|
-
selected: acc.selected
|
|
212
|
-
};
|
|
213
|
-
}, {
|
|
214
|
-
all: [],
|
|
215
|
-
selected: []
|
|
216
|
-
});
|
|
217
|
-
const patches = selected.flatMap(doc => {
|
|
218
|
-
const docPatches = [[doc._id, {
|
|
219
|
-
set: {
|
|
220
|
-
[ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME]
|
|
221
|
-
}
|
|
222
|
-
}]];
|
|
223
|
-
if (doc._id.startsWith("drafts.") && doc.hasPublished) {
|
|
224
|
-
docPatches.push([doc._id.replace("drafts.", ""), {
|
|
225
|
-
set: {
|
|
226
|
-
[ORDER_FIELD_NAME]: doc[ORDER_FIELD_NAME]
|
|
227
|
-
}
|
|
228
|
-
}]);
|
|
229
|
-
}
|
|
230
|
-
return docPatches;
|
|
231
|
-
});
|
|
232
|
-
const allSorted = all.sort(lexicographicalSort);
|
|
233
|
-
return {
|
|
234
|
-
newOrder: allSorted,
|
|
235
|
-
patches,
|
|
236
|
-
message
|
|
237
|
-
};
|
|
238
|
-
};
|
|
239
|
-
function useSanityClient() {
|
|
240
|
-
return useClient({
|
|
241
|
-
apiVersion: API_VERSION
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
const getItemStyle = (draggableStyle, itemIsUpdating) => ({
|
|
245
|
-
userSelect: "none",
|
|
246
|
-
transition: "opacity 500ms ease-in-out",
|
|
247
|
-
opacity: itemIsUpdating ? 0.2 : 1,
|
|
248
|
-
pointerEvents: itemIsUpdating ? "none" : void 0,
|
|
249
|
-
...draggableStyle
|
|
250
|
-
});
|
|
251
|
-
const cardTone = settings => {
|
|
252
|
-
const {
|
|
253
|
-
isDuplicate,
|
|
254
|
-
isGhosting,
|
|
255
|
-
isDragging,
|
|
256
|
-
isSelected
|
|
257
|
-
} = settings;
|
|
258
|
-
if (isGhosting) return "transparent";
|
|
259
|
-
if (isDragging || isSelected) return "primary";
|
|
260
|
-
if (isDuplicate) return "caution";
|
|
261
|
-
return void 0;
|
|
262
|
-
};
|
|
263
|
-
function DraggableList(_ref4) {
|
|
264
|
-
let {
|
|
265
|
-
data,
|
|
266
|
-
listIsUpdating,
|
|
267
|
-
setListIsUpdating
|
|
268
|
-
} = _ref4;
|
|
269
|
-
var _a, _b;
|
|
270
|
-
const toast = useToast();
|
|
271
|
-
const router = usePaneRouter();
|
|
272
|
-
const {
|
|
273
|
-
groupIndex,
|
|
274
|
-
routerPanesState
|
|
275
|
-
} = router;
|
|
276
|
-
const currentDoc = ((_b = (_a = routerPanesState[groupIndex + 1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.id) || false;
|
|
277
|
-
const [orderedData, setOrderedData] = useState(data);
|
|
278
|
-
useEffect(() => {
|
|
279
|
-
if (!listIsUpdating) setOrderedData(data);
|
|
280
|
-
}, [data]);
|
|
281
|
-
const [draggingId, setDraggingId] = useState("");
|
|
282
|
-
const [selectedIds, setSelectedIds] = useState(currentDoc ? [currentDoc] : []);
|
|
283
|
-
const clearSelected = useCallback(() => setSelectedIds([]), [setSelectedIds]);
|
|
284
|
-
const handleSelect = useCallback((clickedId, index, nativeEvent) => {
|
|
285
|
-
const isSelected = selectedIds.includes(clickedId);
|
|
286
|
-
const selectMultiple = nativeEvent.shiftKey;
|
|
287
|
-
const isUsingWindows = navigator.appVersion.indexOf("Win") !== -1;
|
|
288
|
-
const selectAdditional = isUsingWindows ? nativeEvent.ctrlKey : nativeEvent.metaKey;
|
|
289
|
-
let updatedIds = [];
|
|
290
|
-
if (!selectMultiple && !selectAdditional) {
|
|
291
|
-
return setSelectedIds([clickedId]);
|
|
292
|
-
}
|
|
293
|
-
if (selectMultiple) {
|
|
294
|
-
nativeEvent.preventDefault();
|
|
295
|
-
}
|
|
296
|
-
if (selectMultiple && !isSelected) {
|
|
297
|
-
const lastSelectedId = selectedIds[selectedIds.length - 1];
|
|
298
|
-
const lastSelectedIndex = orderedData.findIndex(item => item._id === lastSelectedId);
|
|
299
|
-
const firstSelected = index < lastSelectedIndex ? index : lastSelectedIndex;
|
|
300
|
-
const lastSelected = index > lastSelectedIndex ? index : lastSelectedIndex;
|
|
301
|
-
const betweenIds = orderedData.filter((item, itemIndex) => itemIndex > firstSelected && itemIndex < lastSelected).map(item => item._id);
|
|
302
|
-
updatedIds = [...selectedIds, ...betweenIds, clickedId];
|
|
303
|
-
} else if (isSelected) {
|
|
304
|
-
updatedIds = selectedIds.filter(id => id !== clickedId);
|
|
305
|
-
} else {
|
|
306
|
-
updatedIds = [...selectedIds, clickedId];
|
|
307
|
-
}
|
|
308
|
-
return setSelectedIds(updatedIds);
|
|
309
|
-
}, [setSelectedIds, orderedData, selectedIds]);
|
|
310
|
-
const client = useSanityClient();
|
|
311
|
-
const transactPatches = useCallback(async (patches, message) => {
|
|
312
|
-
const transaction = client.transaction();
|
|
313
|
-
patches.forEach(_ref5 => {
|
|
314
|
-
let [docId, ops] = _ref5;
|
|
315
|
-
return transaction.patch(docId, ops);
|
|
316
|
-
});
|
|
317
|
-
await transaction.commit().then(updated => {
|
|
318
|
-
clearSelected();
|
|
319
|
-
setDraggingId("");
|
|
320
|
-
setListIsUpdating(false);
|
|
321
|
-
toast.push({
|
|
322
|
-
title: "".concat(updated.results.length === 1 ? "1 Document" : "".concat(updated.results.length, " Documents"), " Reordered"),
|
|
323
|
-
status: "success",
|
|
324
|
-
description: message
|
|
325
|
-
});
|
|
326
|
-
}).catch(() => {
|
|
327
|
-
setDraggingId("");
|
|
328
|
-
setListIsUpdating(false);
|
|
329
|
-
toast.push({
|
|
330
|
-
title: "Reordering failed",
|
|
331
|
-
status: "error"
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
}, [client, setDraggingId, clearSelected, setListIsUpdating, toast]);
|
|
335
|
-
const handleDragEnd = useCallback((result, entities) => {
|
|
336
|
-
setDraggingId("");
|
|
337
|
-
const {
|
|
338
|
-
source,
|
|
339
|
-
destination,
|
|
340
|
-
draggableId
|
|
341
|
-
} = result != null ? result : {};
|
|
342
|
-
if ((source == null ? void 0 : source.index) === (destination == null ? void 0 : destination.index)) return;
|
|
343
|
-
if (!(entities == null ? void 0 : entities.length) || !draggableId) return;
|
|
344
|
-
const effectedIds = (selectedIds == null ? void 0 : selectedIds.length) ? selectedIds : [draggableId];
|
|
345
|
-
if (!(effectedIds == null ? void 0 : effectedIds.length)) return;
|
|
346
|
-
setListIsUpdating(true);
|
|
347
|
-
setSelectedIds(effectedIds);
|
|
348
|
-
const {
|
|
349
|
-
newOrder,
|
|
350
|
-
patches,
|
|
351
|
-
message
|
|
352
|
-
} = reorderDocuments({
|
|
353
|
-
entities,
|
|
354
|
-
selectedIds: effectedIds,
|
|
355
|
-
source,
|
|
356
|
-
destination
|
|
357
|
-
});
|
|
358
|
-
if (newOrder == null ? void 0 : newOrder.length) {
|
|
359
|
-
setOrderedData(newOrder);
|
|
360
|
-
}
|
|
361
|
-
if (patches == null ? void 0 : patches.length) {
|
|
362
|
-
transactPatches(patches, message);
|
|
363
|
-
}
|
|
364
|
-
}, [selectedIds, setDraggingId, setSelectedIds, transactPatches, setListIsUpdating]);
|
|
365
|
-
const handleDragStart = useCallback(start => {
|
|
366
|
-
const id = start.draggableId;
|
|
367
|
-
const selected = selectedIds.includes(id);
|
|
368
|
-
if (!selected) clearSelected();
|
|
369
|
-
setDraggingId(id);
|
|
370
|
-
}, [selectedIds, clearSelected, setDraggingId]);
|
|
371
|
-
const incrementIndex = useCallback((shiftFrom, shiftTo, id, entities) => {
|
|
372
|
-
const result = {
|
|
373
|
-
draggableId: id,
|
|
374
|
-
source: {
|
|
375
|
-
index: shiftFrom
|
|
376
|
-
},
|
|
377
|
-
destination: {
|
|
378
|
-
index: shiftTo
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
return handleDragEnd(result, entities);
|
|
382
|
-
}, [handleDragEnd]);
|
|
383
|
-
const onWindowKeyDown = useCallback(event => {
|
|
384
|
-
if (event.key === "Escape") {
|
|
385
|
-
clearSelected();
|
|
386
|
-
}
|
|
387
|
-
}, [clearSelected]);
|
|
388
|
-
useEffect(() => {
|
|
389
|
-
window.addEventListener("keydown", onWindowKeyDown);
|
|
390
|
-
return () => {
|
|
391
|
-
window.removeEventListener("keydown", onWindowKeyDown);
|
|
392
|
-
};
|
|
393
|
-
}, [onWindowKeyDown]);
|
|
394
|
-
const duplicateOrders = useMemo(() => {
|
|
395
|
-
if (!orderedData.length) return [];
|
|
396
|
-
const orderField = orderedData.map(item => item[ORDER_FIELD_NAME]);
|
|
397
|
-
return orderField.filter((item, index) => orderField.indexOf(item) !== index);
|
|
398
|
-
}, [orderedData]);
|
|
399
|
-
const onDragEnd = useCallback(result => handleDragEnd(result, orderedData), [orderedData, handleDragEnd]);
|
|
400
|
-
return /* @__PURE__ */jsx(DragDropContext, {
|
|
401
|
-
onDragStart: handleDragStart,
|
|
402
|
-
onDragEnd,
|
|
403
|
-
children: /* @__PURE__ */jsx(Droppable, {
|
|
404
|
-
droppableId: "documentSortZone",
|
|
405
|
-
children: provided => /* @__PURE__ */jsxs("div", {
|
|
406
|
-
...provided.droppableProps,
|
|
407
|
-
ref: provided.innerRef,
|
|
408
|
-
children: [orderedData.map((item, index) => /* @__PURE__ */jsx(Draggable, {
|
|
409
|
-
draggableId: item._id,
|
|
410
|
-
index,
|
|
411
|
-
children: (innerProvided, innerSnapshot) => {
|
|
412
|
-
const isSelected = selectedIds.includes(item._id);
|
|
413
|
-
const isDragging = innerSnapshot.isDragging;
|
|
414
|
-
const isGhosting = Boolean(!isDragging && draggingId && isSelected);
|
|
415
|
-
const isUpdating = listIsUpdating && isSelected;
|
|
416
|
-
const isDisabled = Boolean(!item[ORDER_FIELD_NAME]);
|
|
417
|
-
const isDuplicate = duplicateOrders.includes(item[ORDER_FIELD_NAME]);
|
|
418
|
-
const tone = cardTone({
|
|
419
|
-
isDuplicate,
|
|
420
|
-
isGhosting,
|
|
421
|
-
isDragging,
|
|
422
|
-
isSelected
|
|
423
|
-
});
|
|
424
|
-
const selectedCount = selectedIds.length;
|
|
425
|
-
const dragBadge = isDragging && selectedCount > 1 ? selectedCount : false;
|
|
426
|
-
return /* @__PURE__ */jsx("div", {
|
|
427
|
-
ref: innerProvided.innerRef,
|
|
428
|
-
...innerProvided.draggableProps,
|
|
429
|
-
...innerProvided.dragHandleProps,
|
|
430
|
-
style: isDisabled ? {
|
|
431
|
-
opacity: 0.2,
|
|
432
|
-
pointerEvents: "none"
|
|
433
|
-
} : getItemStyle(innerProvided.draggableProps.style, isUpdating),
|
|
434
|
-
children: /* @__PURE__ */jsx(Box, {
|
|
435
|
-
paddingBottom: 1,
|
|
436
|
-
children: /* @__PURE__ */jsx(Card, {
|
|
437
|
-
tone,
|
|
438
|
-
shadow: isDragging ? 2 : void 0,
|
|
439
|
-
radius: 2,
|
|
440
|
-
onClick: e => handleSelect(item._id, index, e.nativeEvent),
|
|
441
|
-
children: /* @__PURE__ */jsx(Document, {
|
|
442
|
-
doc: item,
|
|
443
|
-
entities: orderedData,
|
|
444
|
-
increment: incrementIndex,
|
|
445
|
-
index,
|
|
446
|
-
isFirst: index === 0,
|
|
447
|
-
isLast: index === orderedData.length - 1,
|
|
448
|
-
dragBadge
|
|
449
|
-
})
|
|
450
|
-
})
|
|
451
|
-
})
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
}, "".concat(item._id, "-").concat(item[ORDER_FIELD_NAME]))), provided.placeholder]
|
|
455
|
-
})
|
|
456
|
-
})
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
const DEFAULT_PARAMS = {};
|
|
460
|
-
function DocumentListQuery(_ref6) {
|
|
461
|
-
let {
|
|
462
|
-
type,
|
|
463
|
-
filter,
|
|
464
|
-
params = DEFAULT_PARAMS
|
|
465
|
-
} = _ref6;
|
|
466
|
-
const [listIsUpdating, setListIsUpdating] = useState(false);
|
|
467
|
-
const [data, setData] = useState([]);
|
|
468
|
-
const query = "*[_type == $type ".concat(filter ? "&& ".concat(filter) : "", "]|order(@[$order] asc){\n _id, _type, ").concat(ORDER_FIELD_NAME, "\n }");
|
|
469
|
-
const queryParams = {
|
|
470
|
-
...params,
|
|
471
|
-
type,
|
|
472
|
-
order: ORDER_FIELD_NAME
|
|
473
|
-
};
|
|
474
|
-
const {
|
|
475
|
-
data: queryData,
|
|
476
|
-
loading,
|
|
477
|
-
error
|
|
478
|
-
} = useListeningQuery(query, {
|
|
479
|
-
params: queryParams,
|
|
480
|
-
initialValue: []
|
|
481
|
-
});
|
|
482
|
-
useEffect(() => {
|
|
483
|
-
if (queryData) {
|
|
484
|
-
const filteredDocuments = queryData.reduce((acc, cur) => {
|
|
485
|
-
if (!cur._id.startsWith("drafts.")) {
|
|
486
|
-
const alsoHasDraft = queryData.some(doc => doc._id === "drafts.".concat(cur._id));
|
|
487
|
-
return alsoHasDraft ? acc : [...acc, cur];
|
|
488
|
-
}
|
|
489
|
-
cur.hasPublished = queryData.some(doc => doc._id === cur._id.replace("drafts.", ""));
|
|
490
|
-
return [...acc, cur];
|
|
491
|
-
}, []);
|
|
492
|
-
setData(filteredDocuments);
|
|
493
|
-
} else {
|
|
494
|
-
setData([]);
|
|
495
|
-
}
|
|
496
|
-
}, [queryData]);
|
|
497
|
-
const unorderedDataCount = useMemo(() => (data == null ? void 0 : data.length) ? data.filter(doc => !doc[ORDER_FIELD_NAME]).length : 0, [data]);
|
|
498
|
-
if (loading) {
|
|
499
|
-
return /* @__PURE__ */jsx(Flex, {
|
|
500
|
-
style: {
|
|
501
|
-
width: "100%",
|
|
502
|
-
height: "100%"
|
|
503
|
-
},
|
|
504
|
-
align: "center",
|
|
505
|
-
justify: "center",
|
|
506
|
-
children: /* @__PURE__ */jsx(Spinner, {})
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
if (error) {
|
|
510
|
-
return /* @__PURE__ */jsx(Box, {
|
|
511
|
-
padding: 2,
|
|
512
|
-
children: /* @__PURE__ */jsx(Feedback, {
|
|
513
|
-
tone: "critical",
|
|
514
|
-
title: "There was an error",
|
|
515
|
-
description: "Please try again later"
|
|
516
|
-
})
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
if (!data || (data == null ? void 0 : data.length) == 0) return /* @__PURE__ */jsx(Flex, {
|
|
520
|
-
align: "center",
|
|
521
|
-
direction: "column",
|
|
522
|
-
height: "fill",
|
|
523
|
-
justify: "center",
|
|
524
|
-
children: /* @__PURE__ */jsx(Container, {
|
|
525
|
-
width: 1,
|
|
526
|
-
children: /* @__PURE__ */jsx(Box, {
|
|
527
|
-
paddingX: 4,
|
|
528
|
-
paddingY: 5,
|
|
529
|
-
children: /* @__PURE__ */jsx(Text, {
|
|
530
|
-
align: "center",
|
|
531
|
-
muted: true,
|
|
532
|
-
children: "No documents of this type"
|
|
533
|
-
})
|
|
534
|
-
})
|
|
535
|
-
})
|
|
536
|
-
});
|
|
537
|
-
return /* @__PURE__ */jsx(Stack, {
|
|
538
|
-
space: 1,
|
|
539
|
-
style: {
|
|
540
|
-
overflow: "auto",
|
|
541
|
-
height: "100%"
|
|
542
|
-
},
|
|
543
|
-
children: /* @__PURE__ */jsxs(Box, {
|
|
544
|
-
padding: 2,
|
|
545
|
-
children: [unorderedDataCount > 0 && /* @__PURE__ */jsx(Box, {
|
|
546
|
-
marginBottom: 2,
|
|
547
|
-
children: /* @__PURE__ */jsx(Feedback, {
|
|
548
|
-
tone: "caution",
|
|
549
|
-
description: /* @__PURE__ */jsxs(Fragment, {
|
|
550
|
-
children: [unorderedDataCount, "/", data == null ? void 0 : data.length, " documents have no order. Select", " ", /* @__PURE__ */jsx("strong", {
|
|
551
|
-
children: "Reset Order"
|
|
552
|
-
}), " from the menu above to fix."]
|
|
553
|
-
})
|
|
554
|
-
})
|
|
555
|
-
}), /* @__PURE__ */jsx(DraggableList, {
|
|
556
|
-
data,
|
|
557
|
-
listIsUpdating,
|
|
558
|
-
setListIsUpdating
|
|
559
|
-
})]
|
|
560
|
-
})
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
function DocumentListWrapper(_ref7) {
|
|
564
|
-
let {
|
|
565
|
-
type,
|
|
566
|
-
showIncrements,
|
|
567
|
-
resetOrderTransaction,
|
|
568
|
-
filter,
|
|
569
|
-
params
|
|
570
|
-
} = _ref7;
|
|
571
|
-
const toast = useToast();
|
|
572
|
-
const schema = useSchema();
|
|
573
|
-
useEffect(() => {
|
|
574
|
-
if ((resetOrderTransaction == null ? void 0 : resetOrderTransaction.title) && (resetOrderTransaction == null ? void 0 : resetOrderTransaction.status)) {
|
|
575
|
-
toast.push(resetOrderTransaction);
|
|
576
|
-
}
|
|
577
|
-
}, [resetOrderTransaction, toast]);
|
|
578
|
-
const schemaIsInvalid = useMemo(() => {
|
|
579
|
-
if (!type) {
|
|
580
|
-
return /* @__PURE__ */jsxs(Fragment, {
|
|
581
|
-
children: ["No ", /* @__PURE__ */jsx("code", {
|
|
582
|
-
children: "type"
|
|
583
|
-
}), " was configured"]
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
const typeSchema = schema.get(type);
|
|
587
|
-
if (!typeSchema) {
|
|
588
|
-
return /* @__PURE__ */jsxs(Fragment, {
|
|
589
|
-
children: ["Schema ", /* @__PURE__ */jsx("code", {
|
|
590
|
-
children: type
|
|
591
|
-
}), " not found"]
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
if (!("fields" in typeSchema) || !typeSchema.fields.some(field => (field == null ? void 0 : field.name) === ORDER_FIELD_NAME)) {
|
|
595
|
-
return /* @__PURE__ */jsxs(Fragment, {
|
|
596
|
-
children: ["Schema ", /* @__PURE__ */jsx("code", {
|
|
597
|
-
children: type
|
|
598
|
-
}), " must have an ", /* @__PURE__ */jsx("code", {
|
|
599
|
-
children: ORDER_FIELD_NAME
|
|
600
|
-
}), " field of type", " ", /* @__PURE__ */jsx("code", {
|
|
601
|
-
children: "string"
|
|
602
|
-
})]
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
if ("fields" in typeSchema && typeSchema.fields.some(field => {
|
|
606
|
-
var _a;
|
|
607
|
-
return (field == null ? void 0 : field.name) === ORDER_FIELD_NAME && ((_a = field == null ? void 0 : field.type) == null ? void 0 : _a.name) !== "string";
|
|
608
|
-
})) {
|
|
609
|
-
return /* @__PURE__ */jsxs(Fragment, {
|
|
610
|
-
children: [/* @__PURE__ */jsx("code", {
|
|
611
|
-
children: ORDER_FIELD_NAME
|
|
612
|
-
}), " field on Schema ", /* @__PURE__ */jsx("code", {
|
|
613
|
-
children: type
|
|
614
|
-
}), " must be", " ", /* @__PURE__ */jsx("code", {
|
|
615
|
-
children: "string"
|
|
616
|
-
}), " type"]
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
return "";
|
|
620
|
-
}, [type, schema]);
|
|
621
|
-
if (schemaIsInvalid) {
|
|
622
|
-
return /* @__PURE__ */jsx(Box, {
|
|
623
|
-
padding: 2,
|
|
624
|
-
children: /* @__PURE__ */jsx(Feedback, {
|
|
625
|
-
description: schemaIsInvalid,
|
|
626
|
-
tone: "caution"
|
|
627
|
-
})
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
return /* @__PURE__ */jsx(OrderableContext.Provider, {
|
|
631
|
-
value: {
|
|
632
|
-
showIncrements
|
|
633
|
-
},
|
|
634
|
-
children: /* @__PURE__ */jsx(DocumentListQuery, {
|
|
635
|
-
type,
|
|
636
|
-
filter,
|
|
637
|
-
params
|
|
638
|
-
})
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
async function resetOrder() {
|
|
642
|
-
let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
643
|
-
let client = arguments.length > 1 ? arguments[1] : undefined;
|
|
644
|
-
const query = "*[_type == $type]|order(@[$order] asc)._id";
|
|
645
|
-
const queryParams = {
|
|
646
|
-
type,
|
|
647
|
-
order: ORDER_FIELD_NAME
|
|
648
|
-
};
|
|
649
|
-
const documents = await client.fetch(query, queryParams);
|
|
650
|
-
if (!documents.length) {
|
|
651
|
-
return null;
|
|
652
|
-
}
|
|
653
|
-
const transaction = client.transaction();
|
|
654
|
-
let aLexoRank = LexoRank.min();
|
|
655
|
-
for (let index = 0; index < documents.length; index += 1) {
|
|
656
|
-
aLexoRank = aLexoRank.genNext().genNext();
|
|
657
|
-
transaction.patch(documents[index], {
|
|
658
|
-
set: {
|
|
659
|
-
[ORDER_FIELD_NAME]: aLexoRank.toString()
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
return transaction.commit().then(update => update).catch(err => err);
|
|
664
|
-
}
|
|
665
|
-
var __defProp = Object.defineProperty;
|
|
666
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
667
|
-
enumerable: true,
|
|
668
|
-
configurable: true,
|
|
669
|
-
writable: true,
|
|
670
|
-
value
|
|
671
|
-
}) : obj[key] = value;
|
|
672
|
-
var __publicField = (obj, key, value) => {
|
|
673
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
674
|
-
return value;
|
|
675
|
-
};
|
|
676
|
-
class OrderableDocumentList extends Component {
|
|
677
|
-
constructor(props) {
|
|
678
|
-
super(props);
|
|
679
|
-
__publicField(this, "actionHandlers", {
|
|
680
|
-
showIncrements: () => {
|
|
681
|
-
this.setState(state => ({
|
|
682
|
-
showIncrements: !state.showIncrements
|
|
683
|
-
}));
|
|
684
|
-
},
|
|
685
|
-
resetOrder: async () => {
|
|
686
|
-
var _a;
|
|
687
|
-
this.setState(() => ({
|
|
688
|
-
resetOrderTransaction: {
|
|
689
|
-
status: "info",
|
|
690
|
-
title: "Reordering started...",
|
|
691
|
-
closable: true
|
|
692
|
-
}
|
|
693
|
-
}));
|
|
694
|
-
const update = await resetOrder(this.props.options.type, this.props.options.client);
|
|
695
|
-
const reorderWasSuccessful = (_a = update == null ? void 0 : update.results) == null ? void 0 : _a.length;
|
|
696
|
-
this.setState(() => ({
|
|
697
|
-
resetOrderTransaction: {
|
|
698
|
-
status: reorderWasSuccessful ? "success" : "info",
|
|
699
|
-
title: reorderWasSuccessful ? "Reordered ".concat(update.results.length === 1 ? "Document" : "Documents") : "Reordering failed",
|
|
700
|
-
closable: true
|
|
701
|
-
}
|
|
702
|
-
}));
|
|
703
|
-
}
|
|
704
|
-
});
|
|
705
|
-
this.state = {
|
|
706
|
-
showIncrements: false,
|
|
707
|
-
resetOrderTransaction: {}
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
render() {
|
|
711
|
-
var _a, _b, _c, _d, _e, _f;
|
|
712
|
-
const type = (_b = (_a = this == null ? void 0 : this.props) == null ? void 0 : _a.options) == null ? void 0 : _b.type;
|
|
713
|
-
if (!type) {
|
|
714
|
-
return null;
|
|
715
|
-
}
|
|
716
|
-
return /* @__PURE__ */jsx(DocumentListWrapper, {
|
|
717
|
-
filter: (_d = (_c = this == null ? void 0 : this.props) == null ? void 0 : _c.options) == null ? void 0 : _d.filter,
|
|
718
|
-
params: (_f = (_e = this == null ? void 0 : this.props) == null ? void 0 : _e.options) == null ? void 0 : _f.params,
|
|
719
|
-
type,
|
|
720
|
-
showIncrements: this.state.showIncrements,
|
|
721
|
-
resetOrderTransaction: this.state.resetOrderTransaction
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
function orderableDocumentListDeskItem(config) {
|
|
726
|
-
var _a, _b;
|
|
727
|
-
if (!(config == null ? void 0 : config.type) || !config.context || !config.S) {
|
|
728
|
-
throw new Error("\n type, context and S (StructureBuilder) must be provided.\n context and S are available when configuring structure.\n Example: orderableDocumentListDeskItem({type: 'category'})\n ");
|
|
729
|
-
}
|
|
730
|
-
const {
|
|
731
|
-
type,
|
|
732
|
-
filter,
|
|
733
|
-
menuItems = [],
|
|
734
|
-
createIntent,
|
|
735
|
-
params,
|
|
736
|
-
title,
|
|
737
|
-
icon,
|
|
738
|
-
id,
|
|
739
|
-
context,
|
|
740
|
-
S
|
|
741
|
-
} = config;
|
|
742
|
-
const {
|
|
743
|
-
schema,
|
|
744
|
-
getClient
|
|
745
|
-
} = context;
|
|
746
|
-
const client = getClient({
|
|
747
|
-
apiVersion: API_VERSION
|
|
748
|
-
});
|
|
749
|
-
const listTitle = title != null ? title : "Orderable ".concat(type);
|
|
750
|
-
const listId = id != null ? id : "orderable-".concat(type);
|
|
751
|
-
const listIcon = icon != null ? icon : SortIcon;
|
|
752
|
-
const typeTitle = (_b = (_a = schema.get(type)) == null ? void 0 : _a.title) != null ? _b : type;
|
|
753
|
-
if (createIntent !== false) {
|
|
754
|
-
menuItems.push(S.menuItem().title("Create new ".concat(typeTitle)).intent({
|
|
755
|
-
type: "create",
|
|
756
|
-
params: {
|
|
757
|
-
type
|
|
758
|
-
}
|
|
759
|
-
}).serialize());
|
|
760
|
-
}
|
|
761
|
-
return S.listItem().title(listTitle).id(listId).icon(listIcon).schemaType(type).child(Object.assign(S.documentTypeList(type).canHandleIntent(() => !!createIntent).serialize(), {
|
|
762
|
-
// Prevents the component from re-rendering when switching documents
|
|
763
|
-
__preserveInstance: true,
|
|
764
|
-
// Prevents the component from NOT re-rendering when switching listItems
|
|
765
|
-
key: listId,
|
|
766
|
-
type: "component",
|
|
767
|
-
component: OrderableDocumentList,
|
|
768
|
-
options: {
|
|
769
|
-
type,
|
|
770
|
-
filter,
|
|
771
|
-
params,
|
|
772
|
-
client
|
|
773
|
-
},
|
|
774
|
-
menuItems: [...menuItems, S.menuItem().title("Reset Order").icon(GenerateIcon).action("resetOrder").serialize(), S.menuItem().title("Toggle Increments").icon(SortIcon).action("showIncrements").serialize()]
|
|
775
|
-
})).serialize();
|
|
776
|
-
}
|
|
777
|
-
export { orderRankField, orderRankOrdering, orderableDocumentListDeskItem };
|
|
778
|
-
//# sourceMappingURL=index.esm.js.map
|